Android Share Intent for a Bitmap - is it possible not to save it prior sharing?
I had this same problem. I didn't want to have to ask for the read and write external storage permissions. Also, sometimes there are problems when phones don't have SD cards or the cards get unmounted.
The following method uses a ContentProvider called FileProvider. Technically, you are still saving the bitmap (in internal storage) prior to sharing, but you don't need to request any permissions. Also, every time you share the bitmap the image file gets overwritten. And since it is in the internal cache, it will be deleted when the user uninstalls the app. So in my opinion, it is just as good as not saving the image. This method is also more secure than saving it to external storage.
The documentation is pretty good (see the Further Reading below), but some parts are a little tricky. Here is a summary that worked for me.
Set up the FileProvider in the Manifest
<manifest>
...
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
...
</application>
</manifest>
Replace com.example.myapp
with your app package name.
Create res/xml/filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="shared_images" path="images/"/>
</paths>
This tells the FileProvider where to get the files to share (using the cache directory in this case).
Save the image to internal storage
// save bitmap to cache directory
try {
File cachePath = new File(context.getCacheDir(), "images");
cachePath.mkdirs(); // don't forget to make the directory
FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); // overwrites this image every time
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
Share the image
File imagePath = new File(context.getCacheDir(), "images");
File newFile = new File(imagePath, "image.png");
Uri contentUri = FileProvider.getUriForFile(context, "com.example.myapp.fileprovider", newFile);
if (contentUri != null) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
shareIntent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
startActivity(Intent.createChooser(shareIntent, "Choose an app"));
}
Further reading
- FileProvider
- Storage Options - Internal Storage
- Sharing Files
- Saving Files
Android: Share Bitmap Not Saved To SD
What I eneded up doing was saving one "Temp" image to the SD/Phone and just overwrite the each time.
android share image in ImageView without saving in sd card
You could also share it as the Media Gallery content provider URI (if the image is already on the phone, or if it came from the web you could share the URL (although it's not the same effect).
But if came from the web and you directly decoded to Bitmap and now want to share it as a proper image, yeah, you really need the file!
how to share a image bitmap with intent in android?
My problem was solved with a small change in my code:
Uri bitmapUri = Uri.parse (new File (path + fileName) .toString ());
Full code :
InputStream is = getAssets().open(imageName.getText().toString());
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
String path = Environment.getExternalStorageDirectory()+"/" + APP_NAME()+"/pictures/"+ls+"/" ;
new File(path).mkdirs();
String fileName = System.currentTimeMillis() + imageName.getText().toString().replace("pic/" , "");
FileOutputStream fileOutputStream = new FileOutputStream(new File(path+fileName));
fileOutputStream.write(buffer);
fileOutputStream.close();
//InputStream inputStream = new FileInputStream(new File(path+fileName));
//String bitmapPath = MediaStore.Images.Media.insertImage(getContentResolver(),b(inputStream) ,"title", null); // comment this line
Uri bitmapUri = Uri.parse(new File(path+fileName).toString()); //changed
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM , bitmapUri);
startActivity(intent);
if (new File(path+fileName).exists()){
new File(path+fileName).delete();
}
Sharing bitmap through intent doesn't clear previous bitmap
Finally I got my answer.
I was making changes in the layout and sharing the bitmap of that layout through intent. This process i was doing again and again without using following two things.
qrCodeFrame.invalidate();
qrCodeFrame.requestLayout();
so unfortunately i was making the bitmap of previous layout not of refreshed layout.
Related Topics
Drag and Drop Items in Recyclerview with Gridlayoutmanager
Android: Why Is There No Maxheight for a View
Android Studio 3.0 Execution Failed for Task: Unable to Merge Dex
Overlay Images Onto Camera Preview Surfaceview
Jar Mismatch! Fix Your Dependencies
Sending Intent to Broadcastreceiver from Adb
Any Way to Link to the Android Notification Settings for My App
Programmatically Connect to Paired Bluetooth Device
Android Contacts Display Name and Phone Number(S) in Single Database Query
How to Set "Android:Layout_Below" at Runtime Programmatically
Spannablestringbuilder to Create String with Multiple Fonts/Text Sizes etc Example
Findclass from Any Thread in Android Jni
Android N Requires the Ide to Be Running with Java 1.8 or Later
How to Know When the Recyclerview Has Finished Laying Down the Items