0

SLOVED

Sending the intent like

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

In the onActivityResult method

imageUri = data.getData();
    getContentResolver().takePersistableUriPermission(imageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

I have found that this is a common issue. I am getting a java.lang.SecurityException: Permission Denial: error when trying to userImg.setImageURI(tmp.photo); in my code. I have tried many solutions found on SO but nothing. I also tried using glide but no luck there. The uri is read into an object, which I store in memory on runtime, and I request it with tmp.photo. I checked with logging that the Uri is passed successfully into the photo attribute. What can I do?

these are into my manifest.

<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

My code is very simple.

ImageView userImg = (ImageView) findViewById(R.id.userImg);
userImg.setImageURI(tmp.photo);

wheretmp.photo is a Uri object. This generates all of these

Unable to open content: content://com.android.providers.media.documents/document/image%3A156
java.lang.SecurityException: Permission Denial: 
opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord
{74dbab7 13175:com.example.gus.uniman/u0a168} (pid=13175, uid=10168) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
at android.os.Parcel.readException(Parcel.java:1684)
at android.os.Parcel.readException(Parcel.java:1637)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4199)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:5478)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2239)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1517)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1131)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:984)
at android.content.ContentResolver.openInputStream(ContentResolver.java:704)
at android.widget.ImageView.getDrawableFromUri(ImageView.java:900)
at android.widget.ImageView.resolveUri(ImageView.java:871)
at android.widget.ImageView.setImageURI(ImageView.java:490)
at com.example.gus.uniman.PersonDetails.onCreate(PersonDetails.java:78)
at android.app.Activity.performCreate(Activity.java:6682)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2619)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2727)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1478)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
06-07 19:24:36.919 13175-13175/com.example.gus.uniman W/ImageView: resolveUri failed on bad bitmap uri: content://com.android.providers.media.documents/document/image%3A156
06-07 19:24:37.030 13175-13207/com.example.gus.uniman D/OpenGLRenderer: endAllActiveAnimators on 0x76706ab800 (ListView) with handle 0x768d4df4a0
Kostas Andrianos
  • 1,551
  • 2
  • 16
  • 21
  • which android version/api that happend? Nougat? – Max Pinto Jun 07 '17 at 16:37
  • API 25, running on a Nexus 6P that has 7.1.2 with June patches. – Kostas Andrianos Jun 07 '17 at 16:37
  • you has to request runtime permissions – tyczj Jun 07 '17 at 16:40
  • Are you requesting runtime user permissions? – Max Pinto Jun 07 '17 at 16:40
  • No, I just found an article on how to do that, but my problem is, where I go to the app under settings/apps/myApp/permissions, I don't see anything. I understand that somehow I need to present the user with the "Do you want to grant this permission message", but shouldn't it be visible in the settings too? My issue is probably very noobish. – Kostas Andrianos Jun 07 '17 at 16:42
  • You cannot hold the `MANAGE_DOCUMENTS` permission, so if your error is related to that, you need to provide a [mcve] (full Java stack trace and the code that generates it). For `READ_EXTERNAL_STORAGE`, [use runtime permissions](https://stackoverflow.com/questions/32635704/android-permission-doesnt-work-even-if-i-have-declared-it). – CommonsWare Jun 07 '17 at 16:46
  • I updated my question. @CommonsWare – Kostas Andrianos Jun 07 '17 at 16:54

1 Answers1

1

You only have rights to the content identified by the Uri:

  • In your original component (e.g., the activity that got the Uri via onActivityResult() of ACTION_GET_CONTENT), or

  • In any components that you pass the Uri to, if you include FLAG_GRANT_READ_URI_PERMISSION in the Intent used to start that component, and

  • Only while your process is around

In your case, somewhere along the line, you violated those rules. Perhaps you passed the Uri to another component without FLAG_GRANT_READ_URI_PERMISSION, or perhaps you saved the Uri to disk and attempted to use it again later.

See this blog post for more about Uri access lifetime.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Oh I see. Since I need those data to be stored in a database, I thought it would be better to just save a link to them. What should I do instead? – Kostas Andrianos Jun 07 '17 at 17:10
  • @Dinos_12345: If you are getting the `Uri` via `ACTION_OPEN_DOCUMENT` or other facets of the Storage Access Framework, you can try `takePersistableUriPermissions()` on `ContentResolver` to have longer-term access to the content. However, bear in mind that the user might move or delete that content "behind your back". If you are getting the `Uri` by any other means, you will need to import the content into your app, copying it to some file that you control. – CommonsWare Jun 07 '17 at 17:12
  • @Dinos_12345: The simplest way to think of these `Uri` values is that they are akin to URLs to a Web server/Web service, but ones that require an authenticated user session. While you could save the URL somewhere, you may not be able to use it tomorrow, as the user's session may have timed out. – CommonsWare Jun 07 '17 at 17:13
  • I actually read the whole thing you linked me to, thank you for that. I am still learning, so this was very informative for a noob like me. :) – Kostas Andrianos Jun 07 '17 at 17:15