当前位置:首页 > 行业动态 > 正文

安卓外部存储挂载

安卓外部存储挂载详解

安卓存储结构

安卓系统的存储分为 内部存储(Internal Storage)和 外部存储(External Storage)。

  • 内部存储:系统内置的闪存空间,包含系统分区和用户数据分区。
  • 外部存储:可移动的存储介质(如SD卡、OTG设备)或虚拟存储(如云存储)。
类型 特点
内部存储 系统内置,无需挂载,直接通过/data/data访问应用私有目录。
外部存储 需手动挂载,通过/mnt/sdcard/storage/emulated/0访问(Android 10+)。

外部存储挂载流程

  1. 检查存储状态
    通过StorageManager检测外部存储是否可用:

    安卓外部存储挂载

    StorageManager sm = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
    String state = sm.getVolumeState(sm.getPrimaryVolume());
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // 存储已挂载
    }
  2. 动态申请权限

    • Android 6.0+:需申请READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE
    • Android 10+:新增MANAGE_EXTERNAL_STORAGE权限(仅系统应用可用)。
  3. 挂载外部存储

    安卓外部存储挂载

    • 物理存储(如SD卡):系统自动挂载,无需手动操作。
    • 虚拟存储:通过StorageAccessFrameworkMediaStore接口访问。

权限管理与兼容性处理

Android版本 权限要求 访问方式
Android 9- READ_EXTERNAL_STORAGE + WRITE_EXTERNAL_STORAGE 直接文件路径访问(如/sdcard/file.txt
Android 10+ READ_EXTERNAL_STORAGE(作用受限) 通过MediaStoreStorageAccessFramework
Android 11+ 仅系统应用可写外部存储 依赖MANAGE_EXTERNAL_STORAGE权限

兼容性处理示例

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    // 使用Scoped Storage API
    Uri uri = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
} else {
    // 传统文件路径访问
    File file = new File(Environment.getExternalStorageDirectory(), "file.txt");
}

常见问题与解决方案

问题 原因 解决方案
存储空间显示为“只读” 未授予写入权限或存储设备被锁定 检查权限声明,确保存储设备未被写保护
文件创建失败 Scoped Storage限制或沙盒机制 使用MediaStorecreateTempFile方法
跨Android版本兼容问题 不同版本权限模型差异 分版本处理逻辑,优先使用通用API

相关问题与解答

问题1:如何判断设备是否支持外部存储?

解答
通过StorageManager检查是否存在可挂载的外部存储卷:

StorageManager sm = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
boolean hasExternalStorage = sm.getVolumeList().size() > 1; // 除主存储外是否有额外卷

问题2:Android 11+如何实现应用间文件共享?

解答
使用StorageAccessFrameworkIntent.ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT,并通过ContentResolver长期保存URI权限:

安卓外部存储挂载

// 请求用户选择文件
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/");
startActivityForResult(intent, REQUEST_CODE);
// 处理返回的URI
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
        Uri uri = data.getData();
        getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }
}