0

I am trying to figure out the right way to get a file path from the camera after a picture is taken:

Launch the camera intent. Since I am telling the camera to write to internal storage give it the uri and read permission:

File file = new File(context.getFilesDir(), "picture.jpg");
Uri uri = FileProvider.getUriForFile(getApplicationContext(), "my.app.package.fileprovider", file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, ACTION_IMAGE_CAPTURE_REQUEST_CODE);

Listen for the camera intent result:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) {
        return;
    }
    switch (requestCode) {
    case ACTION_IMAGE_CAPTURE_REQUEST_CODE:
        // How do I get the local path to the file here?
        break;
    }
}

What is the best way to get the file path on camera intent return. Sure I can save off the file path to a member variable before launching the intent, but that seems bad, seems I should get the path from the onActivityResult.

I have tried this (Get Image path from camera intent):

String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(MediaStore.Images.Media.INTERNAL_CONTENT_URI,projection, null, null, null);
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToLast();

String imagePath = cursor.getString(column_index_data);

Only difference being that I am using INTERNAL_CONTENT_URI as I am trying to store the pic internally. If I do this I get an exception:

Error getting data column
java.lang.IllegalArgumentException: column '_data' does not exist

Am I going about this wrong. I want to take a pic and store that pic in internal storage.

EDIT:

One more thought. Should I be storing pics internally? I am right not because of the new android M permissions. I already have to ask the user for Camera permission, if I store pic to external storage, I have to ask the user for permission to write to to external. Lastly if I store the image externally, it is readable by all applications on the device that can read from external storage. This may be a privacy issue for my app.

Community
  • 1
  • 1
lostintranslation
  • 23,756
  • 50
  • 159
  • 262

1 Answers1

0

What is the best way to get the file path on camera intent return

You specified the file path in EXTRA_OUTPUT. Either the camera put the photo there, or it didn't. If it did, then you already know the file path: new File(context.getFilesDir(), "picture.jpg"). That should be the case the vast majority of the time.

Some camera apps are buggy and will ignore EXTRA_OUTPUT. In those cases:

  • You can see if the camera app returned a Uri in the Intent passed to onActivityResult(), then use ContentResolver and openInputStream() to begin the process of copying the image to your desired location, or

  • You can see if the "data" extra exists, in which case that's a Bitmap thumbnail that you can save to your desired location.

In all of these cases, the file path is what you specified; it is merely a question of whether or not it takes additional work for you to get the image there.

Sure I can save off the file path to a member variable before launching the intent, but that seems bad

I have no idea why you would think that.

seems I should get the path from the onActivityResult

You are welcome to believe whatever you want. Camera app developers are hopefully reading the documentation for ACTION_IMAGE_CAPTURE. That documentation does not state that the camera app has to return anything if you provide EXTRA_OUTPUT. Hence, many camera apps will not return anything.


UPDATE based on edit:

Should I be storing pics internally?

Um, you already are.

if I store pic to external storage, I have to ask the user for permission to write to to external

That depends on where you are writing. getExternalFilesDir(), getExternalCacheDir(), and kin from Context do not require a permission on Android 4.4+. The methods you call on Environment for external storage locations (e.g., getExternalStoragePublicDirectory()) do require WRITE_EXTERNAL_STORAGE, which is a dangerous permission and would need to be requested at runtime.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 'That documentation does not state that the camera app has to return anything if you provide EXTRA_OUTPUT'. That means you must always store the path to the file you are asking the Camera intent to write to as that is the only sure way to get that path in onActivityResult, correct? – lostintranslation Dec 18 '15 at 22:45
  • @lostintranslation: Correct. Though by "store", `onSaveInstanceState()` should suffice. BTW, I just noticed your edit and updated my answer. – CommonsWare Dec 18 '15 at 22:51
  • ah crap! getExternalFilesDir() is an externally stored location only readable to my application. Allowing externally stored media that is private to my app. Thanks! – lostintranslation Dec 18 '15 at 22:57
  • @lostintranslation: "getExternalFilesDir() is an externally stored location only readable to my application" -- no. It is readable by any app with `READ_EXTERNAL_STORAGE` or `WRITE_EXTERNAL_STORAGE`. It is *unique* for your app. It is not *private* for your app. – CommonsWare Dec 18 '15 at 22:58
  • Yup, sorry catching up on docs. So basically if I want my media to be readable by my app only my choice is internal storage. With the limitation that I am eating into possibly limited storage. At least according to android docs/recommendation: http://developer.android.com/intl/es/guide/topics/media/camera.html#saving-media – lostintranslation Dec 18 '15 at 23:34
  • @lostintranslation: "So basically if I want my media to be readable by my app only my choice is internal storage" -- correct. "With the limitation that I am eating into possibly limited storage" -- not on most modern Android devices (anything running Android 4.0+). Internal and external storage usually are on the same partition. – CommonsWare Dec 19 '15 at 00:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/98394/discussion-between-lostintranslation-and-commonsware). – lostintranslation Dec 19 '15 at 03:15