2

I'm building a Chooser app that replaces the native Android Share dialog. It works fine except when I try to share an image from Chrome via longpress image > share image.

If I try to do: Focus Gallery (by Franco) > Share (My App) > Google+ > No problem. Chrome > Share (My App) > Crash.

As soon as I try to access the content:// uri that is passed to my app as the EXTRA_STREAM, I get an error:

java.lang.SecurityException: Permission Denial: opening provider org.chromium.chrome.browser.util.ChromeFileProvider from ProcessRecord{9a9ad72 13494:com.rejh.sharedr/u0a226} (pid=13494, uid=10226) that is not exported from UID 10101

The content uri looks like this:

content://com.android.chrome.FileProvider/images/screenshot/15307085865714015389178311011200.jpg

Here's what I do (simplified):

@override 
public void onCreate() {
    handleIntent();

@override 
public void onNewIntent() {
    handleIntent();
}

public void handleIntent() {
    Parcelable parcel = getIntent().getParcelableExtra(Intent.EXTRA_INTENT);
    payloadIntent = new Intent((Intent) parcel);

    Uri extraStreamUri = (Uri) payloadIntent.getExtras().get(Intent.EXTRA_STREAM);
    ContentResolver contentResolver = getContentResolver();
    String fileMimeType = contentResolver.getType(extraStreamUri);
    Cursor returnCursor = contentResolver.query(extraStreamUri, null, null, null, null);
}

I get the error on the last line (contentResolver.query()). Weirdly enough, getType() does work.

Manifest declaration of the activity:

<activity
    android:name=".ActShareReplace"
    android:label="Sharedr"
    android:theme="@style/AppTheme.TransparentActivity"
    >
    <intent-filter>
        <action android:name="android.intent.action.CHOOSER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

As far as I can tell I should still have access to the URI since I try to access it from the same activity that receives the intent.

Btw, Chrome is the only app I've been having problems with so far. A user did report that sharing an image from Whatsapp resulted in similar error(s).

REJH
  • 3,273
  • 5
  • 31
  • 56
  • Btw, I'm trying to read the image so I can cache it, then forward it to the next app (Sharedr is a Share Dialog replacement, so it should just forward the intent). I did try simply forwarding the intent at first but then the URI permission is destroyed (because my component, who holds the permission, is no longer alive). – REJH Jul 04 '18 at 13:16
  • "I'm trying to read the image so I can cache it" -- you do not need `query()` for that. I agree that your symptoms are odd, but there is no requirement in an `EXTRA_STREAM` scenario that the `Uri` support `query()` (e.g., for the `OpenableColumns`). – CommonsWare Jul 04 '18 at 13:21
  • 1
    @REJ Try to add this flag, `payloadIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file` – Khaled Lela Jul 04 '18 at 13:25
  • @commonsware: I want to use the image name to cache the file. I get the same error if I try openInputStream (but it doesn't reach that line because it crashes on the query ()) – REJH Jul 04 '18 at 13:25
  • @KhaledLela doesn't work. And doesn't that require `android:grantUriPermission=true` in the manifest? – REJH Jul 04 '18 at 13:36
  • "I want to use the image name to cache the file" -- there is no requirement for the `Uri` that you get to support `query()` and the `OpenableColumns`. For example, it could be served by `FileProvider`. "I get the same error if I try openInputStream" -- I haven't tried implementing a replacement chooser, and the fact that you get the `Intent` via `EXTRA_INTENT` suggests that normal `Uri` permissions will not work. The point behind a chooser is to route an `Intent`; my guess is that what you are doing is beyond what choosers are capable of doing. – CommonsWare Jul 04 '18 at 14:11
  • @CommonsWare "my guess is that what you are doing is beyond what choosers are capable of doing" -- hmm Android System gets it done. That said, maybe it's because it's a system app? I'll try debugging the full intent object I get, maybe it holds an answer. Thanks so far :) – REJH Jul 04 '18 at 14:31
  • "hmm Android System gets it done" -- I don't see where the built-in chooser is attempting to read in the content. I would be stunned if it did so. – CommonsWare Jul 04 '18 at 15:14
  • @CommonsWare Oh that's what I mean. It gets it done *without* caching the result, it just magically grants the receiving activity the permission to the URI. I've been looking into the AOSP code of [ResolverActivity](https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/com/android/internal/app/ResolverActivity.java) and I can't find where/how it does that (thus "magically" :)). As far as I know it's not using `FLAG_GRANT_READ_URI_PERMISSION` or anything like it..? – REJH Jul 04 '18 at 15:43
  • Ok, to clarify; I tried forwarding the `payloadIntent` to whatever target the user chose. That didn't work (in the case sharing an image from Chrome, I get `UID 10130 does not have permission to content://...`). Then I googled, SO'ed and even read the AOSP code and finally figured maybe I need to cache the image so I could set the URI permission myself. So that's where I'm at right now. – REJH Jul 04 '18 at 15:48
  • After thinking this thing over I've decided I probably shouldn't have to cache the file. I've posted a new question that starts at the root of the problem: [Custom chooser activity: SecurityException UID n does not have permission to content:// uri](https://stackoverflow.com/questions/51179904/custom-chooser-activity-securityexception-uid-n-does-not-have-permission-to-con) – REJH Jul 04 '18 at 19:32

0 Answers0