I am trying to create a share button that will share an Image with some extra caption text to social media.
The code I’m using now works fine with some apps, but doesn’t work in other apps.
Here’s the code:
String message = "hello world";
Uri uri = Uri.parse("android.resource://" + getActivity().getPackageName() + "/" + R.raw.loremipsum2);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, message);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/jpeg");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
I’ve been searching for hours what the problem may be, but none of the solutions have worked for me so far.
Apps where it does work:
-Telegram
-Drive
Apps where it doesn’t work:
-Gmail
Error when sharing to Gmail:
Gmail:Can't find android resource
java.io.FileNotFoundException: No package found for authority: android.resource://com.test.testApp/2131820547
Error when sharing to whatsapp
Access denied finding property "ro.vendor.scroll.preobtain.enable"
I’m going crazy onto this one, I need it to work and can obviously be achieved, as many apps can share images to whatsapp.
Any ideas on how to solve it? you’re welcome! 🙂
2
Answers
Okay, so finally, after researching a lot, trust me, a lot, I've finally found an answer to my question, so I'm posting it here as it seems like a pretty basic feature to have in an app.
The solution is, as CommonsWare said, using a fileProvider. I also used a class I found on github to manage cache usage , it is linked here, as
FileProvider
may not use resource URIsThe idea is, store the image in cache, then call
Cache
class to provide a valid URI to the image in cache, and then use that URI for theEXTRA_STREAM
Follow this guide to solve the issue: (it works in all apps I've tried so far. It should also work for other File types with some little modifications.)
SOLUTION
1-Create the class that handles cache. Here's code:
I've done little to none modification to this class, the author is Ivan V on 12.05.2019. (Github)
This class uses a
FileProvider
internally.FileProvider
will allow other apps to access our app files. To configure file providers, we have to do some modification inAndroidManifest.xml
2 - Inside the
<application>
tag, place the followingFileProvider
config:And create
file_paths.xml
in/res/xml
(if the xml folder doesn't exist, create it to) with the following code:3 - Create the sharing method in your activity
Just change all image names etc and you are ready to go!! I hope i was helpful :)
EXTRA_STREAM
is documented to take acontent:
Uri
. That is not what you are using. Few developers know of theandroid.resource
scheme. Fewer still will have code that handles it when an app uses one unexpectedly inEXTRA_STREAM
.For better compatibility, use a
ContentProvider
and acontent:
Uri
that points to it. For example, you could share a file withFileProvider
.