Android的文件基础知识

内部存储和外部存储

在这里插入图片描述

在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的时候不能打开此文件夹。

  1. data/app/

存放所有用户安装的apk文件,不包括系统默认应用文件

  1. 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文件存储目录
  1. /data/misc/

这里存放着大部分的WIFI、VPN信息。

  1. /data/user/0/

/data/data目录实际上软连接到/data/user/0目录,相当于/data/data目录是一个指针指向
/data/user/0目录.

在Android4.2之后,Android推出了一个“多用户”的功能特征,意味着一台设备可能被多个人同时应用,因此需要将每个人的数据、应用、个性配置分开。为了区别数据就用数字来区别多用户,这里的0就是指第一个用户

软连接可用看Linux软连接和硬链接

system

Android系统文件,需要root权限

  1. /system/app/

这里存放一些系统的app

  1. /system/fonts/ 目录

这里存放系统的字体文件

  1. /system/lib/ 目录

这里存放的几乎是所有的共享库(.so)文件。

  1. /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之获取storage 手机存储容量

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

猜你喜欢

转载自blog.csdn.net/lichukuan/article/details/126474636