Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing Bitmap via Android Intent

In my android app, I have a bitmap (say b) and a button. Now when I click on the button, I want to share the bitmap. I am making use of the below code inside my onClick() to achieve this :-

Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("image/png"); intent.putExtra(Intent.EXTRA_STREAM, b); startActivity(Intent.createChooser(intent , "Share")); 

I was expecting a list of all application which are able to handle this intent but I get nothing. There is no list of apps nor is there any error in android studio. My application just get hanged for sometime and then quits.

I have checked the bitmap and it is fine (its not null).

Where am I a going wrong ?

like image 727
Jhilmil Chatterjee Avatar asked Oct 19 '15 20:10

Jhilmil Chatterjee


People also ask

How do I share a bitmap with intent?

setType("image/png"); intent. putExtra(Intent. EXTRA_STREAM, b); startActivity(Intent. createChooser(intent , "Share"));

How do I share a bitmap on Whatsapp Android?

setType("image/png"); waIntent. putExtra(Intent. ACTION_SEND, byteArray); startActivity(Intent. createChooser(waIntent, "Share with"));

How do I share photos with FileProvider on Android?

If you are using Recylerview Adapter to pass image in full to DetailActivity, this solution will help you share the image received in DetailActivity so that you can share with social media apps. Drawable drawable=imageView. getDrawable(); Bitmap bitmap=((BitmapDrawable)drawable).


1 Answers

I found 2 variants of the solution. Both involve saving Bitmap to storage, but the image will not appear in the gallery.

First variant:

Saving to external storage

  • but to private folder of the app.
  • for API <= 18 it requires permission, for newer it does not.

1. Setting permissions

Add into AndroidManifest.xml before tag

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/> 

2. Saving method:

 /**  * Saves the image as PNG to the app's private external storage folder.  * @param image Bitmap to save.  * @return Uri of the saved file or null  */ private Uri saveImageExternal(Bitmap image) {     //TODO - Should be processed in another thread     Uri uri = null;     try {         File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "to-share.png");         FileOutputStream stream = new FileOutputStream(file);         image.compress(Bitmap.CompressFormat.PNG, 90, stream);         stream.close();         uri = Uri.fromFile(file);     } catch (IOException e) {         Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());     }     return uri; } 

3. Checking storage accesibility

External storage might not be accessible, so you should check it before trying to save: https://developer.android.com/training/data-storage/files

/**  * Checks if the external storage is writable.  * @return true if storage is writable, false otherwise  */ public boolean isExternalStorageWritable() {     String state = Environment.getExternalStorageState();     if (Environment.MEDIA_MOUNTED.equals(state)) {         return true;     }     return false; } 

Second variant

Saving to cacheDir using FileProvider. It does not require any permissions.

1. Setup FileProvider in AndroidManifest.xml

<manifest>     ...     <application>         ...         <provider             android:name="android.support.v4.content.FileProvider"             android:authorities="com.mydomain.fileprovider"             android:exported="false"             android:grantUriPermissions="true">                 <meta-data                     android:name="android.support.FILE_PROVIDER_PATHS"                     android:resource="@xml/file_paths" />         </provider>         ...     </application> </manifest> 

2. Add path to the res/xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?> <resources>     <paths xmlns:android="http://schemas.android.com/apk/res/android">          <cache-path name="shared_images" path="images/"/>     </paths> </resources> 

3. Saving method:

 /**  * Saves the image as PNG to the app's cache directory.  * @param image Bitmap to save.  * @return Uri of the saved file or null  */ private Uri saveImage(Bitmap image) {     //TODO - Should be processed in another thread     File imagesFolder = new File(getCacheDir(), "images");     Uri uri = null;     try {         imagesFolder.mkdirs();         File file = new File(imagesFolder, "shared_image.png");          FileOutputStream stream = new FileOutputStream(file);         image.compress(Bitmap.CompressFormat.PNG, 90, stream);         stream.flush();         stream.close();         uri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", file);      } catch (IOException e) {         Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());     }     return uri; } 

More info about file provider - https://developer.android.com/reference/android/support/v4/content/FileProvider

Compressing and saving can be time-consuming, therefore this should be done in a different thread

Actual sharing

/**  * Shares the PNG image from Uri.  * @param uri Uri of image to share.  */ private void shareImageUri(Uri uri){     Intent intent = new Intent(android.content.Intent.ACTION_SEND);     intent.putExtra(Intent.EXTRA_STREAM, uri);     intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);     intent.setType("image/png");     startActivity(intent); } 
like image 145
kjs566 Avatar answered Sep 19 '22 00:09

kjs566