I'm using 3 fragments to show in a tab layout, the next problem refers to one of those fragments.
I'm trying to pick single or multiple images in my app, I open the image picker using a button and the next code:
btn_galeria.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 10);
}
else {
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select picture"), PICK_IMAGE_MULTIPLE);
}
}
});
But as soon as the image picker opens, the app either has one of these outcomes:
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 2572096)
`the image picker shows up and the app keeps running, I'm able to select the images and the app work as expected.E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 6639520)
, but this time, even though the image picker shows up, the app crashes in the background with the next reason:2020-07-07 02:02:51.311 31240-31240/com.ssp.atencionvictimas E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ssp.atencionvictimas, PID: 31240
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 6639520 bytes
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:161)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Caused by: android.os.TransactionTooLargeException: data parcel size 6639520 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:526)
at android.app.IActivityTaskManager$Stub$Proxy.activityStopped(IActivityTaskManager.java:4561)
at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:145)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
2020-07-07 02:02:51.317 31240-31240/com.ssp.atencionvictimas I/Process: Sending signal. PID: 31240 SIG: 9
Basically what I'm trying to do is to let the user pick one or multiple images (if possible maximum 6) and show the selected images using a view adapter already made.
This is the code which executes after the user has selected the image or images:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Esta sección de código se ejecuta cuando se termina un Intent, y se regresa al Activity anterior
if(requestCode == 1 && resultCode == RESULT_OK) {
List<Bitmap> bitmaps = new ArrayList<>();
ClipData clipdata = data.getClipData();
ArrayList<Uri> mArrayUri = new ArrayList<>();
ArrayList<String> ListaUris = new ArrayList<>();
if(clipdata != null) {
for(int i=0; i<clipdata.getItemCount(); i++) {
Uri imageUri = clipdata.getItemAt(i).getUri();
mArrayUri.add(imageUri);
try {
InputStream is = getActivity().getApplicationContext().getContentResolver().openInputStream(imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
bitmaps.add(bitmap);
Log.v("LOG_TAG", "URI DE IMAGEN: " + imageUri);
// Will return "image:x*"
String wholeID = DocumentsContract.getDocumentId(imageUri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
ListaUris.add(filePath);
Log.v("LOG_TAG", "FILEPATH: " + filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
else {
Uri imageUri = data.getData();
mArrayUri.add(imageUri);
try {
InputStream is = getActivity().getApplicationContext().getContentResolver().openInputStream(imageUri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
bitmaps.add(bitmap);
Log.v("LOG_TAG", "URI DE IMAGEN: " + imageUri);
// Will return "image:x*"
String wholeID = DocumentsContract.getDocumentId(imageUri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = { MediaStore.Images.Media.DATA };
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column, sel, new String[]{ id }, null);
String filePath = "";
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
ListaUris.add(filePath);
Log.v("LOG_TAG", "FILEPATH: " + filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
galleryAdapter = new GalleryAdapter(getActivity().getApplicationContext(),mArrayUri);
gvGallery.setAdapter(galleryAdapter);
gvGallery.setVerticalSpacing(gvGallery.getHorizontalSpacing());
ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams) gvGallery
.getLayoutParams();
mlp.setMargins(0, gvGallery.getHorizontalSpacing(), 0, 0);
Log.v("LOG_TAG", "CANTIDAD DE FOTOS: " + ListaUris.size());
Log.v("LOG_TAG", "LISTA DE URIS: " + ListaUris);
}
}
But even if I comment out the previous code, same behaviour occurs, so I believe it has something to do with the way the intent returns or handles the gallery data.
I solved by adding the next method override on the fragment class:
@Override
public void onSaveInstanceState(Bundle outState) {
if (outState != null)
outState.clear();
}