Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
243 views
in Technique[技术] by (71.8m points)

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 ?

question from:https://stackoverflow.com/questions/33222918/sharing-bitmap-via-android-intent

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...