在安卓的开发中,有时候要用到大文件的存储,这个时候就不能存储在应用内部(data/data),只能借助外部存储。而外部存储又分为手机机身的存储空间(一级sd卡)和外置sd卡存储空间(二级sd卡)。

1.要存储首先是获得读写权限

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />//操作文件<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />//向sd卡写入<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />//读取sd卡信息
2.接下来是获得外存储路径
    我们一般会想到用Environment.getExternalStorageDirectory().getAbsolutePath(),但是由于国内手机系统各种定制,各个厂
商都做过了修改。
Environment.getExternalStorageDirectory().getAbsolutePath()的意思是获得外部存储的路径,各个厂商自己认为的外部存储可
能不一样,所以这个方法能调用到的路劲可能也有所差别。
    
    怎么解决呢?安卓源代码里面有一个类专门管理外部存储,那就是StorageManager。调用storageManager.getStorageVolumes()
就能获得所有外置sd卡的挂载情况。但是这个方法要7.0或者以上才能调用。所以我们考虑使用反射。
    
public static ArrayList<StorageInfo> getAvaliableStorages(Context context) {ArrayList<StorageInfo> storagges = new ArrayList<>();StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);try {Class<?>[] paramClasses = {};Method getVolumeList = StorageManager.class.getMethod("getVolumeList", paramClasses);getVolumeList.setAccessible(true);Object[] params = {};Object[] invokes = (Object[]) getVolumeList.invoke(storageManager, params);if (invokes != null) {StorageInfo info = null;for (int i = 0; i < invokes.length; i++) {Object obj = invokes[i];Method getPath = obj.getClass().getMethod("getPath", new Class[0]);String path = (String) getPath.invoke(obj, new Object[0]);info = new StorageInfo(path);File file = new File(info.path);if ((file.exists()) && (file.isDirectory()) && (file.canWrite())) {Method isRemovable = obj.getClass().getMethod("isRemovable", new Class[0]);String state = null;try {Method getVolumeState = StorageManager.class.getMethod("getVolumeState", String.class);state = (String) getVolumeState.invoke(storageManager, info.path);info.state = state;} catch (Exception e) {e.printStackTrace();}if (info.isMounted()) {info.isRemoveable = ((Boolean) isRemovable.invoke(obj, new Object[0])).booleanValue();storagges.add(info);}}}}} catch (NoSuchMethodException e1) {e1.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}storagges.trimToSize();return storagges;
}
这样便得到了所有的外置存储卡的信息。我的手机信息是
机身存储  /storage/emulated/0/1
外置sd卡  /storage/sdcard1/
3.文件写入
    我们只要调用storageInfo.isRemoveable 可移除的就是二级存储卡,一般就是我们可拔插的sd卡。不可移除的就是机身存储。
    调用storageInfo.isMounted()就可知道这个存储位置是否可用。

    (1)机身存储位置的文件写入
     这个没什么好讲,只要获得路径便可直接写入

    (2)外置sd卡的文件写入
     在4.4以前,外置sd卡也是可以直接写入的,但是在4.4以后Android开始有了多卡存储。于是拓展的sd卡,便没有了写入权限。
     据说是为了安卓系统可以在应用卸载之后可以轻松的删掉本地文件。

     但是,Android并不是禁止了sd卡所有的写入权限。在特定的目录下,我们还是可以执行写入操作的。那就是在sd卡的
    
   
    
    大功告成!
  
    context.getExternalFilesDir(null).getAbsolutePath();//要先执行此方法,创建sd卡目录,否则不能创建目录
    String direction = "/storage/sdcard1/Android/data/"+context.getPackageName()+"/files/ ";
    File file = new File(direction);
    if (!file.exists()){file.mkdirs();}
     Android/data/"+context.getPackageName()+"/files/  路径下,允许用户写入文件。这就可以理解了,特定的sd卡目录在
    应用卸载之后会被清除文件,而至于机身自带的存储空间要清除残留文件肯定是没问题的。这样就可以在一定程度上缓解安卓机
    越用越卡的毛病了(残留文件都被系统删除了)。
   所以,如果我们要在外置sd卡写入文件的话,只要写在这个路径下就可以了,我的是
   
    
   /storage/sdcard1/Android/data/"+context.getPackageName()+"/files/ 
   需要注意的是,在创建这个路径的时候要先调用context.getExternalFilesDir(null).getAbsolutePath(),一定要先调用这一句
   否则文件不能写入,这句话大概就是创建固定路径。
public class StorageInfo {public String path;public String state;public boolean isRemoveable;public StorageInfo(String path) {this.path = path;}public boolean isMounted() {return "mounted".equals(state);}
}

Android本地文件存储,机身和外置sd卡相关推荐

  1. 获取手机机身和外置SD卡存储容量的方法

    上一篇有获取外置SD卡路径的方法.获取之后把String型转为path就行了. 代码如下: MainActivity.java File file1=new File(getStoragePath(M ...

  2. Android 外置 SD 卡写入权限问题

    https://busy.im/post/android-sdcard-write/ 最近升级到 Android 9.0 后,发现文件管理器在写入外置 SD 卡时出现了写入失败的问题,定位到 File ...

  3. Android P 外置 SD 卡写入权限问题

    概述 Android 9.0 后,发现文件管理器在写入外置 SD 卡时出现了写入失败的问题,定位到 File.canWrite() 方法,发现返回了 false.经过讨论追踪定位,发现是由于 Goog ...

  4. Android获取拓展外置SD卡(可插拔)路径及读写外置SD卡的方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/xingnan4414/article/details/79388972 有需求做一些类似文件管理器的 ...

  5. android 获取默认存储路径,Android获取外置SD卡存储路径的方法

    在开发应用的过程中,经常会遇到需要获取设备存储路径的问题.而从网上看到的很多方法获取到的都是内置存储位置,并非外置SD卡路径,因此我推荐使用反射的机制来获取外置存储的路径. 通常,使用Environm ...

  6. Android判断有无外置SD卡(TF卡),并读写文件

    转载来源:https://blog.csdn.net/qq_27061049/article/details/94178875 1.相关方法说明: 2.Android Manifest.xml 添加权 ...

  7. android 获取sd卡目录失败_Android获取外置SD卡存储路径的方法

    在开发应用的过程中,经常会遇到需要获取设备存储路径的问题.而从网上看到的很多方法获取到的都是内置存储位置,并非外置SD卡路径,因此我推荐使用反射的机制来获取外置存储的路径. 通常,使用Environm ...

  8. 华为M2 无法写入外置sd卡 文件

    在Android开发者网站的 "外部存储技术信息"文档中描述道 :         WRITE_EXTERNAL_STORAGE只为设备上的主要外部存储授予写权限, ,应用程序无法 ...

  9. 外置存储权限在哪打开_安卓手机外置sd卡的权限怎么打开?

    展开全部 在2.x的版本中,在manifest中配e69da5e887aa3231313335323631343130323136353331333365633962置的权限android.permi ...

最新文章

  1. android写代码截屏微信,android 模仿微信头像裁剪
  2. zigzag扫描matlab,ZIGZAG扫描的MATLAB实现 | 学步园
  3. arm remapping控制输入_人形机器人实时控制系统解密,机器人足球队战胜人类不是梦?...
  4. mysql中的where,group by,having:
  5. 缺少物联网杀手级应用的运营商,到底该怎么办?
  6. NYOJ 636 世界末日
  7. 论文浅尝 | 异构图 Transformer
  8. PHP 制作通讯录(六)
  9. MySQL触发器写入Sqlseever_sqlserver 触发器实例
  10. html页面内容的收缩和展开效果,jquery简单实现网页层的展开与收缩效果
  11. HTML网页图像标签
  12. 多商户商城系统功能拆解14讲-平台端会员等级
  13. 100 bugs in Open Source C/C++ projects
  14. 关于cookie的详细讲解
  15. 支付宝架构有多牛?还没看完我就跪了...
  16. Web开发学习总结1_网络通信
  17. 简易的js获取星期几的两种方法
  18. oracle创建索引和删除索引
  19. 暗黑2魔电西格玛攻略_魔电西格玛,暗黑2最佳继承者-1949游戏测评
  20. 去中心化区块链预言机

热门文章

  1. bootstrap 页面垂直居中_bootstrap4如何实现div的水平居中以及垂直居中
  2. Linux 解压缩.xz
  3. Bill Gekas儿童摄影作品欣赏
  4. Flink的流处理与批处理
  5. 【读书】迟子建《额尔古纳河右岸》 摘录
  6. linux系统不能用投影仪,Linux连接投影仪(ubuntu)失败或显示不正常--未测试
  7. 如何使用.NET来打造一个QQ界面
  8. Matlab求分段函数的积分
  9. 武汉凭什么被列为国家超大城市?
  10. 苏嵌//张福辉//2018.7.11