如何删除 Android 10 范围存储中的图像(媒体存储条目和文件)

Dev*_*hah 6 android android-contentresolver android-studio android-10.0 scoped-storage

当我尝试删除我的应用程序贡献/拥有的图像时,它可以轻松删除。但对于我的应用程序不拥有的图片文件夹内的共享媒体,我通过捕获 向用户显示提示RecoverableSecurityException。但即使在ALLOWING之后,我也无法删除该特定图像文件。

这是我正在使用的代码,请指出我做错了什么。

  • 删除后,图像不会出现在图库或我的应用程序中,但它保留在文件管理器中,并在手机重新启动后重新出现在图库中(我猜只有 MediaStore 条目被删除)
  • 该代码适用于 Android 11 设备。
  • 结果startIntentSenderForResult(intentSender, 12, null, 0, 0, 0, null);是RESULT_OK

用于获取文件:(此代码位于“我的活动”中)

   try {
            String DIRECTORY_NAME = "%Pictures/App_Name%";
            String selection = MediaStore.MediaColumns.RELATIVE_PATH + " like ? ";
            String[] selectionArgs = new String[]{DIRECTORY_NAME};
            ContentResolver contentResolver = this.getContentResolver();
            Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, selection, selectionArgs, null);

            while(cursor.moveToNext()){
                long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
                Uri contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);

                uriArrayList.add(contentUri);

            }
            cursor.close();
        }
        catch (Exception e){
            e.printStackTrace();
        }
Run Code Online (Sandbox Code Playgroud)

对于删除图像文件:(此代码位于我的适配器类中)

    try {
    ContentResolver contentResolver = context.getContentResolver();
    cachedUri = f; //f is Uri 
    contentResolver.delete(f, null, null);
}catch (SecurityException securityException) {

    RecoverableSecurityException recoverableSecurityException;
    if (securityException instanceof RecoverableSecurityException) {
        recoverableSecurityException =
                (RecoverableSecurityException) securityException;
    } else {
        throw new RuntimeException(
                securityException.getMessage(), securityException);
    }
  
    IntentSender intentSender = recoverableSecurityException.getUserAction()
            .getActionIntent().getIntentSender();
    try {
        resultInterface.onResultTaken(intentSender, cachedUri); //Giving a call to the activity that implements the interface

    } catch (Exception e) {
        e.printStackTrace();
    }
}
Run Code Online (Sandbox Code Playgroud)

提示用户(在“我的活动”内获取 onActivityResult):

public class SomeActivity extends AppCompatActivity implements ResultTakenListener{

protected void onCreate(){ 
...}

@Override
public void onResultTaken(IntentSender intentSender, Uri uri) throws IntentSender.SendIntentException {
    cacheduri = uri;
    startIntentSenderForResult(intentSender, 12, null, 0, 0, 0, null);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 12){
    Log.d("Result Code is-->", String.valueOf(resultCode)); //This gives RESULT_OK
        if(resultCode == RESULT_OK){
            ContentResolver contentResolver = this.getContentResolver();
            contentResolver.delete(cacheduri, null, null);
    
        }
    }
}}
Run Code Online (Sandbox Code Playgroud)

que*_*gre 1

我还没有测试过它,但我认为当您处理低于 Q 的构建时,您需要集成自定义行为。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                
         //your existing code that seems to work above Q
            } else {
                String docsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
                File file = new File(docsDir, "fileName.jpg");
                if(file.exists());
                file.delete();
            }
Run Code Online (Sandbox Code Playgroud)