Sharing Bitmap via Android Intent
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);}
As CommonsWare stated you need to get the URI to the bitmap and pass that as your Extra.
String bitmapPath = Images.Media.insertImage(getContentResolver(), bitmap,"title", null);Uri bitmapUri = Uri.parse(bitmapPath);...intent.putExtra(Intent.EXTRA_STREAM, bitmapUri );
** finally i got the solution.**
Step 1 :Share Intent handling Block. This will Pop Up your window with list of Applications in you phone
public void share_bitMap_to_Apps() { Intent i = new Intent(Intent.ACTION_SEND); i.setType("image/*"); ByteArrayOutputStream stream = new ByteArrayOutputStream(); /*compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bytes = stream.toByteArray();*/ i.putExtra(Intent.EXTRA_STREAM, getImageUri(mContext, getBitmapFromView(relative_me_other))); try { startActivity(Intent.createChooser(i, "My Profile ...")); } catch (android.content.ActivityNotFoundException ex) { ex.printStackTrace(); }}
Step 2 :Converting your view to BItmap
public static Bitmap getBitmapFromView(View view) { //Define a bitmap with the same size as the view Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); //Bind a canvas to it Canvas canvas = new Canvas(returnedBitmap); //Get the view's background Drawable bgDrawable = view.getBackground(); if (bgDrawable != null) //has background drawable, then draw it on the canvas bgDrawable.draw(canvas); else //does not have background drawable, then draw white background on the canvas canvas.drawColor(Color.WHITE); // draw the view on the canvas view.draw(canvas); //return the bitmap return returnedBitmap;}
Step 3 :
To get The URI from Bitmap Image
public Uri getImageUri(Context inContext, Bitmap inImage) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes); String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); return Uri.parse(path);}