"IllegalArgumentException: Unknown URL" 尝试删除由 Android 中的相机意图创建的位图时

"IllegalArgumentException: Unknown URL" when trying to delete a bitmap created by a camera intent in Android

我有一段使用相机拍照的有效代码。拍摄完照片后,我会收到它以按比例缩小并以不同方式对其进行操作。 我想做的是删除原始保存的图片(由 Android 自动完成),然后保存我处理过的图片。

所以这是我启动 Intent 的代码:

 private void takePicture(){
        File storagePath =  getAlbumStorageDir();
        String timeStamp = System.currentTimeMillis()+"";
        File file = new File(storagePath, timeStamp + ".jpg");

        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            file.delete();
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        capturedImageUri = Uri.fromFile(file);
        Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        i.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
        context.startActivityForResult(i, CameraCapture.REQUEST_TAKE_PHOTO);
    }

private File getAlbumStorageDir() {
        File file = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), context.getResources().getString(R.string.gallery));
        Log.d("PICTUREVIEW", file.getAbsolutePath());
        if (!file.mkdirs()) {
            Log.e("MyFileStorage", "Directory not created");
        }
        return file;
    }

而退货时,我是这样处理的:

private void manageCapturedPicture() {
    try {
        Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(capturedImageUri);
        context.sendBroadcast(mediaScanIntent);
    //loadPictures();
    Bitmap bm = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(capturedImageUri));
    int width = LayoutUtil.getScreenWidth(context) * 2;
    if (width > 600) {
        width = 600;
    }
    double ratio = ((double)bm.getHeight() / (double)bm.getWidth());
    double height = width * ratio;
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bm, width, (int)height, true);

    ContentResolver contentResolver = context.getContentResolver();
    contentResolver.delete(capturedImageUri, null, null);

    imageView.setImageBitmap(scaledBitmap);

} catch (IOException e) {
    e.printStackTrace();
}
}

如您所见,我正在缩小图像并将其显示在图像视图中(仅用于测试目的)。在我尝试从外部存储中删除原始图片之前,这一切都很好。 当我将这些添加到行时:

    ContentResolver contentResolver = context.getContentResolver();
    contentResolver.delete(capturedImageUri, null, null);

我得到了以下输出(当然还有崩溃):

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=null} to activity {nightout.dk.nightoutandroid/nightout.dk.nightoutandroid.MainActivity}: java.lang.IllegalArgumentException: Unknown URL file:///storage/emulated/0/Pictures/nightout/1450477843900.jpg
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3790)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3833)
            at android.app.ActivityThread.access00(ActivityThread.java:152)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5538)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
     Caused by: java.lang.IllegalArgumentException: Unknown URL file:///storage/emulated/0/Pictures/nightout/1450477843900.jpg
            at android.content.ContentResolver.delete(ContentResolver.java:1323)
            at nightout.dk.nightoutandroid.views.PicturesView.manageCapturedPicture(PicturesView.java:137)
            at nightout.dk.nightoutandroid.views.PicturesView.receiveStringMessage(PicturesView.java:197)
            at nightout.dk.nightoutandroid.services.eventbus.EventBus.postStringMessage(EventBus.java:39)
            at nightout.dk.nightoutandroid.MainActivity.onActivityResult(MainActivity.java:158)
            at android.app.Activity.dispatchActivityResult(Activity.java:6238)
            at android.app.ActivityThread.deliverResults(ActivityThread.java:3786)
            at android.app.ActivityThread.handleSendResult(ActivityThread.java:3833)
            at android.app.ActivityThread.access00(ActivityThread.java:152)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1390)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5538)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

在 Java 中,要删除一个文件,创建一个指向该文件的 File 对象,然后对该 File 对象调用 delete()

请注意,由于您可能会在相机应用程序处于前台时进行配置更改或进程终止,因此请确保在保存的实例状态下保存文件路径Bundle 并从那里恢复它。

关于您的 manageCapturedPicture() 方法:

  • 如果您打算在几毫秒后删除它,请不要在 MediaStore 中为图像编制索引

  • 请随意在 BitmapFactory 上使用 decodeFile(),因为这是您控制的文件

  • 请使用 BitmapFactory.Options 并在读取图像时缩放图像,而不是通过读取完整图像然后缩放来浪费近两倍的堆 space

  • 不要尝试 delete() 来自 ContentProvider 的东西,而你没有从 ContentProvider

  • 得到