2

I have an activity which accepts android.intent.action.SEND.
It accepts some media files and texts.
As it accepts a new 'share' it does some validation checks and pass the Uri to a service, it looks like this:

Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
Intent serviceIntent = new Intent(this, ShareService.class)
        .setData(uri)
        .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // probably redundant but harmless here       
        .putParcelableArrayListExtra(Constants.EXTRA_SHARE_FILES, uris)
startService(serviceIntent);

It works for all file providers and usually for content as well, but from time to time I get reports of failures:

Non-fatal Exception: java.lang.SecurityException: UID 10283 does not have permission to content://com.whatsapp.provider.media/item/33560 [user 0]

Is there anything I can do to keep the Uri permission alive? how should I handle this kind of Uri?

SagiLow
  • 5,721
  • 9
  • 60
  • 115
  • `probably redundant but harmless here` -- actually, it is essential. Beyond that, what is `uris`? – CommonsWare May 01 '19 at 18:18
  • Correct, I actually added the comment when writing the question and I was wrong. Since multiple files share are also handled by the same service, I set `uris` as `ArrayList uris = new ArrayList<>(1); uris.add(uri);` and on the receiving service I use them: `ArrayList attachments = intent.getParcelableArrayListExtra(Constants.EXTRA_SHARE_FILES);` – SagiLow May 01 '19 at 19:10
  • AFAIK, `Uri` values in arbitrary extras are not covered by `FLAG_GRANT_READ_URI_PERMISSION`. That covers the `data` facet of the `Uri`, and covers certain extras on certain actions (kinda hard-coded in the framework). – CommonsWare May 01 '19 at 19:18
  • The `Uri` in the extras is the same as in the `data`, it's just easier to pass and parse. It's in production and actually works for thousands of `Uri`'s but here and there I see a similar error message – SagiLow May 01 '19 at 19:21
  • Oh, sorry, I misinterpreted your previous comment. Is there a scenario where your activity might have finished before the service starts, perhaps? I don't know how the permission grant works in that sort of edge case. – CommonsWare May 01 '19 at 19:23
  • The activity just starts the service and finishes itself. I'm not exactly sure how exactly `startService()` works and if it's sync/async call so I can't really answer. I can only assume it's async and it's a race condition but even in this case, when looking over 'big numbers' it works 99.999% of the times – SagiLow May 01 '19 at 19:28
  • `startService()` is definitely async. You might want to see if you can rig up a way to keep the activity around until the service has started and the `Uri` handoff is complete. Also, going back to my earlier comment... "Since multiple files share are also handled by the same service" -- how do you know that the problem is coming from *this* `startService()` call and not the multiple-files one? – CommonsWare May 01 '19 at 19:31
  • These are 2 separate methods and the exception is coming from the method handling the single file (from within the `startService()` call), I wasn't actually able to reproduce this, I've tried sharing file and get `content` Uri but I get only `file`, any idea which app I can use to send `content` Uri? – SagiLow May 01 '19 at 19:34
  • Anything on Android 7.0+ should be using `content` `Uri` values. Personally, I'd toss together a scrap app that had `FileProvider` and initiated the `ACTION_SEND`, just so I control both sides of the communications. – CommonsWare May 01 '19 at 19:37
  • Sounds good, I'll give it a shot and report back. thanks – SagiLow May 01 '19 at 19:40
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/192684/discussion-between-sagilow-and-commonsware). – SagiLow May 01 '19 at 20:00
  • Sorry, since I offer chats as part of my Warescription, I don't do Stack Overflow chats, as that would be weird. – CommonsWare May 01 '19 at 20:04
  • That's perfectly fine. Anyway, I wasn't able to reproduce it. I've changed the activity to do `moveTaskToBack` instead of `finish()`, let's see how that goes – SagiLow May 01 '19 at 20:11
  • @SagiLow have you figure out what the issue was? – squirrel Mar 26 '21 at 04:58

1 Answers1

-2

please create xml folder in your app and in xml mentioned file provider file and network security configure file after that declare fileprovider in AndroidMenifest.xml file