Joolz Zenda
Joolz Zenda

Reputation: 47

android - app crashes when saving photograph

I've been following the camera guide from http://developer.android.com/guide/topics/media/camera.html

Everything works until after I have taken the photograph and selected the tick to accept the image. Then I get the dreaded 'unfortunately app has stopped working'. I'm testing on a real nexus 5 device.

My code is

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}

/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

/* Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
      return Uri.fromFile(getOutputMediaFile(type));
} 


private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private Uri fileUri;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;

/* Create a File for saving an image or video */
private static File getOutputMediaFile(int type){

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "SimpleCamera");

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("SimpleCamera", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").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;
}

public void openCamera(View view){
    // create Intent to take a picture and return control to the calling application
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

    // start the image capture Intent
    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Image captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "Image saved to:\n" +
                     data.getData(), Toast.LENGTH_LONG).show();
        } else if (resultCode == RESULT_CANCELED) {
            // User cancelled the image capture
        } else {
            // Image capture failed, advise user
        }
    }
}

In my manifest I have included

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />

My Logcat

03-20 12:40:53.658: E/AndroidRuntime(21487): FATAL EXCEPTION: main
03-20 12:40:53.658: E/AndroidRuntime(21487): Process: com.juliette.simplecamera, PID: 21487
03-20 12:40:53.658: E/AndroidRuntime(21487): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=null} to activity {com.juliette.simplecamera/com.juliette.simplecamera.MainActivity}: java.lang.NullPointerException
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3365)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3408)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.ActivityThread.access$1300(ActivityThread.java:135)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1244)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.os.Handler.dispatchMessage(Handler.java:102)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.os.Looper.loop(Looper.java:136)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.ActivityThread.main(ActivityThread.java:5017)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at java.lang.reflect.Method.invokeNative(Native Method)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at java.lang.reflect.Method.invoke(Method.java:515)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at dalvik.system.NativeStart.main(Native Method)
03-20 12:40:53.658: E/AndroidRuntime(21487): Caused by: java.lang.NullPointerException
03-20 12:40:53.658: E/AndroidRuntime(21487):    at com.juliette.simplecamera.MainActivity.onActivityResult(MainActivity.java:94)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.Activity.dispatchActivityResult(Activity.java:5423)
03-20 12:40:53.658: E/AndroidRuntime(21487):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3361)

And my layout just in case

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.juliette.simplecamera.MainActivity" >

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="58dp"
    android:text="@string/camera" 
    android:onClick="openCamera"/>

</RelativeLayout>

I know the issue is something to do with returning to the original activity with the result but I have no idea how to resolve this. Any suggestions would be appreciated, I'm quite new at this and I'm assuming I've made a simple rookie mistake.

Thanks in advance!

Upvotes: 1

Views: 1594

Answers (3)

Hamid Shatu
Hamid Shatu

Reputation: 9700

In this line occurring the crash...because, data is null.

Toast.makeText(this, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();

This line saying that data is null...

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=null}

So, when you are trying to get data using getData() method from Intent object data then NullPointerException occurring.

To prevent this Exception, check that data isn't null before trying to get data as below...

if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
    if (resultCode == RESULT_OK) {

        if(data != null) {

            Toast.makeText(this, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show();
        }
    }
}

Upvotes: 3

GrIsHu
GrIsHu

Reputation: 23638

From your logcat below like it clearly indicates that your Intent data is null.

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=null}

Check for the null value of the Intent data.

Try out as below:

if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
    if (resultCode == RESULT_OK && null != data) {

        // Image captured and saved to fileUri specified in the Intent
        Toast.makeText(this, "Image saved to:\n" +
                 data.getData(), Toast.LENGTH_LONG).show();
    } 

Upvotes: 2

Mr. Borad
Mr. Borad

Reputation: 391

try this

Toast.makeText(MainActivity.this, "Image saved to:\n" +
                     data.getData(), Toast.LENGTH_LONG).show();

Upvotes: 0

Related Questions