文章图片
Android开发中有五种数据持久化API:
文章图片
内部存储
|
文章图片 |
对于内部存储路径,我们一般通过以下两种方式获取,内部存储空间的获取都需要使用Context: context.getFileDir() 对应内部存储的路径为: data/data/packagename/files,但是对于有的手机如:华为,小米等获取到的路径为: data/user/0/packagename/files context.getCacheDir() 对应内部存储的路径为: data/data/packagename/cache,但是对于有的手机如:华为,小米等获取到的路径为: data/user/0/packagename/cache |
文章图片 |
|
文章图片 |
getExternalCacheDir() 对应外部存储路径:/storage/emulated/0/Android/data/packagename/cache getExternalFilesDir(String type) 对应外部存储路径:/storage/emulated/0/Android/data/packagename/files 其他: 1、Environment. getDataDirectory() = /data 这个方法是获取内部存储的根路径 2、 getFilesDir().getAbsolutePath()= /data/user/0/packname/files 这个方法是获取某个应用在内部存储中的files路径 3、 getCacheDir().getAbsolutePath()= /data/user/0/packname/cache 这个方法是获取某个应用在内部存储中的cache路径 4、 getDir(“myFile”, MODE_PRIVATE).getAbsolutePath()= /data/user/0/packname/app_myFile 这个方法是获取某个应用在内部存储中的自定义路径 5、Environment. getExternalStorageDirectory().getAbsolutePath()= /storage/emulated/0 这个方法是获取外部存储的根路径 6、Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_DCIM) = /storage/emulated/0 这个方法是获取外部存储公有目录 7、 getExternalFilesDir(“”).getAbsolutePath()= /storage/emulated/0/Android/data/packname/files 这个方法是获取某个应用在外部存储中的files路径 8、 getExternalCacheDir().getAbsolutePath()= /storage/emulated/0/Android/data/packname/cache 这个方法是获取某个应用在外部存储中的cache路径 |
文章图片 因为外部存储不一定可用,所以返回值可为空或空数组 |
File[] files; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { files = getExternalFilesDirs(Environment.MEDIA_MOUNTED); for(File file:files){ Log.e("main",file); } } | 结果: /storage/emulated/0/Android/data/packname/files/mounted /storage/B3E4-1711/Android/data/packname/files/mounted |
public static String getFilePath(Context context,String dir) { String directoryPath=""; if (MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ) {//判断外部存储是否可用 directoryPath =context.getExternalFilesDir(dir).getAbsolutePath(); }else{//没外部存储就使用内部存储directoryPath=context.getFilesDir()+File.separator+dir; } File file = new File(directoryPath); if(!file.exists()){//判断文件目录是否存在 file.mkdirs(); } return directoryPath; } |
//检测是否可用:boolean mExternalStorageAvailable = false; boolean mExternalStorageWriteable = false; /* 检查外部存储是否可读写 */void updateExternalStorageState() { String state = Environment. getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { // 可读写 mExternalStorageAvailable = mExternalStorageWriteable = true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { // 可读 mExternalStorageAvailable = true; mExternalStorageWriteable = false; } else { mExternalStorageAvailable = mExternalStorageWriteable = false; }} 或者: String externalStorageState = Environment.getExternalStorageState(); if (externalStorageState.equals(Environment.MEDIA_MOUNTED)){ //sd卡已经安装,可以进行相关文件操作 } | //监听外部存储状态 BroadcastReceiver mExternalStorageReceiver; /* 开始监听 */void startWatchingExternalStorage() { mExternalStorageReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 更新状态 updateExternalStorageState(); } }; IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_MEDIA_MOUNTED); filter.addAction(Intent.ACTION_MEDIA_REMOVED); // 动态注册广播接收器 registerReceiver(mExternalStorageReceiver, filter); updateExternalStorageState(); }/* 停止监听 */void stopWatchingExternalStorage() { // 注销广播接收器 unregisterReceiver(mExternalStorageReceiver); } |
在真机上, getExternalStorageDirectory()获取到的路径如下表所示: 系统版本结果 (注意:下面路径中的文件夹相同) 4.0/mnt/sdcard 4.1/storage/sdcard0 4.2/storage/sdcard0 4.4/storage/emulated/0 6.0/storage/emulated/0 其中sdcard/、mnt/sdcard、storage/sdcard0、storage/emulated/0、storage/emulated/legacy都是同一个路径的不同”指针“,指向的是同一个地方,只是不同Android版本的叫法不一样。 在Android版本4.2JellyBean之前,获取sdcard的路径是 /sdcard/ ,但在JellyBean版本之后的路径成为了 /sdcard/0 ,或者是 /sdcard/legacy (legacy可以是0、1、2……),这个“0”到底代表着什么含义? 这是从JellyBean版本起的一个新特征——多用户。因此为了处理单独的账户,部分目录结构必须被改变,/sdcard/legacy始终指向当前登录的用户的SD卡目录。 正因“多用户”功能的增加,内外部存储发生了以下变化: 内部存储: 原先的/data/data/其实相当于直接链接到当前用户文件夹的,变成了/data/user/0/。 外部存储:例如sd卡路径不再是/sdcard/,而是/sdcard/legacy/(legacy可以是0、1、2……),其中的“0”可以当成“设备拥有者”,或者称为“第一用户”(“第一用户”毫无疑问的是“设备所有者”,只有此用户才能创建额外账户)。 参考: Android | 文件存储看这篇就够了 彻底搞懂Android文件存储 Android内、外存储 易混淆点剖析(/mnt/sdcard、/storage/sdcard0、/storage/emulated/0等区别) 一篇文章搞懂android存储目录结构