Android的文件基础知识
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
内部存储和外部存储
在Android4.4以前内部存储Internal Storage就是指手机机身存储而外部存储External Storage则指外置SD卡。
而在Android4.4及以后在没有外置SD卡的情况下机身存储分为了内部存储Internal Storage和外部存储External Storage如果加上外置SD卡则外置SD卡和机身存储的外部存储都算作外部存储External Storage
//在Android4.4及以后提供了getExternalFilesDirs方法来获取所有的外置存储
File[] files = getExternalFilesDirs("");
Android系统中的文件夹
data目录
/data
目录就是所谓的内部存储(ROM),但是当手机没有root的时候不能打开此文件夹。
- data/app/
存放所有用户安装的apk文件不包括系统默认应用文件
- data/data/包名/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jv9LwiLm-1661177297780)(https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/3/29/171257f84ba6265b~tplv-t2oaga2asx-image.image)]
每个应用的数据都存放在以包名为命名的文件夹下如图:
- cache:缓存目录
- databases:数据库目录
- files:文件存储目录
- shared_prefs:SharedPreferences文件存储目录
- /data/misc/
这里存放着大部分的WIFI、VPN信息。
- /data/user/0/
/data/data
目录实际上软连接到/data/user/0
目录相当于/data/data
目录是一个指针指向
/data/user/0
目录.
在Android4.2之后Android推出了一个“多用户”的功能特征意味着一台设备可能被多个人同时应用因此需要将每个人的数据、应用、个性配置分开。为了区别数据就用数字来区别多用户这里的0就是指第一个用户
软连接可用看Linux软连接和硬链接
system
Android系统文件需要root权限
- /system/app/
这里存放一些系统的app
- /system/fonts/ 目录
这里存放系统的字体文件
- /system/lib/ 目录
这里存放的几乎是所有的共享库(.so)文件。
- /system/media/ 目录
这里用来保存系统铃声、系统提示音。
storage
storage
目录就是外部存储包括了机身内部存储和外置SD卡。注意不同的版本存储数据的位置不同例如
Androidr4.4.2 带SD卡(没有Android4.4的手机数据来自网络)
位置 | 路径 | 获取路径的api |
---|---|---|
机身外部存储 | /storage/emulated/0/Android/data/packname/files | getExternalStorageDirectory() |
外置SD卡 | /storage/sdcard1 | getExternalFilesDirs() |
Android 8 小米
位置 | 路径 | 获取路径的api |
---|---|---|
机身外部存储 | /storage/emulated/0/Android/data/packname/files | getExternalStorageDirectory() |
外置SD卡 | /storage/sd_name | getExternalFilesDirs() |
sdcard
详情看Android内、外存储易混淆点剖析/mnt/sdcard、/storage/sdcard0、/storage/emulated/0等区别
获取Andorid中的目录
以下api返回的值均为Android O下返回的值
内部储存目录
//创建/data/user/0/packagename/files文件夹随着应用位置的改变位置可能改变
context.getFilesDir();
//创建/data/user/0/packagename/cache文件夹当需要空间时
//系统会自动删除其中的文件先删除存在最长时间的
context.getCacheDir();
// 获取 /data 目录
Environment.getDataDirectory()
注意读写上述的方法返回的文件对象是不用申请权限当用户卸载app时系统会删除data/data目录下所有关于该app的文件
外部储存的私有目录
//一般存放临时缓存数据对应 清除缓存
//目录为 /storage/emulated/0/Android/data/packagename/cache
context.getExternalCacheDir()
/**
*一般放一些长时间保存的数据对应 清除数据
*type的取值
*null /storage/emulated/0/Android/data/com.example.androidbase/files
*DIRECTORY_MUSIC *Environment.DIRECTORY_MUSIC时/storage/emulated/0/Android/data/com.example.androidbase/file*s/Music
* DIRECTORY_PODCASTS
* DIRECTORY_RINGTONES
* DIRECTORY_ALARMS
* DIRECTORY_NOTIFICATIONS
* DIRECTORY_PICTURES
* DIRECTORY_MOVIES
* 自定义字符串:/storage/emulated/0/Android/data/com.example.androidbase/files/自定义字符串
*/
context.getExternalFilesDir(String type)
//使用Environment来获取需要获取权限来操作
Environment.getExternalStorageDirectory();
方法1、2不需要权限而方法3需要申请权限该目录的特点为
- 系统一般不会清理在里面的文件
- 由于普通用户可能自由操作在里面的文件使用时应该加个非空判断和异常捕获
- 获取
WRITE_EXTERNAL_STORAGE
的其他应用可以操作该文件Android 7.0以后要通过FileProvider 访问 - 自Android 4.4开始App 才可以直接读写外部存储空间中的应用私有目录使开发人员无需在 Manifest 文件中或者动态申请外部存储空间的文件读写权限。
- 随应用卸载后删除
外部储存的公共目录
/**
* 需要申请权限
* Type的值看上面不能为null,注意要创建文件时不能使用 File的 mkdir() 和 mkdirs() 方法它们只会创建目录可以使用
*createNewFile()或者不使用 都可以创建文件
*空字符串时/storage/emulated/0
*自定义字符串/storage/emulated/0/自定义字符串
*/
Environment.getExternalStoragePublicDirectory(String type);
获取外部空间和内部空间总大小和可用大小
Android多媒体数据信息
转载自Android 多媒体MediaProvider、MediaStore
MediaProvider就是Android系统中的一个数据库又称多媒体数据库保存了手机上存储的所有文件的信息。这个数据库存放在/data/data/com.android.providers.media/databases当中里面有两个数据库internal.db和external.dbinternal.db存放的是系统分区的文件信息开发者是没法通过接口获得其中的信息的而external.db存放的则是我们用户能看到的存储区的文件信息即包含了手机内置存储还包含了SD卡。
MediaStore提供了在内部和外部存储设备上所有可用媒体的元数据。
MediaStore内部类
- class MediaStore.Audio:所有音频内容的容器
- class MediaStore.Files:MediaProvider表包含媒体存储中所有文件的索引包括非媒体文件
- class MediaStore.Images:所有图片内容的容器
- interface MediaStore.MediaColumns:MediaProvider表的公共字段
- class MediaStore.Video:所有视频内容的容器
MediaStore.MediaColumns字段说明
- String DATA磁盘上文件的路径
- String DATE_ADDED文件添加到media provider的时间单位秒
- String DATE_MODIFIED文件最后一次修改单元的时间
- String DISPLAY_NAME文件的显示名称
- String HEIGHT图像/视频的高度以像素为单位
- String MIME_TYPE文件的MIME类型
- String SIZE文件的字节大小
- String TITLE标题
- String WIDTH图像/视频的宽度以像素为单位。
实战
仿QQ本地图片选择器
String[] columns = {MediaStore.Images.Media._ID, MediaStore.Images.Thumbnails.DATA, MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,MediaStore.MediaColumns.MIME_TYPE,MediaStore.MediaColumns.SIZE
};
String sortOrder = MediaStore.Images.Media.DATE_ADDED+" desc";
Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, sortOrder);
LinkedHashMap<String,List<ImageBean>> map = new LinkedHashMap<>();
while (cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID));
String thumbnailsPath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA));
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
String groupId = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_ID));
String groupName = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME));
String type = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
String size = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.SIZE));
ImageBean imageBean = new
ImageBean(id,thumbnailsPath,path,groupId,groupName,type,size);
if (map.containsKey(groupId)){
map.get(groupId).add(imageBean);
}else {
ImageGroupBean imageGroupBean = new ImageGroupBean(groupId,groupName,path);
group.add(imageGroupBean);
List<ImageBean> l = new ArrayList<>();
l.add(imageBean);
map.put(groupId,l);
}
}
cursor.close();
效果如图
参考
- https://blog.csdn.net/csdn_aiyang/article/details/80665185
- https://blog.csdn.net/dongyaqin/java/article/details/88947467
- https://blog.csdn.net/qq_39074954/java/article/details/97613088
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |