You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11 Java开发:如何通过路径删除非本应用创建的音乐文件

问题原因

从Android 10(API 29)开始系统引入分区存储机制,第三方应用默认无法直接通过File API修改/删除公共存储目录下其他应用创建的文件,哪怕你在AndroidManifest里声明了存储权限,直接调用File.delete()也会被系统拦截返回false。

解决方案

有两种可选方案,你可以根据自己的上架需求选择:

方案1:使用MediaStore删除(官方推荐,无需全文件访问权限,上架无限制)

不需要申请MANAGE_EXTERNAL_STORAGE高危权限,适配所有Android版本,代码示例如下:

private boolean deleteMusicFile(Context context, File file) {
    String filePath = file.getAbsolutePath();
    long id = -1;
    // 先从MediaStore查询对应文件的id
    Cursor cursor = context.getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            new String[]{MediaStore.Audio.Media._ID},
            MediaStore.Audio.Media.DATA + "=? ",
            new String[]{filePath}, null);
    if (cursor != null && cursor.moveToFirst()) {
        id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID));
        cursor.close();
    }
    if (id == -1) {
        return false;
    }
    // 执行删除
    Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
    try {
        int deleteRow = context.getContentResolver().delete(uri, null, null);
        // 同时删除物理文件缓存(如果存在)
        if (file.exists()) {
            file.delete();
        }
        return deleteRow > 0;
    } catch (SecurityException e) {
        // Android 11及以上如果没有修改权限,会抛异常,需要申请修改权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            IntentSender intentSender = MediaStore.createDeleteRequest(context.getContentResolver(), Collections.singletonList(uri)).getIntentSender();
            // 你需要在当前Activity启动这个IntentSender,等待用户授权后再执行删除
            ((Activity) context).startIntentSenderForResult(intentSender, 1001, null, 0, 0, 0);
        }
        return false;
    }
}

你原来的长按删除逻辑改成调用这个方法即可:

@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
    File file = files.get(i);
    boolean deleted = deleteMusicFile(this, file);
    return deleted;
}

方案2:申请全文件访问权限(适合不上架Google Play的场景)

如果你要继续用File API删除,可以申请MANAGE_EXTERNAL_STORAGE权限,除了清单里的声明,还要补充以下逻辑:

  1. 先在AndroidManifest的application标签里补充属性,适配Android 10过渡:
android:requestLegacyExternalStorage="true"
  1. 应用启动时动态申请权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    if (!Environment.isExternalStorageManager()) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, 1002);
    }
}

用户授权后,你原来的File.delete()逻辑就能正常执行。

注意事项
  • MANAGE_EXTERNAL_STORAGE属于高危权限,如果你要上架Google Play,需要提交应用功能说明证明你确实需要全文件访问权限,否则会被拒审,优先选择方案1。
  • Android 13及以上版本,原来的READ_EXTERNAL_STORAGE权限已经废弃,你需要换成READ_MEDIA_AUDIO权限申请。

内容的提问来源于stack exchange,提问作者namanop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 06:45:01