zoukankan      html  css  js  c++  java
  • Android 4.0以后正确的获取外部sd卡存储目录

    刚解决这个棘手的问题 找了很久,随笔记下。

    网上搜索 android 获取外部sd卡存储目录 普遍都是:

    1) Environment.getExternalStorageDirectory() 这个返回file类

    2) Environment.getExternalStorageDirectory().getAbsolutePath 这个直接返回String

    二者一看没有任何的区别都能返回sk卡目录。

    以上这个代码在android4.0以后只能返回内部存储的卡的路径。并不能返回外部插入的sd卡 (手机一般是micro sd卡)

    这里引用下csdn里面 kidass_x这位大神的解释:

    Environment.getExternalStorageDirectory()是Android 2.x时代的产物,那时Android主流设备只有很小的内置存储器,然后都会外置一张sd卡,那时这个方法返回的就是外置sd卡的根路径。

    但随着Android进入4.x时代,大部分Android设备都已经内置一个较大存储卡,甚至不提供外置存储卡插槽了,此时Environment.getExternalStorageDirectory()返回的路径其实是由内置存储卡虚拟出来的一个目录,用户在这一目录下有全部权限。

    按理说Android应该继续提供其他的方法来返回其他的外置存储卡的路径,但这一次Android却没有,因为Android系统开发者们发现之前直接允许程序任意访问sd卡的做法导致sd卡上垃圾文件的不可管理性,尤其在程序被卸载后,由于不知道那些文件是由这一程序创建的,所以无法关联删除,因此Android 4.0并不给程序开发者提供外置存储卡的路径,而是提供了诸如getExternalFilesDirs()和getExternalCacheDirs()这样的方法,直接给开发者提供一个限制内的存储文件的空间,这个空间是与程序关联的,因此在卸载程序时这两个目录下的文件也会被关联删除。

    闲话到此,主要是为了说明Android 4.0之后,系统不希望开发者直接访问sd卡,所以也没有提供查询多sd卡路径的方法(在2.x和3.x时代末期我们都以为4.0会提供这样的查询接口)。

    但是,Android系统不提供并不意味着就没有办法了,Android说到底还是Linux系统,因此外置sd卡必然是按照Linux的挂载方式挂载到系统中的。因此目前比较主流的方法就是绕过Android直接去读取Linux底层的挂载文件来找到系统中挂载的外置存储器。

    Android 4.0之后正确的获取外部存储sd卡的代码(网上找到的)

     /***
         * 获取外部存储卡列表
         * @return
         * @throws IOException
         */
        public static List<String> getExtSDCardList() throws IOException {
            File file = new File("/proc/mounts");
            if (file.canRead()) {
                BufferedReader reader = null;
                List<String> result = new ArrayList<String>();
                reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
                String lines;
                while ((lines = reader.readLine()) != null) {
                    String[] parts = lines.split("\s+");
                    if (parts.length >= 2) {
                        if (parts[0].contains("vold")) {
                            result.add(parts[1]);
                        }
                    }
                }
                return result;
            }
            return null;
        }

    还有听说Android 4.0之后外部存储卡的权限也和之前的不一样了。

    Android 4.0 之前: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 这个只能读写内部存储卡。

    Android 4.0 之后: <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE"/> 这个就能读写外部存储卡了。

  • 相关阅读:
    mysql 高效分页控件及c#调用实例
    sql server高效分页控件及c#调用实例
    Log4net从下载到使用例子
    Nlog从下载到使用例子
    使用httpClient调用接口,参数用map封装或者使用JSON参数,并转换返回结果
    Pool thread stack traces: Thread[C3P0PooledConnectionPoolManager[identityToken->原因解决办法
    使用spring的aop监听所有controller或者action日志
    ActiveMQ监听消息并进行转发,监听不同的mq服务器和不同的队列
    zookeeper集群查看状态时报错Error contacting service. It is probably not running的一些坑以及解决办法
    AopProxyUtils.getSingletonTarget(Ljava/lang/Object;)Ljava/lang/Object;大坑
  • 原文地址:https://www.cnblogs.com/rui1236/p/6002432.html
Copyright © 2011-2022 走看看