Home » Android » image – How to send large byte arrays between activities in Android?

image – How to send large byte arrays between activities in Android?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I need to send byte[] data from Activity1 to Activity2, in order to writedata("FileOutputStream.write(data)") in a jpg file. My final .jpg file could exceed 1mb.

Activity1:

public void onPictureTaken(byte[] data, Camera camera) {

    Log.w("ImageSizeMyApp", String.valueOf(data.length));

    mCamera.startPreview();
    Intent shareWindow = new Intent(Activity1.this, Activity2.class);
    shareWindow.putExtra("photo",data);
    startActivity(shareWindow);
    closeCamera();

    Log.w("CameraActivity:", "onPictureTaken");

}

In Activity2:

Bundle extras = getIntent().getExtras();
data = extras.getByteArray("photo");

I use Log.w("ImageSizeMyApp", String.valueOf(data.length)); to get this:

  1. ImageSizeMyApp﹕ 446367 (this size sends to the next activity, and everything is good)

  2. ImageSizeMyApp﹕ 577368 (this size closes my camera, and does not send to the next activity)

So 500kb is the limit dimension for Intent. Is there any other stable method to send my byte[] larger than 500kb between activities?

Any reference or advice is welcome. Thanks in advance!

Update:

Could I make another class to store that byte[] array? Or is it better to use a static variable?

How to&Answers:
  1. Create a temporary file.
  2. Pass the file path to the Other Activity.
  3. Get the path and load the image.

Activity 1 :

    //creates the temporary file and gets the path
String filePath= tempFileImage(context,yourBitmap,"name");



Intent intent = new Intent(context, Activity2.class);

//passes the file path string with the intent 
intent.putExtra("path", filePath);


startActivity(intent);

Use this method to create the file:

   //creates a temporary file and return the absolute file path
public static String tempFileImage(Context context, Bitmap bitmap, String name) {

    File outputDir = context.getCacheDir();
    File imageFile = new File(outputDir, name + ".jpg");

    OutputStream os;
    try {
        os = new FileOutputStream(imageFile);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
        os.flush();
        os.close();
    } catch (Exception e) {
        Log.e(context.getClass().getSimpleName(), "Error writing file", e);
    }

    return imageFile.getAbsolutePath();
}

Activity 2 :

//gets the file path
String filePath=getIntent().getStringExtra("path");

//loads the file
File file = new File(filePath);

Finally load the image:

Picasso.with(context).load(file).fit().centerCrop().into(imageView);

Or:

Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
imageView.setImageBitmap(bitmap);

Answer:

I had the same problem. In short: subclass the Application (or create a helper singleton), use it (<application android:name=".App" .../> in manifest.xml) and store the image data there.

App.java snippet:

public final class App extends Application {
    private static App sInstance;
    private byte[] mCapturedPhotoData;

    // Getters & Setters
    public byte[] getCapturedPhotoData() {
        return mCapturedPhotoData;
    }

    public void setCapturedPhotoData(byte[] capturedPhotoData) {
        mCapturedPhotoData = capturedPhotoData;
    }

    // Singleton code
    public static App getInstance() { return sInstance; }

    @Override
    public void onCreate() {
        super.onCreate();
        sInstance = this;
    }
}

Camera Activity saves the data:

private Camera.PictureCallback mJpegCaptureCallback = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        // We cannot pass the large buffer via intent's data. Use App instance.
        App.getInstance().setCapturedPhotoData(data);
        setResult(RESULT_OK, new Intent());
        finish();
    }
};

Parent Activity reads the data:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == RequestCode.CAPTURE && resultCode == RESULT_OK) {
        // Read the jpeg data
        byte[] jpegData = App.getInstance().getCapturedPhotoData();
        App.log("" + jpegData.length);

        // Do stuff

        // Don't forget to release it
        App.getInstance().setCapturedPhotoData(null);
    }
}

Answer:

Following are the steps:

1) Create table in sqlite with byte and id columns
2) Save this byte and his id (you will give) from Activity 1
3) Go to Activity 2 (do not forget to send parameter id)
4) In Activity 2 get this parameter from intent and query database using id to get you byte.

I hope this helps.