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

Android 13及以上访问内部存储非媒体地图文件的权限问题

Android 13下访问自定义格式地图文件的权限解决方案

一、先清理无效权限

你当前添加的权限里,很多是系统保护权限(普通应用无法获取)或重复权限,完全可以删除:

  • MOUNT_UNMOUNT_FILESYSTEMS、WRITE_MEDIA_STORAGE、MEDIA_CONTENT_CONTROL、MANAGE_MEDIA:这些是系统级权限,第三方APP无法通过正常渠道获取,直接删除。
  • 重复的READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE:保留一份即可,且Android 13及以上对非媒体文件,这两个权限已失效。
  • READ_MEDIA_AUDIO、READ_MEDIA_IMAGES、READ_MEDIA_VIDEO:你的文件是自定义.map格式,不属于媒体类型,这些权限没用,直接删除。

二、针对自定义文件的权限方案

根据文件存储位置,选择对应方案:

方案1:优先使用应用专属目录(无需权限)

如果地图文件可以放在应用的专属存储目录,这是最省心的方案——Android 13及所有版本都不需要任何权限,直接读写。

  • 内部专属目录路径:context.getFilesDir()(对应手机内部存储的Android/data/你的包名/files/)
  • 外部专属目录路径:context.getExternalFilesDir(null)(对应外部存储的Android/data/你的包名/files/)

示例代码(读取文件):

File mapFile = new File(context.getFilesDir(), "country.map");
if (mapFile.exists()) {
    // 执行文件读写操作
}

方案2:访问公共目录(需MANAGE_EXTERNAL_STORAGE权限)

如果文件必须放在公共目录(比如Download、Documents),需要申请MANAGE_EXTERNAL_STORAGE权限,但注意:

  • Google Play审核会严格限制该权限的使用,仅允许文件管理器、备份类等特定场景的APP申请,你的地图应用可能无法通过审核。
  • 实现步骤:
    1. 在Manifest中声明权限:
      <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
          tools:ignore="ScopedStorage" />
      
    2. 动态申请权限:
      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()));
              startActivity(intent);
          }
      }
      

方案3:使用存储访问框架(SAF,无需特殊权限)

这是Google推荐的替代方案,无需申请任何权限,通过让用户手动选择文件/目录来获取访问权限:

  • 打开文件选择器获取.map文件的Uri:
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("*/*"); // 或者指定自定义类型 "application/x-map"(如果系统识别)
    startActivityForResult(intent, REQUEST_CODE_PICK_MAP_FILE);
    
  • 在onActivityResult(或Activity Result API)中获取Uri后,通过ContentResolver读写:
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICK_MAP_FILE && resultCode == RESULT_OK) {
            Uri uri = data.getData();
            // 读取文件内容
            try (InputStream inputStream = getContentResolver().openInputStream(uri)) {
                // 处理输入流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

三、总结

  • 优先选择方案1,无需权限且符合Android存储规范;
  • 若必须访问公共目录,优先用方案3(SAF),避免审核风险;
  • 非必要不要用方案2,否则可能无法通过Google Play审核。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:49:55