Emulator crashes when capturing a photo (NullPoint

2019-03-01 13:45发布

问题:

I'm having some issues while capturing photos.

Until now, I could take pictures from camera, from emulator and from a real device, without problems. But those pictures, were saved on a default route.

I wanted to edit that route, so I could set my own.

I did it this way:

File folder = new File(Environment.getExternalStorageDirectory().toString()+"/ImagesFolder/");
            folder.mkdirs();

            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            Uri uriSavedImage=Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString()+"/ImagesFolder/imatge.jpg"));
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

            startActivityForResult(cameraIntent, 1888);

This is working on a real device, a Sony Ericsson Xperia Ray. It creates the folder, and saves the image there.

But the issue is on emulator. I'm afraid this will happen on other devices.

This is the logcat:

01-06 21:35:21.115: E/AndroidRuntime(1565): FATAL EXCEPTION: main
01-06 21:35:21.115: E/AndroidRuntime(1565): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=264032, result=-1, data=null} to activity {com.exercise.AndroidViewPager/com.exercise.AndroidViewPager.AndroidViewPagerActivity}: java.lang.NullPointerException
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3319)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3362)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.ActivityThread.access$1100(ActivityThread.java:141)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.os.Looper.loop(Looper.java:137)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.ActivityThread.main(ActivityThread.java:5039)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at java.lang.reflect.Method.invokeNative(Native Method)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at java.lang.reflect.Method.invoke(Method.java:511)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at dalvik.system.NativeStart.main(Native Method)
01-06 21:35:21.115: E/AndroidRuntime(1565): Caused by: java.lang.NullPointerException
01-06 21:35:21.115: E/AndroidRuntime(1565):     at com.exercise.AndroidViewPager.MyFragmentD.onActivityResult(MyFragmentD.java:52)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:152)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.Activity.dispatchActivityResult(Activity.java:5293)
01-06 21:35:21.115: E/AndroidRuntime(1565):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)
01-06 21:35:21.115: E/AndroidRuntime(1565):     ... 11 more

The crash:

01-06 21:35:21.115: E/AndroidRuntime(1565): Caused by: java.lang.NullPointerException
01-06 21:35:21.115: E/AndroidRuntime(1565):     at com.exercise.AndroidViewPager.MyFragmentD.onActivityResult(MyFragmentD.java:52)

Comes from here:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if( requestCode == 1888 && resultCode == -1) { //-1 = TOT HA ANAT BE.
        Bitmap photo = (Bitmap) data.getExtras().get("data");
        Log.d("debugging",""+photo.getHeight());
        Log.d("debugging",""+photo.getWidth());
        ((ImageView) myFragmentView.findViewById(R.id.fotoCapturada)).setImageBitmap(photo);
    }
}

Exactly:

Bitmap photo = (Bitmap) data.getExtras().get("data");

After some research, I found out nothing clear...

Can you help me on this issue?

Thanks.

回答1:

Since your data extras method isn't working, you could try storing a field of the file or the path when the Intent is launched.

File resultingFile;//This will be in your class definition

File folder = new File(Environment.getExternalStorageDirectory().toString()+"/ImagesFolder/");
folder.mkdirs();

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
resultingFile = new File(folder.toString() + "/image.jpg");
Uri uriSavedImage=Uri.fromFile(resultingFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

startActivityForResult(cameraIntent, 1888);

So when you enter onActivityResult you can test the resultCode against RESULT_OK and RESULT_CANCELED. When I use onActivityResult, I do it like this:

if(requestCode == 1888){
  if(resultCode == RESULT_OK){ //Called when the user saves the image
     if(resultingFile.exists(){
       Bitmap photo = BitmapFactory.decodeFile(resultingFile.getPath()); 
       ((ImageView) myFragmentView.findViewById(R.id.fotoCapturada)).setImageBitmap(photo);
     }
  }else if(resultCode == RESULT_CANCELED){ //Called when the user presses back or cancels the saving of the image

  }
}


回答2:

After some help, specially from @BackpackOnHead, I got it.

What did I achieve?

  • Retrieve a picture from camera,
  • save it on a specified folder
  • save it on a specified name

This is the final code:

On declaration of the class:

File resultingFile;

When clicking the button that starts camera:

public void onClick(View v) {
            Log.d("debugging","Has clicat al botó");

            File folder = new File(Environment.getExternalStorageDirectory().toString()+"/FolderWithImages/"); //NAME OF THE FOLDER
            folder.mkdirs();

            Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            resultingFile=new File(folder.toString() + "/imatge.jpg"); //THIS IS THE NAME OF THE FILE
            Uri uriSavedImage=Uri.fromFile(resultingFile);
            cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);

            startActivityForResult(cameraIntent, 1888);
        }   

Then on, onActivityResult:

Bitmap photo = BitmapFactory.decodeFile(resultingFile.getPath());
        Log.d("debugging",resultingFile.getPath());
        ((ImageView) myFragmentView.findViewById(R.id.fotoCapturada)).setImageBitmap(photo);

Yay!

Why did I do it this way and not with Bitmap photo = (Bitmap) data.getExtras().get("data"); ?

Basically, because for some unknown (for me) reason, on some devices, aswel as on emulator, this .getExtras is returning null, thing that in some devices, obvioulsy, as it should, isn't returning null. This "getExtras" provided the photo. We had to use a workaround, that isn't maybe clear and clean, but it does the trick.



回答3:

getExtras() can return null which in your case it probably does.



回答4:

Try this:

File f = createImageFile();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, f.getAbsolutePath());
startActivityForResult(takePictureIntent, 1);