1

This might be a possible duplicate but i can't seem to pinpoint the exact solution. Camera works fine and returns the image uri on devices below api 23. However app crushes right after capturing image on devices apove api 23 with log error

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { act=inline-data (has extras) }} to activity {ana.foodi/ana.foodi.MainActivity}: java.lang.NullPointerException: uri
                                                         at android.app.ActivityThread.deliverResults(ActivityThread.java:3940)
                                                         at android.app.ActivityThread.handleSendResult(ActivityThread.java:3983)
                                                         at android.app.ActivityThread.-wrap16(ActivityThread.java)
                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1548)
                                                         at android.os.Handler.dispatchMessage(Handler.java:111)
                                                         at android.os.Looper.loop(Looper.java:207)
                                                         at android.app.ActivityThread.main(ActivityThread.java:5765)
                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
                                                      Caused by: java.lang.NullPointerException: uri
                                                         at com.android.internal.util.Preconditions.checkNotNull(Preconditions.java:60)
                                                         at android.content.ContentResolver.query(ContentResolver.java:481)
                                                         at android.content.ContentResolver.query(ContentResolver.java:441)
                                                         at ana.foodi.MainActivity.onActivityResult(MainActivity.java:672)

After checking with breakpoints,realised Uri (selectedImage) is null below:

 @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    final String filePath;
    if(resultCode == Activity.RESULT_OK && REQUEST_POST_PHOTO==999){


        if(requestCode == 2 ) {
            requestRuntimePermission();
            Uri selectedImage = data.getData();
            String[] filePaths = {MediaStore.Images.Media.DATA};
            Cursor c = this.getContentResolver().query(selectedImage, filePaths, null, null, null);
            c.moveToFirst();
            int columnIndex = c.getColumnIndex(filePaths[0]);
            filePath = c.getString(columnIndex);
            c.close();

I've tried requesting runtime permission with this

public void requestRuntimePermission() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }
}

but error persist.

startActivityForResult call

REQUEST_POST_PHOTO=999;
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, REQUEST_CODE_POST);
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Beulah Ana
  • 360
  • 2
  • 14
  • You required only WRITE_EXTERNAL_STORAGE permission. You need to require all *dangerous* level permissions. On [this link](https://developer.android.com/reference/android/Manifest.permission.html) you have a *protection level* field for each permission. – Diego D. Dec 26 '17 at 13:42
  • "Camera works fine and returns the image uri on devices below api 23" -- you do not show your `startActivityForResult()` call. If you are using `ACTION_IMAGE_CAPTURE`, it is not supposed to return a `Uri`, and few devices will have a camera app that does return a `Uri`. – CommonsWare Dec 26 '17 at 13:47
  • @CommonsWare added – Beulah Ana Dec 26 '17 at 13:55

5 Answers5

2

You are using ACTION_IMAGE_CAPTURE. ACTION_IMAGE_CAPTURE is not supposed to return a Uri via onActivityResult(). Instead, either:

  • You provide EXTRA_OUTPUT on the ACTION_IMAGE_CAPTURE Intent, in which case the image is supposed to be saved to that location (see this sample app), or

  • You do not provide EXTRA_OUTPUT on the ACTION_IMAGE_CAPTURE Intent, in which case you get a thumbnail Bitmap back via the "data" extra on the Intent delivered to onActivityResult()

This is covered in the documentation.

Some buggy camera apps will return a Uri. Do not count on this behavior, as well-written camera apps will not.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
1
private static final int REQUEST_CODE_IMAGE = 1000;
private String importFileName = "";

private void cameraIntent() {
    importFileName = getString(R.string.app_name) + new Random().nextInt();
    startActivityForResult(getCameraIntent(context, importFileName), REQUEST_CODE_IMAGE);
}

public Intent getCameraIntent(Context context, String fileName) {
    Intent chooserIntent = null;
    List<Intent> intentList = new ArrayList<>();
    Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    takePhotoIntent.putExtra("return-data", true);
    takePhotoIntent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, context.getResources().getConfiguration().orientation);
    takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(context.getExternalCacheDir(), fileName)));
    intentList = addIntentsToList(context, intentList, Collections.singletonList(takePhotoIntent));

    if (intentList.size() > 0) {
        String title = context.getResources().getString(R.string.choose);
        chooserIntent = Intent.createChooser(intentList.remove(intentList.size() - 1), title);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentList.toArray(new Parcelable[]{}));
    }
    return chooserIntent;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CODE_IMAGE:
            if (resultCode == RESULT_OK) {
                onCaptureImageResult(data);
            }
            break;
    }
}

private void onCaptureImageResult(Intent data) {
    Uri imageUri;
    if (data == null) {
        imageUri = Uri.fromFile(new File(getExternalCacheDir(), importFileName));
    } else {
        imageUri = data.getData();
        if (imageUri == null)
            imageUri = Uri.fromFile(new File(getExternalCacheDir(), importFileName));
    }
}

If you get permissions (camera, read/write external storage permissions) from user, this code snippet will work correctly. You can call cameraIntent().

buraktemzc
  • 390
  • 1
  • 6
  • 19
0

Try this

Use both WRITE_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE to read and write file

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

Here ask to write permission & read permission add multiple permission

public void requestRuntimePermission() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (ContextCompat.checkSelfPermission(context,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        }
    }
}

Check this Android 6.0 multiple permissions

//Check permission granted or not if granted then call this block

        Uri selectedImage = data.getData();
        String[] filePaths = {MediaStore.Images.Media.DATA};
        Cursor c = this.getContentResolver().query(selectedImage, filePaths, null, null, null);
        c.moveToFirst();
        int columnIndex = c.getColumnIndex(filePaths[0]);
        filePath = c.getString(columnIndex);
        c.close();
Ramesh sambu
  • 3,577
  • 2
  • 24
  • 39
0

At least for older versions, if multiple selection is allowed (Intent#EXTRA_ALLOW_MULTIPLE), URIs will be returned as clipboard data:

data.getClipData()

See Intent#getClipData() and ClipData.

Check if data is being returned there:

ClipData clipData = data.getClipData();
Uri selectedImage = null;
if (clipData != null) {
    selectedImage = clipData.getItemAt(0).getUri();
} else {
    selectedImage = data.getData();
}
Xavier Rubio Jansana
  • 6,388
  • 1
  • 27
  • 50
0
 targetSdkVersion 21
 change your targetsdk version in build.gradle to marshmallow it will be solved. 
PRATEEK BHARDWAJ
  • 2,364
  • 2
  • 21
  • 35