1

I am having an issue when trying to retrieve a photo from the camera

I am trying to allow the user to take a photo with the camera application, then show a preview of it in the application.

I will also need access to the file at a later stage in the application (But this is not an issue)

I am having the following crash:

Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{41f55850 10769:com.sec.android.app.camera/u0a84} (pid=10769, uid=10084) that is not exported from uid 10119

I have followed This link and a couple others. I dont have an issue on devices like my Galaxy S8+. Only this device that is running Android 4.4.4 API 19.

Android Manifest:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">

        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="my_images"
        path="Android/data/com.example.app/files/Pictures" />
</paths>

PhotoActivity.java

    private File setUpPhotoFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
    String imageFileName = "IMG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",   /* suffix */
            storageDir      /* directory */
    );
    return image;
}

Starting the camera intent when clicking a button:

if (isCameraApplicationAvailable(PhotoActivity.this)) {
                Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);


                File f = null;
                try {
                    f = setUpPhotoFile();
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(PhotoActivity.this, BuildConfig.APPLICATION_ID + ".provider", f));
                } catch (IOException e) {
                   // Handle exception
                }
                List<ResolveInfo> resolvedIntentActivities = getPackageManager().queryIntentActivities(takePictureIntent, PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolvedIntentInfo : resolvedIntentActivities) {
                    String packageName = resolvedIntentInfo.activityInfo.packageName;

                    grantUriPermission(packageName, Uri.fromFile(f), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
                takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivityForResult(takePictureIntent, ACTION_TAKE_PHOTO);
            }

Handle image when complete:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ACTION_TAKE_PHOTO && resultCode == Activity.RESULT_OK) {
        handleCameraPhoto();
    }
}

I dont understand why its only an issue on 4.4.4 and not other OS's.

When there is a crash, it doesn't say my application crashed, it says Camera has stopped working and I can only view the crash when I am viewing the logs with no filter, which means the crash is not in my application?

Stillie
  • 2,647
  • 6
  • 28
  • 50
  • 1
    Permission Denial, please add external read permission in manifest – Basi Apr 09 '19 at 07:03
  • check this question : https://stackoverflow.com/questions/24467696/android-file-provider-permission-denial – ToraCode Apr 09 '19 at 07:05
  • 2
    Possible duplicate of [FileProvider Not Working with Camera](https://stackoverflow.com/questions/33650632/fileprovider-not-working-with-camera) – denis_lor Apr 09 '19 at 07:05
  • Sorry that permission is in the manifest as well – Stillie Apr 09 '19 at 07:05
  • Possible duplicate of [Android - file provider - permission denial](https://stackoverflow.com/questions/24467696/android-file-provider-permission-denial) – Basi Apr 09 '19 at 07:08
  • You will see I am manually requesting perms as mentioned in the suggest SO link – Stillie Apr 09 '19 at 07:09
  • The `Uri` you pass in the `grantUriPermission()` call needs to be the `Uri` from the `FileProvider`, not `Uri.fromFile(f)`. – Mike M. Apr 09 '19 at 07:10
  • @MikeM. Thank you!! This sorted this out. Can you create an answer for this so i can accept? – Stillie Apr 09 '19 at 07:48
  • Oh, I'm good. :-) It was just a slight mix-up. Nothing major. Feel free to post an answer yourself, so you can close out your question, in a couple of days. Btw, you might consider doing a version check, kinda like the one Soham suggested, so you're not doing that `grantUriPermission()` loop unnecessarily on versions that don't need it. Anyhoo, glad you got it working. Cheers! – Mike M. Apr 09 '19 at 08:39

4 Answers4

1

As per @MikeM's comment I was using Uri.fromFile(file) instead of using the FileProvider to get the Uri.

Was doing this:

grantUriPermission(packageName, Uri.fromFile(f), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

When I should have been doing this:

grantUriPermission(packageName, FileProvider.getUriForFile(PhotoActivity.this, BuildConfig.APPLICATION_ID + ".provider", f), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

This fixed the issue I had

Thank you @MikeM

Stillie
  • 2,647
  • 6
  • 28
  • 50
0

For security reason using file provider you have to use Flag in your intent. So use addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); or addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); in your takePictureIntent

This is necessary for file provider in Android <= Lollipop (API 22)

Tariqul Islam
  • 680
  • 6
  • 14
0

I think a simple check will solve your problem.

      if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
       grantUriPermission(packageName, Uri.fromFile(f), 
Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); 

    takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION|Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
Soham
  • 4,397
  • 11
  • 43
  • 71
-1

You're facing this issue because you've haven't specified runtime permissions in your app search on google for specifying run time permissions programmatically after doing that your issue should be solved.