内部存储和外部存储
在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(): context.getExternalFilesDir(String type): //使用Environment来获取,需要获取权限来操作 Environment.getExternalStorageDirectory();
方法1、2不需要权限,而方法3需要申请权限,该目录的特点为:
- 系统一般不会清理在里面的文件
- 由于普通用户可能自由操作在里面的文件,使用时应该加个非空判断和异常捕获
- 获取
WRITE_EXTERNAL_STORAGE
的其他应用可以操作该文件,Android 7.0以后要通过FileProvider 访问 - 自Android 4.4开始,App 才可以直接读写外部存储空间中的应用私有目录,使开发人员无需在 Manifest 文件中或者动态申请外部存储空间的文件读写权限。
- 随应用卸载后删除
外部储存的公共目录
Environment.getExternalStoragePublicDirectory(String type);
获取外部空间和内部空间总大小和可用大小
Android多媒体数据信息
转载自Android 多媒体:MediaProvider、MediaStore
MediaProvider就是Android系统中的一个数据库,又称多媒体数据库,保存了手机上存储的所有文件的信息。这个数据库存放在/data/data/com.android.providers.media/databases当中,里面有两个数据库:internal.db和external.db,internal.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
来源地址:https://blog.csdn.net/lichukuan/article/details/126474636