Using data from context providers or requesting Google Photos read permission?
Asked Answered
H

6

24

My app allows users to import their photos and videos from other apps. Now that Google replaced Google+ Photos with Google Photos, couple of things broke for me. One of these things is re-using imported files after app restart. I have a feeling they've tightened up the permissions given out when Google Photos returns the intent with the image URI, so after my app gets killed it no longer has the permission to access the uploaded file. I'm getting the Security expection:

java.lang.SecurityException: Permission Denial: opening provider com.google.android.apps.photos.contentprovider.MediaContentProvider from ProcessRecord{2c17ab9e 2124:com.myapp.myapp/u0a436} (pid=2124, uid=10436) that is not exported from uid 10427

EDIT:

I'm also getting the same problem with reusing files provided by com.google.android.apps.docs.sync.filemanager.FileProvider

Any suggestions/workaround? I know I can read the file before I lost permission so in theory I could copy it but I can't say I like this very much..

Hin answered 1/6, 2015 at 11:24 Comment(0)
S
29

Yep, this is by design, as described on Android Developer site.

For security reasons, the permissions are temporary, so once the client app's task stack is finished, the file is no longer accessible. You must get the file data when you receive the intent answer, in the onActivityResult method. Store a copy of the file data, because the file won't be available anymore when onActivityResult returns.

Stupe answered 7/7, 2015 at 16:43 Comment(6)
This was my conclusion as well so I'll choose your answer as the answer. ThanksHin
It looks like antipattern. Make a copy of the file in main thread?Royer
@Royer You have access from any thread for as long as your activity that was targeted by the intent isn't stoppedHackle
i had a similar issue and i was able to fix it by using ACTION_OPEN_DOCUMENT instead of ACTION_PICK. i believe ACTION_OPEN_DOCUMENT grants persisting permission and is not as strict as ACTION_PICK. When i was using ACTION_PICK, i lost permission when i got the URI in one activity and went to a different activity to display the image, Just as the developer docs say.Willful
@Willful thanks, your answer should be the accepted answer.Floriculture
@Willful Still applicable, thank you. However, the issue remains that the permissions are lost on reboot.Cochard
M
13
  1. You can reproduce this SecurityException Log when you use the "Google Photo" app.

  2. Main cause of this problem is "Google Photo" shares ContentUri with fixed string like "content://com.google.android.apps.photos.contentprovider/1/1" and connect it with a static temporary values. "Google Photo" does not provide the file path when the actual Activity or Context which receives Intent.ACTION_SEND. Maybe, it is the policy of "Google Photo", not to expose the private image file to other app.

  3. For example, you defines 2 Activity in Manifest file, Actvity A and Activity B. Activity A for receives the Intent.ACTION_SEND. Activity B for processing the image file. Activity A forward the intent to Activity B. Then Activity B is not the correct Activity to "Google Photo", you encounters the SecurityException.

So, I recommend you to save the file temporarily on Activity A and use the temporary file path on Activity B

Melancon answered 18/6, 2015 at 7:30 Comment(2)
thank you ! i think your answer is right to my issue.Grantee
I have the same problem, Google photos causes a load of issues :-/Fattish
W
3

maybe you can try adding this user-permission into your manifest file.

<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
Wyly answered 2/6, 2015 at 20:17 Comment(2)
can you use the inputstream to access the file ? like "context.getContentResolver().openInputStream(uri);" ?Wyly
that's exactly what I'm doing when getting the permission errorHin
P
2

Looks like this question is simular

I think when activity (not fragment) dies - all retrieved by it URI become invalidated

I also have the same problem - trying to upload picture in background. But user in UI thread may change activity and URI becomes invalid

Phenosafranine answered 3/6, 2015 at 22:46 Comment(1)
Yes it does look similar, but I think the permission changed for the new Photos app content provider as I have a feeling I tried that permission before with no luck. I ended up copying files into my territory and registering them in my content provider to retain access. Let me know if you find a better solution!Hin
Y
1

You need to set permissions explicitly to all packages match your intent. It happens in Android 4.4 usually.

you can use this utility to do that :

List<ResolveInfo> resInfoList = getContext().getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            getContext().grantUriPermission(packageName, imageFileUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
Youlandayoulton answered 12/1, 2017 at 18:48 Comment(0)
S
0

I have same issue with this, and you and try the follow work around methods:

  1. Android 5.1.1 lollipop return null file path if image chosen from gallery

  2. https://gist.github.com/alexzaitsev/75c9b36dfcffd545c676

  3. Choosing photo using new Google Photos app is broken

Superinduce answered 9/6, 2015 at 15:59 Comment(2)
My problem is not the initial get call - it's the permission retention. After getting access to the file, the access is revoked if the app is suspended or the user moves away from the appHin
Please include the answer here, rather than just links. See meta.stackexchange.com/questions/8231/…Abiogenetic

© 2022 - 2024 — McMap. All rights reserved.