Android存储权限梳理及api接口调用

Android存储权限梳理及api接口调用

背景

Android开发中需要了解android 存储权限管理和对应的api使用逻辑。

概述

Android系统的文件存储按存储介质类型分为内部存储和外部存储,按存储目录类型分为私有目录和公共目录;对于Android系统中的进程来说,如果需要存储空间,需要按需申请对应的权限才能访问;否则是不能达到目的的。

Android文件存储分类及接口

文件操作的各种API接口及继承关系如下:

内部路径 不用权限

内部存储

  • 是否需要用户权限:

  • 是否能被气筒应用访问:

  • 卸载应用数据是否被删除:

内部存储控件不需要用户权限,这意味着不需要用户去授权android.permission.WRITE_EXTERNAL_STORAGEandroid.permission.READ_EXTERNAL_STORAGE就可以读写该目录下的文件。而且该目录下的文件不能被其他应用访问。这也就保证了应用内部存储的文件的安全性和隐私性,如果需要查看应用内部的文件,可以通过Android Studio的Device File Explore工具进行访问:

通过访问/data/data/应用包名,查看应用内部的存储文件

/data/data/应用名/cache :存放的是APP的缓存信息

/data/data/应用名/code_cache :在运行时存放应用产生的编译或者优化的代码

/data/data/应用名/files : 存放APP的文件信息

还有一些运行时,产生的文件夹,例如调用SharedPreference所产生的 /data/data/应用包名/shared_prefs 目录,存放着app的SharedPreference所产生的xml文件,还有调用数据库所产生的 **/data/data/应用包名/databases/**文件夹,这里就不一一举例。

相关API Context 类

getCacheDir

缓存路径

File getCacheDir() 返回内部存储的cache文件夹

Log.d("THINK",getCacheDir().getPath()); //data/user/0/com.example.camera/cache

getCodeCacheDir

File getCodeCacheDir() 返回内部存储的code_cache文件夹,要求Android5.0+

Log.d("THINK",getCodeCacheDir().getPath()); ///data/user/0/com.example.camera/code_cache


 

示意路径

getFilesDir

File getFilesDir() 访问内部存储的files目录

Log.d("THINK",getFilesDir().getPath()); ///data/user/0/com.example.camera/files

内部文件 文件路径

fileList

files 下的所有文件名

String[] fileList() 返回files目录下的文件名,例如files目录下有test.txt文件和test1.txt文件

 //输出 test.txt和test1.txt
    for (String item : fileList()){
            Log.d("THINK",item);
    }

相关的openFileInput和openFileOutput就是直接在files文件夹读写某个文件:

openFileOutput

FileOutputStream openFileOutput() 写文件到files目录下:

try {
        FileOutputStream outputStream = openFileOutput("test.txt", Context.MODE_PRIVATE);
        outputStream.write("this is test content".getBytes());
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

此时file目录下就会多了一个test.txt文件

openFileInput

FileInputStream openFileInput() 读files目录下文件,例如我们读刚刚写入的test.txt文件

// 输出:this is test content
    try {
        FileInputStream fileInputStream = openFileInput("test.txt");
        byte[] bytes = new byte[1024];
        StringBuffer stringBuffer = new StringBuffer();
        int len = 0;
        while ((len=fileInputStream.read(bytes))!=-1){
            stringBuffer.append(new String(bytes,0,len));
        }
        Log.d("THINK",stringBuffer.toString());
        fileInputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }

getDataDir

不常用

File getDataDir() 返回内部存储的根文件夹,要求Android7.0+

Log.d("THINK",getDataDir().getPath()); ///data/user/0/com.example.camera

外部存储 公共目录

  • 是否需要用户权限:

  • 是否能被其他应用访问:

  • 卸载应用数据是否被删除:

公共目录 Environment 类 - 需要权限

需要在manifest xml 配置和request Permission

公共目录必须需要用户授权读写的权限,这意味着我们需要在AndroidManifest.xml中注册用户权限。

 <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

并且在Android 6.0系统之后需要申请用户权限,并获得用户授权,才能读写文件。

公共目录相对开放,我们可以访问其他APP存在公共目录下的文件,并且当APP被删除时,并不会删除应用存在公共目录下的文件。

我们可以通过Environment对象,访问读写公共目录的文件。接下来看看相关的API。

相关API Environment类

Environment类提供了丰富的访问对应公有目录下的type,可以通过Environment源码进行查看。

Environment.getExternalStorageDirectory

File Environment.getExternalStorageDirectory() 访问外部存储设备公共根目录:

  //输出:/storage/emulated/0
    Log.d("THINK",Environment.getExternalStorageDirectory().getPath()); 

注意这个不能保证该接口有效,得调用上述的state 看看状态。获取的路径就是如下:

Environment.getExternalStorageState

String Environment.getExternalStorageState() 获得外部存储SD卡的状态,在读写SD卡的时候,应该先判断一下SD卡的状态,是否能够支持读写。

具体返回值及对应的状态也可以查看Environment.getExternalStorageState的源码。

Environment.getExternalStoragePublicDirectory(String type)

具体的对应文件夹

例如:

//输出:/storage/emulated/0/Music

Log.d("THINK",Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();

外部存储 私有目录 Context类 - 不需要权限

  • 是否需要用户权限:4.4以上不需要

  • 是否能被其他应用访问:否

  • 卸载应用数据是否被删除:是

私有目录,在Android4.4系统以上。不需要注册和用户授权SD读写的权限,就可以在应用的私有目录进行读写文件。并且文件不能被其他应用所访问,具有较好的隐私性和安全性,并且在用户删除的时候,对应的应用私有目录也会被删除。

私有目录地址:/storage/emulated/0/Android/data/应用包名

相关API

私有目录下访问的API都在ContextWrapper对象上。这意味这我们可以直接在Activity中调用或者通过Context对象去调用。

getExternalCacheDir

File Context.getExternalCacheDir() 访问/storage/emulated/0/Android/data/应用包名/cache目录,该目录用来存放应用的缓存文件,当我们通过应用删除缓存文件的时候,该目录下的文件会被清除。

//输出:/storage/emulated/0/Android/data/com.example.camera/cache
    Log.d("THINK",this.getExternalCacheDir().getPath());

getExternalFilesDir

File Context.getExternalFilesDir(String type) 访问/storage/emulated/0/Android/data/应用包名/files 目录,该目录用来存放应用的数据,当我们通过应用去清除应用数据的时候,该目录下的文件会被清除。我们也可以通过type,去创建并获得对应目录下的File文件。例如:

 //创建并输出:/storage/emulated/0/Android/data/com.example.camera/files/test
    Log.d("THINK",this.getExternalFilesDir("test").getPath());
 
  File file = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsoluteFile();

使用方式和内部存储的差不多,不过路径不一样罢了。

也可以将type传为null,这时候访问的目录就是files目录,例如:

//输出:/storage/emulated/0/Android/data/com.example.camera/files
    Log.d("THINK",this.getExternalFilesDir(null).getPath());

注意版本权限

·WRITE_EXTERNAL_STORAGE在android11 之后就不再支持了。。

高版本中使用存储权限可以 用如下的配置:

READ_MEDIA_AUDIO,

READ_MEDIA_IMAGES,

READ_MEDIA_VIDEO

外部存储权限的实现可以参考之前的文档:

Android R及以上版本中APP外部存储实现_tools:ignore="selectedphotoaccess-CSDN博客

总结

开发中经常会进行文件存储,可以根据具体需求,选择合适的方案对文件进行存储,参考如下:

  • 当需要存储一些私密性和安全性比较高的小数据,例如用户的账号密码等信息,可以存放在内部存储空间上。

  • 当需要存放一些能够被其他应用也能访问的数据,并且当应用被删除的时候,不希望数据被清除的时候,可以放到外部存储的公有目录下,但别忘了申请读写SD卡的权限。

  • 当需要存放一些应用的数据和缓存数据,希望有较好的隐私性和应用被删除的时候,对应的应用数据和缓存也被删除,这时候可以选择存放在外部存储的私有目录下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/768039.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【力扣 - 每日一题】3099. 哈沙德数 | 模拟 (Go/C++)

题目内容 如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&#xff09;。给你一个整数 x 。如果 x 是 哈沙德数 &#xff0c;则返回 x 各个数位上的数字之和&#xff0c;否则&#xff0c;返回 -1 。 示例 1&#xff1…

修改CentOS7 yum源

修改CentOS默认yum源为阿里镜像源 备份系统自带yum源配置文件 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载ailiyun的yum源配置文件 CentOS7 yum源如下&#xff1a; wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun…

按是否手工执行测试的角度划分:手工测试、自动化测试

1.手工测试&#xff08;Manual testing&#xff09; 手工测试是由人一个一个的输入用例&#xff0c;然后观察结果&#xff0c;和机器测试相对应&#xff0c;属于比较原始但是必须的一个步骤。 由专门的测试人员从用户视角来验证软件是否满足设计要求的行为。 更适用针对深度…

如何批量创建、提取和重命名文件夹!!!

你是否还在一个一个手动创建文件名&#xff01; 你是否还在一个一个手动提取文件名&#xff01; 你是否还在一个一个手动修改文件名&#xff01; 请随小生一起批量自动创建、提取、重命名&#xff01; 1、批量创建文件夹 【案例】创建1日-31日共31个文件夹 【第一步】在A列…

Atom CMS v2.0 SQL 注入漏洞(CVE-2022-25488)

前言 CVE-2022-25488 是一个发现于 Telesquare SDT-CW3B1 设备中的命令注入漏洞。这一漏洞可以被未经认证的远程攻击者利用&#xff0c;通过特殊构造的 HTTP 请求在设备上执行任意命令。以下是关于该漏洞的详细信息&#xff1a; 漏洞详细信息 漏洞编号: CVE-2022-25488影响范…

统一开放平台实现方案(访微信SDK)

需求分析 在互联中&#xff0c;我们的服务是不对外开放的&#xff0c;但是有先场景下我们可以对外开放&#xff0c;但是必须是系统所允许的用户才可以&#xff0c;这样做一方面保证安全&#xff0c;另一方面可以提升平台的能力&#xff0c;比如调用微信的接口必须要进行微信开…

统计信号处理基础 习题解答11-11

题目 考虑矢量MAP估计量 证明这个估计量对于代价函数 使贝叶斯风险最小。其中&#xff1a;, &#xff0c;且. 解答 贝叶斯风险函数&#xff1a; 基于概率密度的非负特性&#xff0c;上述对积分要求最小&#xff0c;那就需要内层积分达到最小。令内层积分为&#xff1a; 上述积…

为什么网上商店需要翻译成其他语言

网上商店不仅仅是一个可以买到商品的网站。它是一个完整的电子商务平台&#xff0c;为来自世界各地的用户提供购买所需物品的机会。但是&#xff0c;为了让这些用户舒适地使用网站&#xff0c;需要高质量的翻译和本地化。 本地化是指产品或服务适应特定文化或市场的过程。它包…

匠心独运:红酒与手工艺的很好结合

在岁月的长河中&#xff0c;红酒与手工艺都以其不同的魅力和技艺&#xff0c;书写着各自的故事。当这两者相遇&#xff0c;仿佛是一场跨越时空的对话&#xff0c;不仅展现了匠心独运的技艺之美&#xff0c;更在无声中诉说着对品质与生活的热爱。今天&#xff0c;就让我们一起探…

「算法题」二分查找算法演示

一个样式更加美观大方的HTML页面示例,其中包括了二分查找算法的演示。 布局描述 页面主体使用白色背景,加上轻微的阴影和圆角边框,使页面看起来更加精致。输入框和按钮使用了更加现代的样式,包括圆角边框和悬浮效果。按钮使用了鲜明的颜色,以吸引用户点击。搜索结果显示时…

html+js+css登录注册界面

拥有向服务器发送登录或注册数据并接收返回数据的功能 点赞关注 界面 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>Login and Registration Form</title> <style> * …

linux命令行操作

一、看二进制文件 od -t x1 1.txt | less 二、看信号 kill -l man 7 signal 三、查看当前进程的pid号 echo $$

44.实现管理HOOK点的链表对象

上一个内容&#xff1a;43.实现HOOK接管寄存器数据 以 43.实现HOOK接管寄存器数据 它的代码为基础进行修改 首先创建一个类 这里创建的名为HOOKPOINT.h HOOKPOINT.cpp文件里面的内容 #include "pch.h" #include "HOOKPOINT.h"HOOKPOINT::HOOKPOINT() {…

钉钉机器人接入Dify工作流

实现钉钉机器人接入dify工作流&#xff0c;完成ai 流式问答 代码地址 有用的话点个star github地址 效果 配置使用 修改.env_template文件 为.env 设置.env文件内的环境变量 API_KEY: dify的api_keyAPI_URL: dify 的api接口CLIENT_ID : 钉钉机器人应用的idCLIENT_SECRET:钉…

Arthas实战(1)- 运行Arthas

1. 下载Arthas 下载到服务器&#xff1a; wget https://github.com/alibaba/arthas/releases/download/arthas-all-3.7.1/arthas-bin.zip解压 Arthas unzip arthas-bin.zip -d arthas删除压缩包 rm -f arthas-bin.zip 2. 启动Arthas 运行 Arthas java -jar arthas/arthas-bo…

高编:共享内存(key)

system v &#xff1a; 共享内存 信号量集 IPC对象操作通用框架&#xff1a; 0x ftok key值 > 申请 》读写 》关闭 》卸载 优点&#xff1a; 共享内存效率高没有读写阻塞 操作流程&#xff1a; key 》申请对象 》映射对象》读写对象》撤销映射 》删除对象…

Django 一对一关系

作用&#xff1a; 两个数据库表建立外键关系当外键表的数据被删除时&#xff0c;主表的数据也会一并删除。 1&#xff0c;添加表模型 Test/app8/views.pyfrom django.db import modelsclass User(models.Model):username models.CharField(max_length50, uniqueTrue)email …

Webpack: Dependency Graph 管理模块间依赖

概述 Dependency Graph 概念来自官网 Dependency Graph | webpack 一文&#xff0c;原文解释&#xff1a; Any time one file depends on another, webpack treats this as a dependency. This allows webpack to take non-code assets, such as images or web fonts, and als…

Steam夏促怎么注册 Steam夏促账号注册教程

随着夏日的炙热渐渐充斥着每一个角落&#xff0c;Steam平台也赶来添热闹&#xff0c;推出了一系列让人眼前一亮的夏季促销活动。如果你也是游戏爱好者&#xff0c;我们肯定不能错过这次的steam夏促。正直本次夏日促销有着很多的游戏迎来史低和新史低&#xff0c;有各种各样的游…

智慧城市大数据平台总体技术建设方案(DOC文件)

第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章 政策标准保障…