文档章节

Android存储访问及目录

猴亮屏
 猴亮屏
发布于 2017/07/06 15:27
字数 1268
阅读 23
收藏 0

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等,如下:

在Environment中还提供了Android标准目录的路径,以String类型提供。
DIRECTORY_ALARMS 系统提醒铃声存放的标准目录。
DIRECTORY_DCIM 相机拍摄照片和视频的标准目录。
DIRECTORY_DOWNLOADS 下载的标准目录。
DIRECTORY_MOVIES 电影存放的标准目录。
DIRECTORY_MUSIC 音乐存放的标准目录。
DIRECTORY_NOTIFICATIONS 系统通知铃声存放的标准目录。
DIRECTORY_PICTURES 图片存放的标准目录
DIRECTORY_PODCASTS 系统广播存放的标准目录。
DIRECTORY_RINGTONES 系统铃声存放的标准目录。

  注意:传入的类型参数不能是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()

  这两个方法得到的是内存上的目录,并且只允许app本身来访问,所以当文件保存在这里时,其他外部的程序,包括系统程序(如系统相机)都不可访问。

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

 

测试代码

复制代码

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());
    }
}

参考资料:

http://www.2cto.com/kf/201408/327215.html

http://www.cnblogs.com/mengdd/p/3742623.html(圣骑士的博客,我最喜欢的博客之一,我的黄油刀也是从他博客上学的,真心感谢🙏)

© 著作权归作者所有

共有 人打赏支持
猴亮屏

猴亮屏

粉丝 35
博文 517
码字总数 56802
作品 4
北京
Android工程师

暂无文章

计算卷积神经网络浮点数运算量

前言 本文主要是介绍了,给定一个卷积神经网络的配置之后,如何大概估算它的浮点数运算量。 相关代码:CalFlops,基于MXNet框架的 Scala 接口实现的一个计算MXNet网络模型运算量的demo。 正文...

Ldpe2G
今天
1
0
Sql语言与MySql数据库

1. 数据库简介 1. 数据库,就是存储数据的仓库,只能通过sql语言来访问,数据库也是一个文件系统。通常,MySQL、Oracle等数据库,也被称为关系型数据库,其保存的不仅仅只是数据,还包括数据...

江左煤郎
今天
1
0
IDEA 取消自动import .*

打开设置 > Editor > Code Style > Java > Scheme Default > Imports ① 将 Class count to use import with "*" 改为 99 (导入同一个包的类超过这个数值自动变为 * ) ② 将 Names count ......

乔老哥
今天
3
0
PostGIS学习笔记(开篇)

PostGIS事实上算是笔者开始写博客的第一篇内容。而事实上那篇博文的内容并不丰富,笔者对PostGIS的了解仍然不多,然而17年在OSGeo课程学习时对PostGIS又有了进一步了解,并逐步发现它的强大。...

胖胖雕
今天
3
0
【Centos】在nginx服务器中配置php和mysql

接上一章《【Centos】利用Vultr服务器和namesilo布网》(https://my.oschina.net/u/3776619/blog/2051986),在Centos中配置好nginx,并在iptables中开启了80端口,和为了远程mysql操作方便开...

yongh701
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部