I'm creating an Android app where the user can select one of several images to share (which are stored in the drawable
folder) and the app opens up a standard ACTION_SEND chooser to allow them to share it to any app that supports PNGs, like so:
Uri imageUri = Uri.parse("android.resource://com.owlswipe.imagesharer/" + getImage());
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
sendIntent.setType("image/png");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(sendIntent, "share to an app"));
public int getImage() {
return R.drawable.firstimage;
}
However, if the user selects to share it to Whatsapp, it doesn't work properly: instead of interpreting it as an image (like if you normally share a photo to Whatsapp) it thinks it's a document called "Untitled" and does not show as an image.
Opening this Untitled document on a computer reveals it's called DOC-20180721-WA0012.
with no file extension! Manually adding a png
to the end of the filename reveals the correct image.
Making this weirder (but definitely solvable somehow!):
If the user chooses to open the image in an SMS app, for example, the image appears normally.
This has happened with multiple devices (Pixel 2 on P beta and Nokia 2 on 7.1.1)
This issue does not happen with other apps, where PNGs can be sent via Whatsapp like a normal image (though they do seem to be automatically converted to JPEGs by Whatsapp).
What can I do to make sure Whatsapp sees my image as a proper PNG file? Alternatively, how do I properly share a pre-loaded image from my app such that every app can interpret it correctly?
I solved this by properly implementing a FileProvider! This guide helped me so much , but I'll give a brief summary here.
Within the application
tag of your Manifest, start declaring your new FileProvider like so:
<provider
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="${applicationId}">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths"/>
</provider>
Then, create a new directory called xml
(control-click on your res
in Android Studio and go to New > Directory). Then, create a new file within xml
called file_provider_paths
(control-click on the new xml
directory, and go to New > File, and name it file_provider_paths.xml
). Add this code to that new xml file:
<paths>
<cache-path name="cache" path="/" />
<files-path name="files" path="/" />
</paths>
Finally, use it in your MainActivity or wherever like so:
// create new Intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
// set flag to give temporary permission to external app to use your FileProvider
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// generate URI, I defined authority as the application ID in the Manifest, the last param is file I want to open
Uri uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, imageFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);
// Set type to only show apps that can open your PNG file
intent.setType("image/png");
// start activity!
startActivity(Intent.createChooser(intent, "send"));
To get that imageFile
from an image in my drawable
directory, I first converted it to a Bitmap, and then onto a File object, like so:
// create file from drawable image
Bitmap bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.yourbeautifulimage);
File filesDir = getApplicationContext().getFilesDir();
File imageFile = new File(filesDir, "ABeautifulFilename.png");
OutputStream os;
try {
os = new FileOutputStream(imageFile);
bm.compress(Bitmap.CompressFormat.PNG, 100, os); // 100% quality
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
And you're done, every app can see your shared image now!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.