Android Camera Application does not display image correctly - java

I want to make an app that takes a picture with the device's camera, saves the image in the internal memory, and then displays that image in the next Activity. The preview works perfectly, but when I hit the Capture button the app goes to the next activity and only shows a blank white screen. Maybe I'm not writing or reading the file correctly?
Here is the Main Activity:
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "File_name";
private Camera mCamera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
CameraPreview mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
//////////////////////
public void sendInfo(String pathway) {
Intent intent = new Intent(this, show_image.class);
intent.putExtra(EXTRA_MESSAGE,pathway);
startActivity(intent);
}
/////////////////
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data , Camera camera) {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,"pic.jpg");
FileOutputStream fos = null;
if (directory == null){
Log.d("Logtag", "Error creating media file, check storage permissions: ");
return;
}
try {
fos = new FileOutputStream(mypath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
String path = directory.getAbsolutePath();
sendInfo(path);
} catch (FileNotFoundException e) {
Log.d("Logtag", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Logtag", "Error accessing file: " + e.getMessage());
}
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A safe way to get an instance of the Camera object.
*/
public Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) {
// Camera is not available (in use or does not exist)
Toast.makeText(getApplicationContext(), "Camera is not available (in use or does not exist)",
Toast.LENGTH_LONG).show();
}
return c; // returns null if camera is unavailable
}
}
Here is the Second activity that is supposed to display the image that was just taken:
public class show_image extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String path = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
try {
File f = new File(path, "pic.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
ImageView img= new ImageView(this);
img.setImageBitmap(b);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
public static Bitmap decodeFile(File f, final int maxSize) {
Bitmap b = null;
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > maxSize || o.outWidth > maxSize) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(maxSize / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
} catch (Exception e) {
Log.e("Logtag", "Error processing bitmap", e);
} finally {
//FileUtil.closeQuietly(fis);
}
return b;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The LogCat from Android Studio:
02-25 12:32:49.389 17041-17041/edu.ramapo.camer I/System.out﹕ debugger has settled (1496)
02-25 12:32:49.620 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.view.ViewGroup.onNestedScrollAccepted, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onNestedScrollAccepted
02-25 12:32:49.620 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 11360: Landroid/view/ViewGroup;.onNestedScrollAccepted (Landroid/view/View;Landroid/view/View;I)V
02-25 12:32:49.620 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0000
02-25 12:32:49.620 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.view.ViewGroup.onStopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onStopNestedScroll
02-25 12:32:49.620 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 11366: Landroid/view/ViewGroup;.onStopNestedScroll (Landroid/view/View;)V
02-25 12:32:49.620 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0000
02-25 12:32:49.630 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.support.v7.internal.widget.ActionBarOverlayLayout.stopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.setHideOnContentScrollEnabled
02-25 12:32:49.630 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 9050: Landroid/support/v7/internal/widget/ActionBarOverlayLayout;.stopNestedScroll ()V
02-25 12:32:49.630 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x000e
02-25 12:32:49.660 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method
android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations
02-25 12:32:49.660 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 367: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
02-25 12:32:49.660 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
02-25 12:32:49.670 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType
02-25 12:32:49.670 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 389: Landroid/content/res/TypedArray;.getType (I)I
02-25 12:32:49.670 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
02-25 12:32:50.611 17041-17041/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libEGL_adreno200.so
02-25 12:32:50.621 17041-17041/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_adreno200.so
02-25 12:32:50.621 17041-17041/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libGLESv2_adreno200.so
02-25 12:32:50.631 17041-17041/edu.ramapo.camer I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:265>: EGL 1.4 QUALCOMM build: HAREESHG_Nondeterministic_AU+PATCH[ES]_msm8960_JB_1.9.6_MR2_CL3219408_release_ENGG (CL3219408)
Build Date: 09/28/13 Sat
Local Branch: hhh
Remote Branch: quic/jb_1.9.6_1
Local Patches: 8d50ec23e42ef52b570aa6ff1650afac0b503d78 CL3219408: Fix in the Glreadpixels for negative offsets and larger dimensions.
801859126f6ca69482b39a34ca61447e3f7cded8 rb: fix panel settings to clear undrawn/undefined buffers
Reconstruct Branch: LOCAL_PATCH[ES]
02-25 12:32:50.991 17041-17041/edu.ramapo.camer D/OpenGLRenderer﹕ Enabling debug mode 0
02-25 12:32:51.552 17041-17041/edu.ramapo.camer I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread.
02-25 12:32:56.037 17041-17047/edu.ramapo.camer D/dalvikvm﹕ Debugger has detached; object registry had 4113 entries
02-25 12:33:18.651 17041-17041/edu.ramapo.camer D/dalvikvm﹕ GC_FOR_ALLOC freed 694K, 38% free 12155K/19420K, paused 29ms, total 32ms
02-25 12:33:18.771 17041-17041/edu.ramapo.camer I/dalvikvm-heap﹕ Grow heap (frag case) to 45.705MB for 31961104-byte allocation
02-25 12:33:24.507 17041-17041/edu.ramapo.camer D/dalvikvm﹕ GC_FOR_ALLOC freed 31627K, 40% free 11825K/19424K, paused 30ms, total 30ms
02-25 12:33:24.587 17041-17041/edu.ramapo.camer I/dalvikvm-heap﹕ Grow heap (frag case) to 45.382MB for 31961104-byte allocation

Well right now I made a copy of the app I sent you the link already here is the code:
public class GlassARTest extends FragmentActivity {
private static final String TAG = "CameraActivity";
public static final int MEDIA_TYPE_IMAGE = 1;
private Camera mCamera;
private CameraPreview mPreview;
private Context mContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
mContext = this;
if(checkCameraHardware(mContext)){
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
}
private PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return null;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
return pictureFile.getPath();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null){
Intent intent = new Intent(mContext, ImageDisplayActivity.class);
intent.putExtra(ImageDisplayActivity.KEY_PATH, result);
startActivity(intent);
}
}
}.execute();
}
};
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
} private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
}
and the other Activity:
public class ImageDisplayActivity extends FragmentActivity{
public static final String KEY_PATH = "path";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_display);
final ImageView imageDisplay = (ImageView)findViewById(R.id.image_displayer);
final Bundle extras = getIntent().getExtras();
if(extras != null){
final String path = extras.getString(KEY_PATH);
File imgFile = new File(path);
Bitmap bitmap = decodeFile(imgFile);
imageDisplay.setImageBitmap(bitmap);
}
}
private Bitmap decodeFile(File f){
Bitmap b = null;
try {
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > 50 || o.outWidth > 50) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(50 / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
}
return b;
}
}
this code worked showing a pixelated image of what I took picture of (as I'm just decoding it in low quality for testing purposes).
I hope this help you.

Related

How can I save only the last taken image to directory?

Here I have created an app to take images and save them to external storage of the phone. (Also there is a problem with below code that images are not saved to the given location.) I want only the last taken image to be saved in external memory of the phone.Everytime I take a new picture, I need to delete the previously taken image and save only the last taken image. How can I do it? Also is it possible to take images continously at regular intervals? I searched and I found that I can do it with a Timer(). Is it possible? Thank You.
Edit- Actually what I want is to comapare two images. One is taken at the moment and other is taken immediately before it. (I take images at regular time intervals and I compare new one with the previous one.) Only after comparison, I delete previous one.
public class MyCamera extends Activity {
private Camera mCamera;
private CameraPreview mCameraPreview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
}
/**
* Helper method to access the camera returns null if it cannot get the
* camera or does not exist
*
* #return
*/
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
PictureCallback mPicture = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, e.getMessage());
} catch (IOException e) {
Log.d(TAG, e.getMessage());
}
}
};
private static File getOutputMediaFile() {
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"MyCameraApp");
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
String fname = "IMG_" + timeStamp + ".jpg";
System.out.println(fname);
File mediaFile;
mediaFile = new File(mediaStorageDir, fname);
return mediaFile;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_camera, menu);
return true;
}
}
You can keep a constant name for your photo file.
String fname = "MyImage.jpg";
You can give some constant name. And about taking image at regular interval, you can use handler.
You can read more about it here.
And make sure your remove your handler when your camera is closed.
EDITED
You can list the files of your directory,mediaStorageDir in your case.
List all the files of the directory, and delete the file which is older by comparing the last modified.

Select random image to send to server

I am new to Android development. I created my first app which is a camera with the ability to capture an image, query the user for a Car ID related to the image, preview the captured image, and upload that image to the server.
I am interested in randomly sending out one image from possibly multiple such as from the image directory to the server. I do NOT want to send multiple images to the server--just one random image.
Upon much research on this website as well as on numerous others, I determined the following: I must obtain the image directory to where the captured images are uploaded to, I must randomly select an image from said directory using the random capability in Android, I must set up the image bitmap based on the file uri of the image, and I must convert the bitmap to a blob data type by base64 encoding.
I did the above, but my bitmap returned as null since I receive the message, "Please select image", which was the toast message for that instance.
Here is my code:
public class MainActivity extends Activity {
// Activity request codes.
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
Bitmap bitmap;
ProgressDialog pd;
InputStream is;
//Directory name to store captured images.
private static final String IMAGE_DIRECTORY_NAME = "Hello Camera";
private Uri fileUri; //File url to store captured images.
private ImageView imgPreview;
private Button btnCapturePicture;
private Button upload;
Button mButton;
EditText mEdit;
/* Initializes activity, defines UI layout, and retrieves widgets
* to interact with.
* #param savedInstanceState - data is caught here and saved for
* future app use.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.button);
mEdit = (EditText)findViewById(R.id.edittext);
mButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Log.v("EditText", mEdit.getText().toString());
}
});
imgPreview = (ImageView) findViewById(R.id.imgPreview);
btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
upload = (Button) findViewById(R.id.upload);
upload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (bitmap == null) {
Toast.makeText(getApplicationContext(), "Please Select Image", Toast.LENGTH_LONG).show();
} else {
new ImageUpload().execute();
}
}
});
/**
* Captures image button click event in order to capture a photo.
* #param new View.OnClickListener- call to constructor
*/
btnCapturePicture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Captures an image.
captureImage();
}
});
//Checks for camera availability.
if (!isDeviceSupportCamera()) {
Toast.makeText(getApplicationContext(),
"Sorry! Your device doesn't support camera", Toast.LENGTH_LONG).show();
//Closes if a camera is not available on the device.
finish();
}
}
/**
* Checks if device has camera hardware.
*
* #return - true or false.
*/
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
//Device has a camera.
return true;
} else {
// Device does not have a camera.
return false;
}
}
/*
* Launches camera app request image capture.
*/
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
//Starts the image capture Intent.
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
/**
* Gets and stores the file url. Will be null after returning from camera
* app.
*
* #param outState - Holds per-instance state from activity.
*/
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Saves the file url in bundle. It will be null on screen orientation changes.
outState.putParcelable("file_uri", fileUri);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//Gets the file url.
fileUri = savedInstanceState.getParcelable("file_uri");
}
/**
* Receives activity result method. Will be called after closing the camera.
*
* #param requestCode - Requests to capture an image.
* #param resultCode - Based on success or failure of image capturing, shows
* an image preview or one of two error messages.
* #param data - Carries the result data(successfully captured image).
* #return - An image preview, or one of two error messages.
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//If the result is the image capturing event,
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
//the image was successfully captured
// and will be displayed in the preview.
previewCapturedImage();
} else if (resultCode == RESULT_CANCELED) {
//The user cancelled the image capturing.
Toast.makeText(getApplicationContext(),
"User cancelled image capture", Toast.LENGTH_SHORT).show();
} else {
//Image capturing failed, but the user did not actually cancel it.
Toast.makeText(getApplicationContext(),
"Sorry! Failed to capture image", Toast.LENGTH_SHORT).show();
}
}
}
/**
* Displays the image from a path to ImageView.
* Downsizes an image if necessary and throws exception
* if the image is too large.
*/
private void previewCapturedImage() {
try {
imgPreview.setVisibility(View.VISIBLE);
upload.setVisibility(View.VISIBLE);
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
Log.v("Directory", mediaStorageDir.toString());
mediaStorageDir.listFiles(new FileFilter() {
public boolean accept(File file) {
return !file.isDirectory();
}
});
File[] listFiles = mediaStorageDir.listFiles();
Log.v("File listFiles", listFiles.toString());
Random r = new Random ();
Log.v("Random r", r.toString());
File randomPicture = listFiles[r.nextInt(listFiles.length)];
Log.v("Random Picture File", randomPicture.toString());
Uri pictureUri = Uri.fromFile(randomPicture);
Log.v("PictureUri", pictureUri.toString());
BitmapFactory.Options options = new BitmapFactory.Options();
// Downsizes images. Will throw OutOfMemory Exception for larger images.
options.inSampleSize = 8;
Bitmap bitmap = BitmapFactory.decodeFile(pictureUri.getPath(), options);
Log.v("Bitmap", bitmap.toString());
ImageView imgView = (ImageView) findViewById(R.id.imgPreview);
Log.v("ImgView", imgView.toString());
imgView.setImageBitmap(bitmap);
} catch (NullPointerException e) {
e.printStackTrace();
}
}
/**
* Creates the file uri to store an image.
*
* #param type - Refers to the captured image.
* #return Uri.fromFile - The file uri to store an image.
*/
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/**
* Returns the captured image.
*
* #param type - Refers to the captured image.
* #return null or mediaFile - mediaFile: Captured
* image inside of timestamped file.
*/
private static File getOutputMediaFile(int type) {
// External sdcard location.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
Log.v("Directory Two", mediaStorageDir.toString());
// Create the storage directory if it does not exists
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Creates a media file name corresponding to a timestamp.
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
/*
* Uploads the saved and captured image to the server.
*/
public class ImageUpload extends AsyncTask<String, String,String> {
String postUrl = "";
public void postURL(String url) {
postUrl = url;
}
/**
* Compresses the selected gallery image and encodes
* compressed image to a base64 string.
*
* #param params
*/
#Override
protected String doInBackground(String... params) {
String result = null;
try {
HttpClient client = new DefaultHttpClient();
String postURL = "";
HttpPost post = new HttpPost("http://IP here/files/justine/image_save.php");
ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
String msg = mEdit.getText().toString();
nameValuePair.add(new BasicNameValuePair("carid",msg));
//Converts image file uri to blob base64
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] byte_arr = stream.toByteArray();
String image_str = new String(Base64.encode(byte_arr, Base64.DEFAULT));
nameValuePair.add(new BasicNameValuePair("carimage", image_str));
UrlEncodedFormEntity ent = new UrlEncodedFormEntity(nameValuePair, HTTP.UTF_8);
post.setEntity(ent);
HttpResponse responsePOST = client.execute(post);
HttpEntity resEntity = responsePOST.getEntity();
result = EntityUtils.toString(resEntity);
if (resEntity != null) {
Log.i("RESPONSE", EntityUtils.toString(resEntity));
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
Toast.makeText(getApplicationContext(),
"Successfully uploaded", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(),
"Sorry! Failed to upload", Toast.LENGTH_SHORT).show();
}
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.justin.myapplication" >
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="22" />
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true">
</supports-screens>
<!-- Accessing camera hardware -->
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.screen.portrait" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboard|keyboardHidden"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Logcat:
07-15 13:34:52.998 22775-22775/? D/dalvikvm﹕ Late-enabling CheckJNI
07-15 13:34:53.154 22775-22775/com.example.justin.myapplication D/libEGL﹕ loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
07-15 13:34:53.162 22775-22775/com.example.justin.myapplication D/libEGL﹕ loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
07-15 13:34:53.170 22775-22775/com.example.justin.myapplication D/libEGL﹕ loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
07-15 13:34:53.256 22775-22775/com.example.justin.myapplication D/OpenGLRenderer﹕ Enabling debug mode 0
07-15 13:35:08.795 22775-22775/com.example.justin.myapplication V/EditText﹕ 77869548059
07-15 13:35:10.779 22775-22775/com.example.justin.myapplication V/Directory Two﹕ /storage/emulated/0/Pictures/Hello Camera
07-15 13:35:11.490 22775-22775/com.example.justin.myapplication W/IInputConnectionWrapper﹕ showStatusIcon on inactive InputConnection
07-15 13:35:18.350 22775-22775/com.example.justin.myapplication V/Directory﹕ /storage/emulated/0/Pictures/Hello Camera
07-15 13:35:18.412 22775-22775/com.example.justin.myapplication V/File listFiles﹕ [Ljava.io.File;#427723e8
07-15 13:35:18.412 22775-22775/com.example.justin.myapplication V/Random r﹕ java.util.Random#4277d730
07-15 13:35:18.412 22775-22775/com.example.justin.myapplication V/Random Picture File﹕ /storage/emulated/0/Pictures/Hello Camera/IMG_20150713_143026.jpg
07-15 13:35:18.412 22775-22775/com.example.justin.myapplication V/PictureUri﹕ file:///storage/emulated/0/Pictures/Hello%20Camera/IMG_20150713_143026.jpg
07-15 13:35:18.443 22775-22775/com.example.justin.myapplication D/dalvikvm﹕ GC_FOR_ALLOC freed 207K, 3% free 8778K/9024K, paused 19ms, total 21ms
07-15 13:35:18.443 22775-22775/com.example.justin.myapplication I/dalvikvm-heap﹕ Grow heap (frag case) to 8.897MB for 314944-byte allocation
07-15 13:35:18.459 22775-22784/com.example.justin.myapplication D/dalvikvm﹕ GC_FOR_ALLOC freed 6K, 3% free 9079K/9332K, paused 18ms, total 18ms
07-15 13:35:18.607 22775-22775/com.example.justin.myapplication V/Bitmap﹕ android.graphics.Bitmap#4275f650
07-15 13:35:18.607 22775-22775/com.example.justin.myapplication V/ImgView﹕ android.widget.ImageView{42748e50 V.ED.... ......I. 0,0-0,0 #7f0c0051 app:id/imgPreview}
I am confused as to why the bitmap is returning null. I appreciate any insight as to why as well as any suggestions of how to improve my current code for my interested goal. Thank you greatly.
I think you are missing a reference to your created directory. Haven't tried this myself, but this might work in your previewCapturedImage() method:
File mediaStorageDir = new File(Environment.getExternalStorageDirectory().toString() + IMAGE_DIRECTORY_NAME);
I think you failed to add IMAGE_DIRECTORY_NAME since I believe you are making that a directory.
mediaStorageDir.listFiles()
Returns a list of files, but it can also contain directories. To only retrieve files, use:
mediaStorageDir.listFiles(new FileFilter() {
public boolean accept(File file) {
return !file.isDirectory();
}
});

Android video record error

Can anybody point out the error I am doing? I am trying to record a short video, but somehow it finds a way to crash.
Source Code:
public class Start_recording extends Activity implements SurfaceHolder.Callback
{
MediaRecorder recorder;
SurfaceHolder surfaceHolder;
SurfaceView myVideoView;
Camera camera;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
camera = Camera.open();
camera.unlock();
recorder = new MediaRecorder();
setContentView(R.layout.activity_main_rst);
myVideoView = (SurfaceView)findViewById(R.id.surface_camera);
surfaceHolder = myVideoView.getHolder();
surfaceHolder.addCallback(this);
initMediaRecorder();
boolean exists = (new File(android.os.Environment.getExternalStorageDirectory() + "/Record/")).exists();
if (!exists)
{
new File(android.os.Environment.getExternalStorageDirectory() + "/Record/").mkdirs();
}
try
{
recorder.prepare(); // This is the line of error.
recorder.start();
Thread.sleep(36000);
recorder.stop();
setupActionBar();
}
catch(Exception e)
{
Log.v("Error is there : ",e.toString());
e.printStackTrace();
}
}
public void initMediaRecorder()
{
try
{
recorder.setPreviewDisplay(surfaceHolder.getSurface());
recorder.setCamera(camera);
recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(android.os.Environment.getExternalStorageDirectory()+"/Record/test.3gp");
recorder.setMaxDuration(300000);
}
catch(Exception f)
{
Log.v("Exception here : ",f.toString());
f.printStackTrace();
}
}
}
Error :
E/MediaRecorderJNI(1575): Application lost the surface
V/Error is there :(1575): java.io.IOException: invalid preview surface
W/System.err(1575): java.io.IOException: invalid preview surface
W/System.err(1575): at android.media.MediaRecorder._prepare(Native Method)
W/System.err(1575): at android.media.MediaRecorder.prepare(MediaRecorder.java:666)
W/System.err(1575): at com.example.project.Start_recording.onCreate(Start_recording.java:51)
I have added the permissions correctly in the Manifest file and also set the setPreviewDisplay(). But I get as invalid preview surface.Please correct me.
One has to use SurfaceHolder.Callback to start recording only after the surface really is created.

Drawing Text (TimeStamp) Over image captured from Standalone Camera

I have my code below that on click opens the camera, takes a photo, gets the photo from the camera, then puts in into a imageview. However i want to take the image and apply Text (Some sort of time stamp, either the time stamp from the image preferably, or just the system datetime) on the image and save as a jpeg.
If anyone can help me out that would be awesome.
public class PhotoIntentActivity extends Activity {
private static final int ACTION_TAKE_PHOTO_B = 1;
private static final String BITMAP_STORAGE_KEY = "viewbitmap";
private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility";
private ImageView mImageView;
private Bitmap mImageBitmap;
private String mCurrentPhotoPath;
private static final String JPEG_FILE_PREFIX = "IMG_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
private AlbumStorageDirFactory mAlbumStorageDirFactory = null;
/* Photo album for this application */
private String getAlbumName() {
return getString(R.string.album_name);
}
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = mAlbumStorageDirFactory.getAlbumStorageDir(getAlbumName());
if (storageDir != null) {
if (! storageDir.mkdirs()) {
if (! storageDir.exists()){
Log.d("CameraSample", "failed to create directory");
return null;
}
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File albumF = getAlbumDir();
File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF);
return imageF;
}
private File setUpPhotoFile() throws IOException {
File f = createImageFile();
mCurrentPhotoPath = f.getAbsolutePath();
return f;
}
private void setPic() {
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the ImageView */
int targetW = mImageView.getWidth();
int targetH = mImageView.getHeight();
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = 1;
if ((targetW > 0) || (targetH > 0)) {
scaleFactor = Math.min(photoW/targetW, photoH/targetH);
}
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
/* NEWELY ADDED CODE */
/* Decode the JPEG file into a Bitmap */
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
Bitmap replacedBitmap = timestampItAndSave(bitmap);
/* Associate the Bitmap to the ImageView */
mImageView.setImageBitmap(replacedBitmap);
mImageView.setVisibility(View.VISIBLE);
/* NEWELY ADDED CODE */
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO_B:
File f = null;
try {
f = setUpPhotoFile();
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
} // switch
startActivityForResult(takePictureIntent, actionCode);
}
private void handleBigCameraPhoto() {
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
Button.OnClickListener mTakePicOnClickListener =
new Button.OnClickListener() {
public void onClick(View v) {
dispatchTakePictureIntent(ACTION_TAKE_PHOTO_B);
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mImageView = (ImageView) findViewById(R.id.imageView1);
mImageBitmap = null;
Button picBtn = (Button) findViewById(R.id.btnIntend);
setBtnListenerOrDisable(
picBtn,
mTakePicOnClickListener,
MediaStore.ACTION_IMAGE_CAPTURE
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
mAlbumStorageDirFactory = new FroyoAlbumDirFactory();
} else {
mAlbumStorageDirFactory = new BaseAlbumDirFactory();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO_B: {
if (resultCode == RESULT_OK) {
handleBigCameraPhoto();
}
break;
} // ACTION_TAKE_PHOTO_B
}
}
// Some lifecycle callbacks so that the image can survive orientation change
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelable(BITMAP_STORAGE_KEY, mImageBitmap);
outState.putBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY, (mImageBitmap != null) );
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mImageBitmap = savedInstanceState.getParcelable(BITMAP_STORAGE_KEY);
mImageView.setImageBitmap(mImageBitmap);
mImageView.setVisibility(
savedInstanceState.getBoolean(IMAGEVIEW_VISIBILITY_STORAGE_KEY) ?
ImageView.VISIBLE : ImageView.INVISIBLE
);
}
/**
* Indicates whether the specified action can be used as an intent. This
* method queries the package manager for installed packages that can
* respond to an intent with the specified action. If no suitable package is
* found, this method returns false.
* http://android-developers.blogspot.com/2009/01/can-i-use-this-intent.html
*
* #param context The application's environment.
* #param action The Intent action to check for availability.
*
* #return True if an Intent with the specified action can be sent and
* responded to, false otherwise.
*/
public static boolean isIntentAvailable(Context context, String action) {
final PackageManager packageManager = context.getPackageManager();
final Intent intent = new Intent(action);
List<ResolveInfo> list =
packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
private void setBtnListenerOrDisable(
Button btn,
Button.OnClickListener onClickListener,
String intentName
) {
if (isIntentAvailable(this, intentName)) {
btn.setOnClickListener(onClickListener);
} else {
btn.setText(
getText(R.string.cannot).toString() + " " + btn.getText());
btn.setClickable(false);
}
}
}
Getting error on 4.0 emulators. Log Cat.
07-12 20:53:50.510: D/gralloc_goldfish(545): Emulator without GPU emulation detected.
07-12 20:53:54.861: W/IInputConnectionWrapper(545): showStatusIcon on inactive InputConnection
07-12 20:54:00.700: D/dalvikvm(545): GC_FOR_ALLOC freed 114K, 3% free 10052K/10311K, paused 217ms
07-12 20:54:00.710: I/dalvikvm-heap(545): Grow heap (frag case) to 11.072MB for 1228816-byte allocation
07-12 20:54:00.860: D/dalvikvm(545): GC_CONCURRENT freed 3K, 3% free 11249K/11527K, paused 4ms+3ms
07-12 20:54:00.960: D/AndroidRuntime(545): Shutting down VM
07-12 20:54:00.960: W/dalvikvm(545): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
07-12 20:54:01.000: E/AndroidRuntime(545): FATAL EXCEPTION: main
07-12 20:54:01.000: E/AndroidRuntime(545): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {com.example.android.photobyintent/com.example.android.photobyintent.PhotoIntentActivity}: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.ActivityThread.deliverResults(ActivityThread.java:2976)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3019)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.ActivityThread.access$1100(ActivityThread.java:122)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1176)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.os.Handler.dispatchMessage(Handler.java:99)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.os.Looper.loop(Looper.java:137)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.ActivityThread.main(ActivityThread.java:4340)
07-12 20:54:01.000: E/AndroidRuntime(545): at java.lang.reflect.Method.invokeNative(Native Method)
07-12 20:54:01.000: E/AndroidRuntime(545): at java.lang.reflect.Method.invoke(Method.java:511)
07-12 20:54:01.000: E/AndroidRuntime(545): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
07-12 20:54:01.000: E/AndroidRuntime(545): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
07-12 20:54:01.000: E/AndroidRuntime(545): at dalvik.system.NativeStart.main(Native Method)
07-12 20:54:01.000: E/AndroidRuntime(545): Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor
07-12 20:54:01.000: E/AndroidRuntime(545): at android.graphics.Canvas.<init> (Canvas.java:133)
07-12 20:54:01.000: E/AndroidRuntime(545): at com.example.android.photobyintent.PhotoIntentActivity.timestampItAndSave(PhotoIntentActivity.java:103)
07-12 20:54:01.000: E/AndroidRuntime(545): at com.example.android.photobyinten
t.PhotoIntentActivity.setPic(PhotoIntentActivity.java:154)
07-12 20:54:01.000: E/AndroidRuntime(545): at com.example.android.photobyintent.PhotoIntentActivity.handleBigCameraPhoto(PhotoIntentActivity.java:199)
07-12 20:54:01.000: E/AndroidRuntime(545): at com.example.android.photobyintent.PhotoIntentActivity.onActivityResult(PhotoIntentActivity.java:244)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.Activity.dispatchActivityResult(Activity.java:4649)
07-12 20:54:01.000: E/AndroidRuntime(545): at android.app.ActivityThread.deliverResults(ActivityThread.java:2972)
07-12 20:54:01.000: E/AndroidRuntime(545): ... 11 more
Updated code with draw bit map.
private Bitmap timestampItAndSave(Bitmap toEdit){
Bitmap dest = Bitmap.createBitmap(toEdit.getWidth(), toEdit.getHeight(), Bitmap.Config.ARGB_8888);
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD HH:MM:SS");
String dateTime = sdf.format(Calendar.getInstance().getTime()); // reading local time in the system
Canvas cs = new Canvas(dest);
Paint tPaint = new Paint();
tPaint.setTextSize(35);
tPaint.setColor(Color.BLUE);
tPaint.setStyle(Style.FILL);
float height = tPaint.measureText("yY");
cs.drawText(dateTime, 20f, height+15f, tPaint);
cs.drawBitmap(dest,0 ,0,tPaint);
try {
dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/timestamped")));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
return dest;
}
You don't want to put that in the onDraw method, as that's called whenever the View is invalidated (which you don't want).
Just create a method and put that code inside it. Call it after you've gotten the image, like so:
private Bitmap timestampItAndSave(Bitmap toEdit){
Bitmap dest = Bitmap.createBitmap(toEdit.getWidth(), toEdit.getHeight(), Bitmap.Config.ARGB_8888);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateTime = sdf.format(Calendar.getInstance().getTime()); // reading local time in the system
Canvas cs = new Canvas(dest);
Paint tPaint = new Paint();
tPaint.setTextSize(35);
tPaint.setColor(Color.BLUE);
tPaint.setStyle(Style.FILL);
float height = tPaint.measureText("yY");
cs.drawText(dateTime, 20f, height+15f, tPaint);
try {
dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(Environment.getExternalStorageDirectory() + "/timestamped")));
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
return dest;
}
I also recommend not saving it to "/sdcard/" but instead use Environment.getExternalStorageDirectory() (already implemented for you)
Edit: Also noticed you're creating a second Bitmap out of myImageBitmap; is that necessary?

Black Screen When App Opens

I keep getting this black screen when ever I open my app, the only way to get rid of it is to press the back button, then again go to the app. I was told by my friend that it is going into deadlock! but I do not think because when I checked the logcat it shows the below log messages.
View
private boolean mGameIsRunning;
public void surfaceCreated(SurfaceHolder holder) {
// Your own start method.
start();
}
public void start() {
if (!mGameIsRunning) {
thread.initLevel();
thread.setRunning(true);
thread.start();
mGameIsRunning = true;
} else {
thread.onResume();
thread.initLevel();
thread.setRunning(true);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "Surface is being destroyed");
// tell the thread to shut down and wait for it to finish
// this is a clean shutdown
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Log.d(TAG, "Thread was shut down cleanly");
}
Thread
private Object mPauseLock = new Object();
private boolean mPaused;
#Override
public void run() {
Canvas canvas;
Log.d(TAG, "Starting game loop");
while (running) {
canvas = null;
// try locking the canvas for exclusive pixel editing
// in the surface
try {
canvas = this.mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder) {
mStartTime = System.currentTimeMillis();
mElapsedTime = System.currentTimeMillis() - mStartTime;
this.updateGame();
this.onDraw(canvas);
}
synchronized(mPauseLock){
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
}
}
}
} finally {
// in case of an exception the surface is not left in
// an inconsistent state
if (canvas != null) {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
} // end finally
}
}
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
Log
07-08 17:24:41.735: DEBUG/Hitman(3221): View added
07-08 17:24:41.895: DEBUG/(3221): Enemies Spawed
07-08 17:24:41.934: DEBUG/(3221): Starting game loop
07-08 17:24:42.165: INFO/ActivityManager(66): Displayed activity com.android.hitmanassault/.Hitman: 1384 ms (total 1384 ms)
07-08 17:24:46.164: DEBUG/(3221): Enemies Spawed
07-08 17:24:48.914: INFO/ActivityManager(66): Start proc com.android.settings for broadcast com.android.settings/.widget.SettingsAppWidgetProvider: pid=3228 uid=1000 gids={3002, 3001, 3003}
07-08 17:24:48.914: INFO/ActivityManager(66): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher/.Launcher }
07-08 17:24:48.924: DEBUG/PhoneWindow(3221): couldn't save which view has focus because the focused view com.android.hitmanassault.HitmanView#44d99528 has no id.
07-08 17:24:48.954: INFO/WindowManager(66): Setting rotation to 0, animFlags=0
07-08 17:24:49.014: INFO/ActivityManager(66): Config changed: { scale=1.0 imsi=310/260 loc=en_US touch=3 keys=2/1/2 nav=3/1 orien=1 layout=34}
07-08 17:24:49.275: DEBUG/(3221): Surface is being destroyed
07-08 17:24:49.285: DEBUG/(3221): Thread was shut down cleanly
07-08 17:24:49.694: DEBUG/ddm-heap(3228): Got feature list request
07-08 17:24:49.754: WARN/IInputConnectionWrapper(3221): showStatusIcon on inactive InputConnection
07-08 17:24:51.315: DEBUG/dalvikvm(66): GC freed 2325 objects / 114696 bytes in 122ms
07-08 17:24:58.234: INFO/ActivityManager(66): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.hitmanassault/.HitmanTitle }
07-08 17:24:58.284: INFO/WindowManager(66): Setting rotation to 1, animFlags=0
07-08 17:24:58.354: INFO/ActivityManager(66): Config changed: { scale=1.0 imsi=310/260 loc=en_US touch=3 keys=2/1/2 nav=3/1 orien=2 layout=34}
07-08 17:24:58.554: DEBUG/(3221): Enemies Spawed
07-08 17:24:58.945: WARN/IInputConnectionWrapper(144): showStatusIcon on inactive InputConnection
07-08 17:25:00.604: DEBUG/dalvikvm(66): GC freed 1403 objects / 71832 bytes in 103ms
Activity Class:
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.game_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.menu_restart:
startActivity(new Intent(this, Hitman.class));
return true;
case R.id.menu_scores:
startActivity(new Intent(this, HitmanScores.class));
return true;
case R.id.menu_help:
startActivity(new Intent(this, HitmanHelp.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new CanvasSurfaceView(this));
Log.d(TAG, "View added");
}
Does rotating the display cause it to refresh (in emulator: CTRL+F12)? If so then you have to override onResume() in your activity and have it restart whatever it is you set up that might not be being called. It could be that you just need to call view.invalidate() from the activity onResume()? You don't show code from your activity so I'm unsure.
In the code I saw, you should use this.postInvalidate() (same as invalidate() but for from a different thread) instead of this.onDraw(canvas) and have it call this.onDraw() on its own in the UI thread, as opposed to in your thread.
Where do you initialize your thread? Try doing so in surfaceCreated( ) instead of the surfaceView consturctor (which is where I think you did it..)
public void surfaceCreated(SurfaceHolder holder) {
// Restart draw thread
Thread.State state = thread.getState();
if(state == Thread.State.TERMINATED)
thread = new MyThread(getHolder(), getContext());
thread.setRunning(true);
thread.start();
}

Categories

Resources