2

I'm saving an image in DCIM directory, but in cases, I need to delete it. Previously, I called just image.delete(), where image is file. But now this image is saved in another way:

    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM" + File.separator + IMAGES_FOLDER_NAME);

    Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
    OutputStream fos = resolver.openOutputStream(imageUri);
    boolean saved = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

I tried to make a query with its name and call contentResolver.delete(...), but it doesn't work.

I have permission to write external storage, but I don't want to use SAF.

How can I delete such file?

4

4 回答 4

4

您需要使用调用插入时获得的使用delete方法。ContentResolverUri

 Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
 OutputStream fos = resolver.openOutputStream(imageUri);
 boolean saved = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
 ......
 int result = resolver.delete(imageUri, null, null);
 if (result > 0) {
     Log.d("Tag", "File deleted");
 }

如果您没有存储需要执行的 Uri query(),请检索内容然后调用delete.

于 2019-08-06T08:29:23.293 回答
1

调用方法 startActivityForResult 之前的 intent.addFlags。像这样

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
      intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
          | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

因为它检查 ContentProvider#enforceWritePermissionInner 中的权限。

真正的实现是在 ActivityManagerService#checkPermission 方法中。

于 2020-08-13T12:08:04.880 回答
0

完整的解决方案还应包括处理在尝试使用 ContentResolver 删除时将在 Andorid Q 上发生的潜在错误。在这种情况下,您应该将代码包装在 try/catch 块中。以下解决方案:

      try {
        // 1
        getApplication<Application>().contentResolver.delete(
                imageUri,"${MediaStore.Images.Media._ID} = ?",
                arrayOf(imageId)
        )
      }
       // 2
      catch (securityException: SecurityException) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
          val recoverableSecurityException =
                  securityException as? RecoverableSecurityException
                          ?: throw securityException

             val intentSender = recoverableSecurityException.userAction.actionIntent.intentSender
             startIntentSenderForResult(
                intentSender,
                DELETE_PERMISSION_REQUEST,
                null,
                0,
                0,
                0,
                null
              )
        } else {
          throw securityException
        }
      }
  1. 在这里,您在 try 块内调用 contentResolver.delete(),因为此方法可以在运行时抛出 SecurityException。该方法需要您要删除的图像的 ContentUri。在 where 参数中,您指定要根据其 _ID 删除图像。在最后一个参数中,您在数组中传递 _ID 的字符串版本。

  2. 在 Android 10 及更高版本中,无法直接从 MediaStore 删除或修改项目。您需要获得这些操作的权限。正确的做法是首先捕获RecoverableSecurityException,其中包含一个intentSender,可以提示用户授予权限。然后,您使用从 RecoverableSecurityException 中提取的 intentSender 启动IntentSenderForResult,以授予在 Android Q 上删除文件的附加权限。

来源:https ://www.raywenderlich.com/9577211-scoped-storage-in-android-10-getting-started

于 2020-06-13T16:20:07.667 回答
0
  File file = new File(delPath);
  if (file.exists()) {
   try {
        Uri imageUri = FileProvider.getUriForFile(Context,
                        getApplicationContext()
                                .getPackageName() + ".provider", file);
        ContentResolver contentResolver = getContentResolver();
                int deletefile = contentResolver.delete(imageUri, null, null);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

这里的删除路径delPath是要从存储中删除的图像的文件路径。

于 2019-08-06T09:21:31.520 回答