• Android存储访问及目录


    Android的外部存储

      Android支持外部存储(case-insensitive filesystem with immutable POSIX permission classes and modes)。

      外部存储可以通过物理介质提供(如SD卡),也可以通过将内部存储中的一部分封装而成,设备可以有多个外部存储实例。

    访问外部存储的权限

      从Android 1.0开始,写操作受权限WRITE_EXTERNAL_STORAGE保护。

      从Android 4.1开始,读操作受权限READ_EXTERNAL_STORAGE保护。

      从Android 4.4开始,应用可以管理在它外部存储上的特定包名目录,而不用获取WRITE_EXTERNAL_STORAGE权限。

      比如,一个包名为com.example.foo的应用,可以自由访问外存上的Android/data/com.example.foo/目录。

      外部存储对数据提供的保护较少,所以系统不应该存储敏感数据在外部存储上。

      特别地,配置和log文件应该存储在内部存储中,这样它们可以被有效地保护。

      对于多用户的情况,一般每个用户都会有自己独立的外部存储,应用仅对当前用户的外部存储有访问权限。

    Environment API的目录

      getDataDirectory():用户数据目录。

      getDownloadCacheDirectory():下载缓存内容目录。

      getExternalStorageDirectory():主要的外部存储目录。

      但是这个目录很可能当前不能访问,比如这个目录被用户的PC挂载,或者从设备中移除,或者其他问题发生,你可以通过getExternalStorageState()来获取当前状态。

      还有多用户或者多外部存储的情况,此文不再讨论。

      为了不污染用户的根命名空间,一般不会直接使用这个外部存储的根目录。

      任何应用私有的文件的应该被放置在 Context.getExternalFilesDir返回的目录下,在应用被卸载的时候,系统会清理的就是这个目录。

      另一些共享文件应该被放置在 getExternalStoragePublicDirectory(String)返回的目录中。

      写这个路径需要 WRITE_EXTERNAL_STORAGE权限,读需要 READ_EXTERNAL_STORAGE权限,当然写权限默认包含了读权限。

      KITKAT 即Android 4.4开始,如果你的应用只是需要存储一些内部数据,可以考虑使用 :

      getExternalFilesDir(String)或者getExternalCacheDir(),它们不需要获取权限。

      getExternalStoragePublicDirectory(String type)这个方法接收一个参数,表明目录所放的文件的类型,传入的参数是Environment类中的DIRECTORY_XXX静态变量,比如DIRECTORY_DCIM等。

      注意:传入的类型参数不能是null,返回的目录路径有可能不存在,所以必须在使用之前确认一下,比如使用File.mkdirs创建该路径。

      getRootDirectory()得到Android的根目录。

      isExternalStorageEmulated()设备的外存是否是用内存模拟的,是则返回true。(API Level 11)

      isExternalStorageRemovable()设备的外存是否是可以拆卸的,比如SD卡,是则返回true。(API Level 9)

    Context API中的目录

      getExternalFilesDir(String type)是应用在外部存储上的目录。

      和Environment类的getExternalStoragePublicDirectory(String type)方法类似,返回包含参数指定的特定类型文件的子目录。

      getExternalCacheDir()是应用的在外部存储上的缓存目录。

       从Android 4.4这两个方法不需要读写权限,是针对于本应用来说,如果要访问其他应用的相关目录,还是需要声明读写权限。

      Android 4.4之前的版本要访问的话还是要声明读写权限的,如果没有在manifest中写权限,上面两个get方法都会返回null。

      与上面两个方法形成对比的是下面两个方法:

      getFilesDir() 

      getCacheDir()

      这两个方法得到的是内存上的目录。

      这些目录都是属于应用的,当应用被卸载的时候,里面的内容都会被移除,但是不要依赖于系统的操作。

    测试代码

    复制代码
    package com.mengdd.utils.android;
    
    import android.content.Context;
    import android.os.Environment;
    
    public class DirectoryUtils {
    
        private static final String LOG_TAG = "DirectoryUtils";
    
        public static void getEnvironmentDirectories() {
            LogUtils.i(LOG_TAG, "getRootDirectory(): "
                    + Environment.getRootDirectory().toString());
            LogUtils.i(LOG_TAG, "getDataDirectory(): "
                    + Environment.getDataDirectory().toString());
            LogUtils.i(LOG_TAG, "getDownloadCacheDirectory(): "
                    + Environment.getDownloadCacheDirectory().toString());
            LogUtils.i(LOG_TAG, "getExternalStorageDirectory(): "
                    + Environment.getExternalStorageDirectory().toString());
    
            LogUtils.i(
                    LOG_TAG,
                    "getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES): "
                            + Environment.getExternalStoragePublicDirectory(
                                    Environment.DIRECTORY_PICTURES).toString());
    
    //        LogUtils.i(
    //                LOG_TAG,
    //                "isExternalStorageEmulated(): "
    //                        + Environment.isExternalStorageEmulated());
    //
    //        LogUtils.i(
    //                LOG_TAG,
    //                "isExternalStorageRemovable(): "
    //                        + Environment.isExternalStorageRemovable());
    
        }
    
        public static void getApplicationDirectories(Context context) {
    
            LogUtils.i(LOG_TAG, "context.getFilesDir(): "
                    + context.getFilesDir().toString());
            LogUtils.i(LOG_TAG, "context.getCacheDir(): "
                    + context.getCacheDir().toString());
    
            // methods below will return null if the permissions denied
            LogUtils.i(
                    LOG_TAG,
                    "context.getExternalFilesDir(Environment.DIRECTORY_MOVIES): "
                            + context
                                    .getExternalFilesDir(Environment.DIRECTORY_MOVIES));
    
            LogUtils.i(
                    LOG_TAG,
                    "context.getExternalCacheDir(): "
                            + context.getExternalCacheDir());
        }
    }
    复制代码

      在MI 2S上输出Log:

      在三星S5660上(API Level 9,注释掉了两个方法):

    参考资料

      android.os.Environment

      http://developer.android.com/reference/android/os/Environment.html

      External Storage Technical Information

      http://source.android.com/devices/tech/storage/

      Context

      http://developer.android.com/reference/android/content/Context.html

  • 相关阅读:
    命令行界面下用户和组管理之groupadd的使用
    vue数据更新UI不刷新显示解决方案
    传入函数作为string.replace方法的第二个参数应用
    CSS 黑魔法-css控制图标颜色
    谈谈Web Components
    js函数组合
    “平滑滚动”效果骚操作
    BFC布局解析
    关于js构造函数return的一些解惑
    关于setTimeout和setInterval你不知道的事
  • 原文地址:https://www.cnblogs.com/exmyth/p/5125246.html
Copyright © 2020-2023  润新知