Android 开发SD卡存储目录的使用

Android 开发SD卡存储目录的使用

最近两天产品收到用户反馈:“下载目录是否可以选择外置SD卡”,用户就是上帝啊,需要什么我们就要实现什么。但是,在真正的开发过程中遇到了不少问题,记下来做个前车之鉴。

你还在为开发中频繁切换环境打包而烦恼吗?快来试试 Environment Switcher 吧!使用它可以在app运行时一键切换环境,而且还支持其他贴心小功能,有了它妈妈再也不用担心频繁环境切换了。https://github.com/CodeXiaoMai/EnvironmentSwitcher

解决思路

先说一下思路吧,既然是可以选择外置SD卡,那么很显然SD卡是可有可无的,那么就需要去扫描当前是否存在外置SD卡。只有存在SD卡,用户才有选择的余地。下面是扫描存储设备的代码。如果返回的sparseArray.size() > 1,说明存在外置SD卡,且sparseArray.get(1) 得到的就是外置SD卡的路径,否则不存在。

public static SparseArray<String> scanStorage() {
    SparseArray<String> sparseArray = new SparseArray<>();
    final StorageManager storageManager = (StorageManager) HSApplication.getContext().getSystemService(
            Context.STORAGE_SERVICE);
    try {
        String[] paths = (String[]) storageManager.getClass().getMethod("getVolumePaths")
                .invoke(storageManager);
        for (int i = 0; i < paths.length; i++) {
            String status = (String) storageManager.getClass()
                    .getMethod("getVolumeState", String.class).invoke(storageManager, paths[i]);
            if (Environment.MEDIA_MOUNTED.equals(status)) {
                sparseArray.append(i, paths[i]);
            }
        }
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    return sparseArray;
}

Android 4.4 带来的问题

接下来设置下载目录为外置SD卡,我的设备的外置SD卡路径为“/storage/sdcard1” (PS:不同设备的SD卡路径可能是不一样的,跟手机的Rom有关系,因此千万不能写死。)然后我把下载路径设置为“/storage/sdcard1/com.xiaomai.myproject/download”,然后开始下载,问题出现了。

open failed: EACCES (Permission denied)

哦!大概意思就是:文件打开失败,原因也说的很清楚,权限拒绝!该死,忘了加权限。去manifest.xml中声明权限!

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

可是我发现已经声明存储设备的读写权限了啊,再试一次,还是不行。这是怎么回事,难道我用来假的权限????于是开始Google,经过一番搜索终于找到问题的原因了。

https://source.android.com/devices/storage/index.html

下面是Android官方文档中一段话

Access to external storage is protected by various Android permissions. Starting in Android 1.0, write access is protected with the WRITE_EXTERNAL_STORAGE permission. Starting in Android 4.1, read access is protected with the READ_EXTERNAL_STORAGE permission.

Starting in Android 4.4, the owner, group and modes of files on external storage devices are now synthesized based on directory structure. This enables apps to manage their package-specific directories on external storage without requiring they hold the broad WRITE_EXTERNAL_STORAGE permission. For example, the app with package name com.example.foo can now freely access Android/data/com.example.foo/ on external storage devices with no permissions. These synthesized permissions are accomplished by wrapping raw storage devices in a FUSE daemon.

意思是:

访问外部存储器受到各种Android权限的保护。从Android 1.0开始,写权限受到权限的 WRITE_EXTERNAL_STORAGE保护。从Android 4.1开始,读取权限受到权限READ_EXTERNAL_STORAGE 保护。

从Android 4.4开始,外部存储设备上的文件所有者,组和模式现在基于目录结构进行合成。这使应用程序能够在外部存储上管理其特定于包的目录,而无需拥有广泛 WRITE_EXTERNAL_STORAGE权限。例如,具有包名称“com.example.foo”的应用程序现在可以在没有权限的外部存储设备上对“Android/data/com.example.foo/”进行自由访问 。这些合成的权限是通过在FUSE守护进程中包装原始存储设备来实现的。

这么一大段,说人话就是从Android4.4,应用对外置SD卡的访问只限于“Android/data/[包名]/”,而对于外置SD卡的其他路径,没有权限访问。(内置存储不受影响,可以访问任何目录)

问题原因找到了,那就把下载路径老老实实的改成“Android/data/com.xiaomai.myproject/”吧,我再自己的包名下读写文件总行了吧。可是。。。没错,还是不行,问题还是权限拒绝。原来,Android4.4以后应用程序本身是没有权限在外置SD卡中创建目录的,包括自己的包名。必须用下面的方法

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        getExternalFilesDirs(null);
}

再次运行,这次终于可以了。

SD女佣 SD Maid Pro将会以完善的方式帮您整理、清洁android设备。&rdquo;浏览器&rdquo;是一个完全成熟的文件管理器,用它来浏览管理你的android文件夹。&rdquo;搜索器&rdquo;可以使用来打来/删除 或者重命名文件(搜索文件内部,支持通配符)。&rdquo;查找冗余&rdquo;可以搜索你设备的空文件夹目录,并且比较那些已安装的应用程序列表。&rdquo;应用控制&rdquo;可以冻结、重置以及删除应用程序(甚至是系统应用程序)。&rdquo;清理系统&rdquo;可以清理设备中已知的不必要的目录。&rdquo;优化数据库&rdquo;检测数据库((System/Apps),并可以整理压缩数据库,以加快访问,以及腾出更多的可用空间。 这个来自您Android设备的女佣,会让你的存储器恢复到整洁状态并保持下去。 这个程序最好安装在已经ROOT的Android设备 ! 没有ROOT的设备,SD女佣对必要的目录没有访问权限。 这是一个强大的工具 !但是使用它会有相对而言的风险 ! 最好不要安装非官方版本的SD女佣,它们“签证包&rdquo;是错误,会带来不安全因素。 金无足赤人无完人, Android也是如此。 被你删除的应用程序有时候会留下的残留数据。 android系统也会不断创建日志、 崩溃报告和普通用户用不上调试文件。 在您使用“谷歌应用市场&rdquo;下载应用程序之后,它会产生临时文件(如同浏览器访问网站一样)。 让我们来搞定这些无用的垃圾 … … 为什么不使用SD女佣&rdquo;来一次全面的清洁呢?SD 女佣将会以完善的方式帮您整理、清洁android设备 (^.^)! 选择一个标签卡项,点击&rdquo;检查&rdquo;,然后点击&rdquo;全部清理&rdquo;或者根据需求单个的选择。它就这么的容易。 “浏览器&rdquo;是一个完全成熟的文件管理器,用它来浏览管理你的android文件夹。 “搜索器&rdquo;可以使用来打来/删除 或者重命名文件(搜索文件内部,支持通配符)。 “查找冗余&rdquo;可以搜索你设备的空文件夹目录,并且比较那些已安装的应用程序列表。 “应用控制&rdquo;可以冻结、重置以及删除应用程序(甚至是系统应用程序)。 “清理系统&rdquo;可以清理设备中已知的不必要的目录。 “优化数据库&rdquo;检测数据库((System/Apps),并可以整理压缩数据库,以加快访问,以及腾出更多的可用空间。 此外,你也可以查看&rdquo;最大文件&rdquo;,或者查看上次修改的文件。 免费版可以使用10个主要功能,另外2个高级功能,需要购买“解锁器&rdquo;来解锁。 SD女佣正在精益求精的不断的研发和设计中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值