Activity return a image

2019-03-16 04:12发布

问题:

I want to return a bitmap in my activity, so other applications can use it.

Returning a text is clear.

Intent data = new Intent();
data.putExtra("text1", "text.");
data.putExtra("text2", "longer text.");
setResult(RESULT_OK, data);

But how to return a bitmap?

More Information: The activity has several intents to be available for everyone who wants to get a image.

<intent-filter>
    <action android:name="android.intent.action.GET_CONTENT" />
    <category android:name="android.intent.category.OPENABLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="image/*" />
    <data android:mimeType="vnd.android.cursor.dir/image" />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.PICK" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="image/*" />
    <data android:mimeType="vnd.android.cursor.dir/image" />
</intent-filter>

EDIT: Here is the solution in one function:

public void finish(Bitmap bitmap) {
    try {
        File folder = new File(Environment.getExternalStorageDirectory() + "/Icon Select/");
        if(!folder.exists()) {
            folder.mkdirs();
        }
        File nomediaFile = new File(folder, ".nomedia");
        if(!nomediaFile.exists()) {
            nomediaFile.createNewFile();
        }

        FileOutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/Icon Select/latest.png");
        bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
        File bitmapFile = new File(Environment.getExternalStorageDirectory() + "/Icon Select/latest.png");

        if(bitmapFile.exists()) {
            Intent localIntent = new Intent().setData(Uri.fromFile(bitmapFile));
            setResult(RESULT_OK, localIntent);                
        } else {
            setResult(RESULT_CANCELED);
        }
        super.finish();

    } catch (Exception e) {
        e.printStackTrace();
        Log.d("beewhale", "Error writing data");
    }
}

回答1:

While I agree with Ovidiu Latcu, you may run into memory issues.

It may be better to store the Bitmap to a temp location on the SD Card. And then access it from there. (Write and Read the Bitmap to file).

Alternatively, if you do want to go with putting a byte array as an extra, Compress the bitmap to another format first, e.g. Jpeg or similar, this again will reduce changes of memory issues.

A simple 8M pixel image, is 32MB (4 layers). And this exceeds the allowed memory usage on most (if not all) phones for an application.

Storing straight to the Storage is how the built in camera app works to avoid this problem.

Here is my code for dealing with it:

public void showCameraScreen(View view) {
    // BUILT IN CAMERA 
    Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);   
    camera.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(getTempFile(this)) );   
    this.startActivityForResult(camera, 1);

}   

private File getTempFile(Context context) {
    // it will return /sdcard/MyImage.tmp
    final File path = new File(Environment.getExternalStorageDirectory(), context.getPackageName());
    if (!path.exists()) {
        path.mkdir();
    }
    return new File(path, "MyImage.tmp");
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1 && resultCode == RESULT_OK) {
        final File file = getTempFile(this);

        byte[] _data = new byte[(int) file.length()];
        try {
            InputStream in = new FileInputStream(file);
            in.read(_data);
            in.close();
            in = null;
            //DO WHAT YOU WANT WITH _data. The byte array of your image.
        } catch (Exception E) {

        }
    }
}  

Note: You would also need to write code on your called intent, that stores to the passed Uri - Here, the built in camera api does it.



回答2:

You could use the putExtra(key,byte[]) and pass the bytes of your Bitmap and then in your onActivityResult use BitmapFactory.decodeByteArray() to create the Bitmap.

EDIT: You could also return an Uri to your resource/picture.