Android sd相关笔记 - Android4.4上应用写sd卡问题

Android sd卡笔记


1. Environment.getExternalStorageDirectory() 的使用
(1)Environment.getExternalStorageDirectory()在部分手机中获取到的是内部存储路径,而不是sd卡路径,如三星手机等
(2).如果系统设置了优先存储在内置存储中,那么Environment.getExternalStorageDirectory()获取到的也是内部存储路径
(3)Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)在没有sd的部分手机
(Environment.getExternalStorageDirectory()指向内部路径时)上也返回true
[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. //此方法不知是否可行,没有大量手机测试  
  2. public static boolean externalMemoryAvailable(final Context context) {  
  3. File[] list = context.getExternalCacheDirs();  
  4. boolean hasSd = list != null && list.length > 1;  
  5. return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) && hasSd;  
  6. }  

那么如何正确获取手机存储位置路径呢,这里附上链接:
http://blog.fidroid.com/post/android/ru-he-zheng-que-huo-de-androidnei-wai-sdqia-lu-jing     (sd卡路径获取)
http://www.cnblogs.com/bluestorm/p/3694921.html    (/storage/sdcard, /sdcard, /mnt/sdcard 三者的区别)
http://www.cnblogs.com/yejiurui/p/3421314.html   (android中的目录结构介绍)

2. 在sd卡根目录下创建目录(部分手机)失败

因为在 Android4.4新版本中,Google针对外卡写权限增加了CTS用例,对外卡的写操作增加了限制,由此导致部分开发者的应用可能存在外卡写权限兼容性问题。
Android4.4对外卡的写操作进行增加了如下两条限制:
(1)通过用户态文件系统fuse对外卡的写权限进行了限制;
  • 用户只能在外卡Android/data/<package-name>/目录下进行写操作。
  • 拥有WRITE_MEDIA_STORAGE权限(仅特权用户才能申请这个权限)的用户才能对整个外卡进行写操作。
(2)Android4.4的MediaProvider不允许对外卡进行任何写操作。 

注意:随着应用的卸载,Android/data/<package-name>/目录也会被删除

参考:
http://developer.huawei.com/devunion/ui/newsDetail.html?news=/devunion/news/n_00033.html
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1027/1849.html      (Android 外部存储权限分析)
https://developer.android.com/training/articles/scoped-directory-access.html

3. 在sd卡的Android/data/<package-name>/目录下mkdirs()失败(部分手机)
本人经过多次尝试,终于成功了,做法是:
(1)mContext.getExternalFilesDir(null).getAbsolutePath();//要先执行该方法,后面才能创建目录,否则失败
个人猜测是新建了Android/data/<package-name>/目录
(2)然后再调用mkdirs()

4. getExternalFilesDir(null)及getExternalFilesDirs(null)
getExternalFilesDir(null)返回的是SdCard/Android/data/应用包名/files或者内置存储路径/Android/data/应用包名/files
getExternalFilesDirs(null)返回的是内置和sd卡的/Android/data/应用包名/files

测试:
[java]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. private void getDir(){  
  2.         Context context = getApplicationContext();  
  3.         Log.e(TAG, "getCacheDir():" + context.getCacheDir().getAbsolutePath());  
  4.         Log.e(TAG, "getExternalCacheDir():" + context.getExternalCacheDir().getAbsolutePath());  
  5.         print("getExternalCacheDirs():", context.getExternalCacheDirs());  
  6.         Log.e(TAG, "getFilesDir:" + context.getFilesDir().getAbsolutePath());  
  7.         Log.e(TAG, "getExternalFilesDir(null):" + context.getExternalFilesDir(null).getAbsolutePath());  
  8.         print("getExternalFilesDirs(null):", context.getExternalFilesDirs(null));  
  9.           
  10.         Log.e(TAG, "getObbDir:" + context.getObbDir().getAbsolutePath());  
  11.         print("getObbDirs():", context.getObbDirs());  
  12.           
  13.         Log.e(TAG, "Environment.getDataDirectory():" + Environment.getDataDirectory());  
  14.         Log.e(TAG, "Environment.getDownloadCacheDirectory():" + Environment.getDownloadCacheDirectory());  
  15.         Log.e(TAG, "Environment.getRootDirectory():" + Environment.getRootDirectory());  
  16.     }  
  17.       
  18.     private void print(String tag, File[] list){  
  19.         if(list == null){  
  20.             Log.e(TAG, tag + "null or list.length == 0");  
  21.         }else{  
  22.             int i = 0;  
  23.             for(File f : list){  
  24.                 if(f != null){  
  25.                     i++;  
  26.                     Log.e(TAG, tag + " " + i + " " + f.getAbsolutePath());  
  27.                 }  
  28.             }  
  29.         }  
  30.     }  

(1)有sd卡
[plain]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. 08-24 14:10:23.666: E/DirDemo(26722): getCacheDir():/data/data/应用包名/cache  
  2. 08-24 14:10:23.666: E/DirDemo(26722): getExternalCacheDir():/storage/emulated/0/Android/data/应用包名/cache  
  3. 08-24 14:10:23.666: E/DirDemo(26722): getExternalCacheDirs(): 1 /storage/emulated/0/Android/data/应用包名/cache(内部存储)  
  4. 08-24 14:10:23.666: E/DirDemo(26722): getExternalCacheDirs(): 2 /storage/sdcard1/Android/data/应用包名/cache  
  5. 08-24 14:10:23.666: E/DirDemo(26722): getFilesDir:/data/data/应用包名/files  
  6. 08-24 14:10:23.666: E/DirDemo(26722): getExternalFilesDir(null):/storage/emulated/0/Android/data/应用包名/files  
  7. 08-24 14:10:23.667: E/DirDemo(26722): getExternalFilesDirs(null): 1 /storage/emulated/0/Android/data/应用包名/files  
  8. 08-24 14:10:23.667: E/DirDemo(26722): getExternalFilesDirs(null): 2 /storage/sdcard1/Android/data/应用包名/files  
  9. 08-24 14:10:23.667: E/DirDemo(26722): getObbDir:/storage/emulated/0/Android/obb/应用包名  
  10. 08-24 14:10:23.667: E/DirDemo(26722): getObbDirs(): 1 /storage/emulated/0/Android/obb/应用包名  
  11. 08-24 14:10:23.667: E/DirDemo(26722): getObbDirs(): 2 /storage/sdcard1/Android/obb/应用包名  
  12. 08-24 14:10:23.667: E/DirDemo(26722): Environment.getDataDirectory():/data  
  13. 08-24 14:10:23.667: E/DirDemo(26722): Environment.getDownloadCacheDirectory():/cache  
  14. 08-24 14:10:23.667: E/DirDemo(26722): Environment.getRootDirectory():/system  

(2)无sd卡
[plain]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. 08-24 14:22:39.862: E/DirDemo(6457): getCacheDir():/data/data/应用包名/cache  
  2. 08-24 14:22:39.873: E/DirDemo(6457): getExternalCacheDir():/storage/emulated/0/Android/data/应用包名/cache  
  3. 08-24 14:22:39.881: E/DirDemo(6457): getExternalCacheDirs(): 1 /storage/emulated/0/Android/data/应用包名/cache  
  4. 08-24 14:22:39.882: E/DirDemo(6457): getFilesDir:/data/data/应用包名/files  
  5. 08-24 14:22:39.890: E/DirDemo(6457): getExternalFilesDir(null):/storage/emulated/0/Android/data/应用包名/files  
  6. 08-24 14:22:39.895: E/DirDemo(6457): getExternalFilesDirs(null): 1 /storage/emulated/0/Android/data/应用包名/files  
  7. 08-24 14:22:39.903: E/DirDemo(6457): getObbDir:/storage/emulated/0/Android/obb/应用包名  
  8. 08-24 14:22:39.907: E/DirDemo(6457): getObbDirs(): 1 /storage/emulated/0/Android/obb/应用包名  
  9. 08-24 14:22:39.907: E/DirDemo(6457): Environment.getDataDirectory():/data  
  10. 08-24 14:22:39.907: E/DirDemo(6457): Environment.getDownloadCacheDirectory():/cache  
  11. 08-24 14:22:39.907: E/DirDemo(6457): Environment.getRootDirectory():/system  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值