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

时间: 2024-12-10 15:45:35

Android存储访问及目录的相关文章

android存储访问框架Storage Access Framework

在了解storage access framework 之前,我们先来看看android4.4中的一个特性.如果我们希望能选择android手机中的一张图片,通常都是发送一个Intent给相应的程序,一般这个程序是系统自带的图库应用(如果你的手机中有两个图库类的app 很可能会叫你选择一个),这个Intent一般是这样写的: Intent intent=new Intent(Intent.ACTION_GET_CONTENT);//ACTION_OPEN_DOCUMENT intent.addC

一篇文章搞懂android存储目录结构

前言 前两天因为开发一个app更新的功能,我将从服务器下载的apk文件放在了内部存储目录(测试手机为小米,路径为:data/user/0/packagename/files)下面,然后安装的时候一直安装不了,提示解析包出错.后来查询发现,安装apk是调用了PackageInstaller,没有相关权限,这个无法获取内部路径,所以会安装不了.借机也复习了一遍Android下面存储相关的知识点,特来总结一番. 存储分类 对于Android存储目录,我总结成一张思维导图,如果有需要原图的,请在我的公众

android访问asset目录下的资源

android提供了AssetManager来访问asset目录下的资源, 在activity中通过getAssets()获取AssetManager 常用的api如下: 1.列举路径下的资源String[] list(String path) 2.InputStream open(asset目录下的资源路径) 下面是放问asset目录下的图片的代码 package com.example.qunzheng.customerview; import android.app.Activity; i

Android 存储目录

Android 存储目录总结:https://www.jianshu.com/p/9528329d4787 Android内.外存储 易混淆点剖析(/mnt/sdcard./storage/sdcard0./storage/emulated/0等区别): https://blog.csdn.net/ITermeng/article/details/79423035 原文地址:https://www.cnblogs.com/pomodoro/p/12660460.html

2015年最新Android基础入门教程目录(完结版)

2015年最新Android基础入门教程目录(完结版) 标签(空格分隔): Android基础入门教程 前言: 关于<2015年最新Android基础入门教程目录>终于在今天落下了帷幕,全套教程 共148节已编写完毕,附上目录,关于教程的由来,笔者的情况和自学心得,资源分享 以及一些疑问等可戳:<2015最新Android基础入门教程>完结散花~ 下面是本系列教程的完整目录: 第一章:环境搭建与开发相关(已完结 10/10) Android基础入门教程--1.1 背景相关与系统架构

Android存储子系统

这篇文章主要是分析Android存储向关联的一些模块,这个分析主要从大的工作流程和代码模块分析,没有对于没有分析到地方后续遇到后在详细分析.主要从以下几个模块分析 系统分区的挂载.外部分区挂载.Vold守候进程分.MountService的业务分析.Sdcard的详细分析.MTP模式分析和设备存储空间的监控机制. 系统分区挂载 Android是基于linux内核的系统,遵从linux的文件系统的挂载方式.在Android中在init进程负责挂载常用的system,data,cache等分区.In

Android存储选择

最近翻译了一篇Android Developer上的文章,文章的原路径是Storage Options.这篇文章说的是Android中的存储选择. Android为我们提供了几种存储稳固的应用数据的选择.你选择的方法取决于你的具体的需求,例如数据是否应该是对于当前应用是私有的或者对于其他的应用是可访问的,还有你的数据需要多大的空间. 你的数据存储方式如下: Shared Preferences: 用key-value的方式存储基本的私有数据. Internal Storage:(内部存储) 在设

SEAndroid安全机制对Android属性访问的保护分析

Android系统通过属性暴露设备和运行时信息,并且可以通过设置属性来控制系统行为.因此,属性也像文件一样,是一种需要保护的资源.在启用SEAndroid之前,敏感属性只能被预先设定的进程进行设置.启用SEAndroid之后,敏感属性会进一步被SEAndroid安全策略保护.这样就可以更有效地保护系统属性了.在本文中,我们就详细分析SEAndroid安全机制对Android属性设置保护提供的支持. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 在分析SE

Android多媒体访问

Android的多媒体文件主要存储在/data/data/com.android.providers.media/databases目录下,该目录下有两个db文件,一个是内部存储数据库文件(internal.db),一个是存储卡数据库(external-XXXX.db).媒体文件的操作主要是围绕着这两个数据库来进行.这两个数据库的结构是完全一模一样的. Android提供了MediaStore类,该类是一个ContentProvider,管理着设备上自带的和外部的多媒体文件,同时包含着每一个多媒