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"/> 这个就能读写外部存储卡了。