2

Good day.I have an weird issue to which none of examples in stack overflow has worked.I am opening an gallery,after which i am redirecting user to crop intent.Important to mention that this only happens on android N and not below devices.The issue is that this exception is thrown as soon as the crop is done..I dont know what causes this,but actually here is how i start crop intent.

 Intent cropIntent = new Intent("com.android.camera.action.CROP");
    cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);


    Uri outPutUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", new File(output));
    Uri photoURI = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", new File(path));

    activity.grantUriPermission("com.android.camera.action.CROP", outPutUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    activity.grantUriPermission("com.android.camera.action.CROP", photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

    cropIntent.setDataAndType(photoURI, "image/*");

    cropIntent.putExtra("crop", "true");

    cropIntent.putExtra("aspectX", aspectX);
    cropIntent.putExtra("aspectY", aspectY);


    cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);

    activity.startActivityForResult(cropIntent, CROP_REQUEST);

I have granted the Uri permission,have added these to 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/provider_paths"/>

I have tried all stack over flow answer examples,there is no more issue on stack overflow with this scenario and not any of them have worked.So what is the issue with android N ?Should it be so hard?

This is the exception which is being thrown

FATAL EXCEPTION: main
Process: com.android.gallery3d, PID: 5735
java.lang.SecurityException: Permission Denial: writing android.support.v4.content.FileProvider uri content://my.package.name/external_files/Android/data/my.package.name/cache/0.5062300225583558.png from pid=5735, uid=10071 requires the provider be exported, or grantUriPermission()
at android.os.Parcel.readException(Parcel.java:1683)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:621)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1000)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:742)
at android.content.ContentResolver.openOutputStream(ContentResolver.java:718)
at com.android.gallery3d.filtershow.crop.CropActivity$BitmapIOTask.<init>(CropActivity.java:408)
at com.android.gallery3d.filtershow.crop.CropActivity.startBitmapIO(CropActivity.java:339)
at com.android.gallery3d.filtershow.crop.CropActivity.startFinishOutput(CropActivity.java:311)
at com.android.gallery3d.filtershow.crop.CropActivity$1.onClick(CropActivity.java:117)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22260)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
09-30 13:19:44.376 11909-11942/volo.global.pingbing E/FA: Task exception on worker thread: java.lang.IncompatibleClassChangeError: The method 'java.io.File android.support.v4.content.ContextCompat.getNoBackupFilesDir(android.content.Context)' was expected to be of type virtual but instead was found to be of type direct (declaration of 'com.google.firebase.iid.zzg' appears in /data/app/volo.global.pingbing-1/base.apk): com.google.android.gms.measurement.internal.zzt.zzEd(Unknown Source)
Maveňツ
  • 1
  • 12
  • 50
  • 89
fasf safsaf
  • 31
  • 1
  • 5
  • Do post your [logcat](http://www.cmstactical.net/uploads/4/8/9/1/48914725/9763380_orig.jpg) will help us more to get your issue. – Maveňツ Sep 30 '16 at 10:18
  • one minute ill post – fasf safsaf Sep 30 '16 at 10:22
  • This is not correct way to grant for SD Read/Write Permission, Please refer [this link](https://developer.android.com/training/permissions/requesting.html) – Maveňツ Sep 30 '16 at 10:38
  • 1
    this is not granting to the sd card...this is issue on Android N as i have told you,this happens exclusevely on android N and no on any other platform OS,only on Android N whenever i target 24 sdk,and i do not want to target lower and everyone said this is the single solution – fasf safsaf Sep 30 '16 at 10:40
  • Still google have not updated Permissions and security issues in [android N](https://developer.android.com/about/versions/nougat/android-7.0-changes.html) – Maveňツ Sep 30 '16 at 10:43
  • @fasfsafsaf Is your problem still persist ? – Ambar Jain Jun 12 '17 at 06:28

3 Answers3

8
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            grantUriPermission(packageName, photoURI, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
angryITguy
  • 9,332
  • 8
  • 54
  • 82
Tong Tracy
  • 111
  • 1
  • 6
  • 2
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – J. Chomel Feb 21 '17 at 07:05
  • 2
    Thank you for your advice.Let me explain the reason of this code.In Android N,you must get permission of the "write or read Uri file" for security.when you want system photo to crop your "uri file",so you must allow system photo. if you don't know this package name,you can through all the package name. – Tong Tracy Feb 23 '17 at 06:32
1

First, Android does not have a CROP Intent. There are many image cropping libraries available for Android. Use one.

Second, the first parameter to grantUriPermissions() is not an action string or some random series of characters. It is an application ID (a.k.a., package name). com.android.camera.action.CROP is not a package name.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • wrong...Android has default Croping intent which can be accessed through the it's application ID (a.k.a package name),thus it is fair enough to assume android can handle the intent within given package name and handler Class for that intent,second the grant uri permission requires String which means that i must grant the URI permission and URI can be series of characters . – fasf safsaf Dec 08 '16 at 14:17
  • 1
    @fasfsafsaf: "Android has default Croping intent" -- [no, it does not](https://commonsware.com/blog/2013/01/23/no-android-does-not-have-crop-intent.html). – CommonsWare Dec 08 '16 at 14:21
  • Following the advice to use a third party image cropping library cost me about 4 hours, only to find out that none of them correctly handles Uri using the FileProvider either. I've never had problems using `com.android.camera.action.CROP`, so I feel your warnings against it may be exaggerated. Tong Tracy's answer does work. – wvdz Jun 19 '17 at 00:55
  • @wvdz: "only to find out that none of them correctly handles Uri using the FileProvider either" -- you would not need that `Uri` for a library in your own project. Hand them the `File`. `FileProvider` is for giving access to data *to other apps*, not to a library in your own app. "I feel your warnings against it may be exaggerated" -- feel free to point everybody to the official documentation for this undocumented `Intent` action. – CommonsWare Jun 19 '17 at 11:12
  • @CommonsWare: I guess that's a good point. So I should simply pass the file path between the activities instead of a Uri? Still, all the libraries I looked at use Uri to communicate files, e.g. https://github.com/ArthurHub/Android-Image-Cropper, https://github.com/Yalantis/uCrop, and use `Uri.fromFile()`. – wvdz Jun 20 '17 at 09:27
-1

you should add this sentence: grantUriPermission(); like

this:grantUriPermission("com.google.android.apps.photos",cropedImageUri,Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

My error is like to u.I solve it by this.

M. Wiśnicki
  • 6,094
  • 3
  • 23
  • 28
张松波
  • 11
  • 1