I have code that I inherited that worked in < API 23. I had to upgrade it to work with the latest APIs, and it necessitated me to use a FileProvider now, due to an exposed file security issue. No bigs. However, now the camera doesn't work (and it's not necessarily due to the FileProvider, it just happened to have stopped working at the same time as needing to use FileProvider, due to the upgraded API)
The code dies on the create intent call for the MediaStore.ACTION_IMAGE_CAPTURE intent with the error:
android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.media.action.IMAGE_CAPTURE dat=content://com.company.appname/external_files/temp.jpg flg=0x1 }
I've done a ton of searching for this, but everyone (especially StackOverflow so far) seems to think that adding code to check whether a camera is present will solve this, but it doesn't. It's just a check to not run the code if a camera is not detected. All my devices I'm using to test have cameras. I've debugged on the Android emulator (and verified the emulated camera is connected to my laptop camera by taking a picture of myself using the default camera application) as well as my phone, which has front and back cameras, both of which work. So, no answers that circumvent the problem, please. I know I have cameras and don't need to check for them. I need help determining why my code isn't finding an intent for MediaStore.ACTION_IMAGE_CAPTURE.
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
and
<provider
android:name=".Providers.GenericFileProvider"
android:authorities="com.company.myapp"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
MainActivity.java
File f = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
Uri uri = FileProvider.getUriForFile(MainActivity.this, AUTHORITY, f);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CAMERA);
The code throws an exception on the last line when it starts the activity. Because this was inherited code, I'm tempted to scrap what they have for the camera capture and start fresh, but the code used to work before it was upgraded for > API 23.
Just FYI, the previous call before the upgrade looked like
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
but that no longer works (blocked by API because of the exposure of the file URI)
Has anyone found out how to make this work?
Style Note
I edited the code for brevity, there is exception handling in the production code.
Just an fyi, the previous call before the upgrade looked like
That code uses EXTRA_OUTPUT
, which is the correct way to pass the Uri
with ACTION_IMAGE_CAPTURE
. Its problem is the Uri.fromFile()
part, which will not work on Android 7.0+, once your targetSdkVersion
rises to 24 or higher, as you noted.
The correct code is the combination of the two:
File f = new File(Environment.getExternalStorageDirectory(), "temp.jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(MainActivity.this, AUTHORITY, f));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CAMERA);
See this sample app for a complete example of using ACTION_IMAGE_CAPTURE
with FileProvider
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With