Android 当图库中的 select 图片来自最近的图片时,应用程序崩溃

Android app getting crash when select image from Recent images from gallery

我的应用程序在 select image from PicturesGallery 中的图像类别时运行完美,但在 select image from recent images

时应用程序崩溃

这是我的意图

galleryLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (EasyPermissions.hasPermissions(getActivity(), perms_gallery)) {
                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"), SELECT_FILE);
            }else {
                EasyPermissions.requestPermissions(getActivity(), getString(R.string.read_file),
                        READ_REQUEST_CODE, perms_gallery);
            }
        }
    });

崩溃从这里开始String id = wholeID.split(":")[1];

public String getPathFromUriGallery(Context context, Uri uri) {
    Cursor cursor = null;
    try {
        String wholeID = DocumentsContract.getDocumentId(uri);
        String id = wholeID.split(":")[1];
        String sel = MediaStore.Images.Media._ID + "=?";

        String[] filePath = {MediaStore.Images.Media.DATA};
        cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, filePath, sel, new String[]{id}, null);
        cursor.moveToFirst();
        int columnIndex = cursor.getColumnIndex(filePath[0]);
        return  cursor.getString(columnIndex);
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

这是我的错误日志

Process: io.test.susitkMed.doctor, PID: 9576
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=Intent { dat=content://com.google.android.apps.docs.storage/document/acc=3;doc=encoded=0ajgvv25pDn5wcNiiiv1YFYu7neaIdrulcWk/kBdEa8TqupNEKLhnLzz flg=0x1 launchParam=MultiScreenLaunchParams { mDisplayId=0 mBaseDisplayId=0 mFlags=0 } }} to activity {io.test.susitkMed.doctor/io.test.susitkMed.doctor.ui.activities.MainActivity}: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4520)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4563)
    at android.app.ActivityThread.-wrap22(ActivityThread.java)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1698)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6776)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)
 Caused by: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1

改用这个方法..

public String getImagePathFromUri(Uri contentUri) {
            String res = null;
            String[] proj = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
            if (cursor.moveToFirst()) {
                int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                res = cursor.getString(column_index);
            }
            cursor.close();
            return res;
        }

我从这个 github 示例中找到了这个解决方案 https://github.com/maayyaannkk/ImagePicker

这是上述问题的解决方案

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

    if (requestCode == PICK_IMAGE && resultCode == RESULT_OK
            && null != data) {

        Uri selectedImage = data.getData();
        String   imageEncoded = getRealPathFromURI(getActivity(), selectedImageUri);
        Bitmap selectedImage = BitmapFactory.decodeFile(imageString);
        image.setImageBitmap(selectedImage);
    }
}

这些方法用于获取图像url

public String getRealPathFromURI(Context context, Uri contentUri) {
    OutputStream out;
    File file = new File(getFilename(context));

    try {
        if (file.createNewFile()) {
            InputStream iStream = context != null ? context.getContentResolver().openInputStream(contentUri) : context.getContentResolver().openInputStream(contentUri);
            byte[] inputData = getBytes(iStream);
            out = new FileOutputStream(file);
            out.write(inputData);
            out.close();
            return file.getAbsolutePath();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

private byte[] getBytes(InputStream inputStream) throws IOException {
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];

    int len = 0;
    while ((len = inputStream.read(buffer)) != -1) {
        byteBuffer.write(buffer, 0, len);
    }
    return byteBuffer.toByteArray();
}

private String getFilename(Context context) {
    File mediaStorageDir = new File(context.getExternalFilesDir(""), "patient_data");
    // Create the storage directory if it does not exist
    if (!mediaStorageDir.exists()) {
        mediaStorageDir.mkdirs();
    }

    String mImageName = "IMG_" + String.valueOf(System.currentTimeMillis()) + ".png";
    return mediaStorageDir.getAbsolutePath() + "/" + mImageName;

}

改用Document provider

例如:

Intent it = new Intent();
it.setAction(Intent.ACTION_GET_CONTENT);
it.setType("image/*");
startActivityForResult(it, 1000);

----------------------

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1000) {
        if (resultCode == Activity.RESULT_OK && data != null) {
            try {
                Bitmap bm = getBitmapFromUri(data.getData());
                iv.setImageBitmap(bm);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

private Bitmap getBitmapFromUri(Uri uri) throws IOException {
    ParcelFileDescriptor parcelFileDescriptor =
            getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
    Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    parcelFileDescriptor.close();
    return image;
}

当我 select 最近的图像然后图像在 android 中损坏 |来自最近

的多张图片

我在下面提到了我的答案link请去那里找到你的解决方案

You can find the full post from this link || Click link here

此外,您可以在这里找到

Sample preview

Call multiple images select

 Intent i = new Intent(Intent.ACTION_GET_CONTENT);
                        i.addCategory(Intent.CATEGORY_OPENABLE);
                        i.setType("image/*");
                        i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                        *gallery*.launch(i);

gallery basically startActivityForResult(i,123) and OnActivityResult method is deprecated, the gallery is alternative which is defined below

ActivityResultLauncher<Intent> gallery = choosePhotoFromGallery();

choosePhotoFromGallery()是下面定义的方法

private ActivityResultLauncher<Intent> choosePhotoFromGallery() {
    return registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            result -> {
                try {
                    if (result.getResultCode() == RESULT_OK) {
                        if (null != result.getData()) {
                            if (result.getData().getClipData() != null) {
                                ClipData mClipData = result.getData().getClipData();
                                for (int i = 0; i < mClipData.getItemCount(); i++) {
                                    ClipData.Item item = mClipData.getItemAt(i);
                                    Uri uri = item.getUri();
                                    String imageFilePathColumn = getPathFromURI(this, uri);
                                    productImagesList.add(imageFilePathColumn);
                                }
                            } else {
                                if (result.getData().getData() != null) {
                                    Uri mImageUri = result.getData().getData();
                                    String imageFilePathColumn = getPathFromURI(this, mImageUri);
                                    productImagesList.add(imageFilePathColumn);
                                }
                            }
                        } else {
                            showToast(this, "You haven't picked Image");
                            productImagesList.clear();
                        }
                    } else {
                        productImagesList.clear();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    showToast(this, "Something went wrong");
                    productImagesList.clear();
                }
            });
}

getPathFromURI()是下面定义的方法

 public String getPathFromURI(Context context, Uri contentUri) {
    OutputStream out;
    File file = getPath();

    try {
        if (file.createNewFile()) {
            InputStream iStream = context != null ? context.getContentResolver().openInputStream(contentUri) : context.getContentResolver().openInputStream(contentUri);
            byte[] inputData = getBytes(iStream);
            out = new FileOutputStream(file);
            out.write(inputData);
            out.close();
            return file.getAbsolutePath();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

private byte[] getBytes(InputStream inputStream) throws IOException {
    ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];

    int len = 0;
    while ((len = inputStream.read(buffer)) != -1) {
        byteBuffer.write(buffer, 0, len);
    }
    return byteBuffer.toByteArray();
}

getPath()

private File getPath() {
    File folder = new File(Environment.getExternalStorageDirectory(), "Download");
    if (!folder.exists()) {
        folder.mkdir();
    }
    return new File(folder.getPath(), System.currentTimeMillis() + ".jpg");
}