Android系统 应用存储路径与权限

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
简介: Android系统 应用存储路径与权限

Android系统 文件访问权限笔记

Android系统 理解/sys/目录权限和UID和GID?

Android系统 应用存储路径与权限

Android系统 自定义系统和应用权限

Android系统 AppOps默认授予应用相应的权限

Android系统 权限组管理和兼容性


数据和文件存储概览 | Android 开发者 | Android Developers..

Android应用的存储路径分为内部和外部存储。内部存储固定且小,外部存储如SD卡容量大但可能不稳定。应用在这两种存储中都有私有目录,仅该应用可访问且随应用卸载而删除。外部存储的公共目录可被其他应用访问,且不随应用卸载而删除。

存储类型 特点 是否私有 是否随应用卸载删除 是否可被其他应用访问
内部存储 固定且容量小
外部存储(专属目录) 容量大,可能不稳定
外部存储(公共目录) 容量大,可能不稳定

Android应用的文件访问能力基于其请求的权限。与存储相关的权限有READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE和MANAGE_EXTERNAL_STORAGE。Android 10及以上版本引入了分区存储,限制应用只能访问其专属目录和特定媒体文件。

权限名称 功能描述 Android 10及以上版本的特点
READ_EXTERNAL_STORAGE 读取外部存储中的文件 只能访问专属目录和特定媒体文件
WRITE_EXTERNAL_STORAGE 写入外部存储中的文件 只能访问专属目录和特定媒体文件
MANAGE_EXTERNAL_STORAGE 管理外部存储的文件 可以访问和管理所有文件

Android文件系统和目录结构

Android有特殊类型的应用,根据其存储路径和权限不同,分为系统预装应用、特权系统应用、用户安装应用和平台签名应用。它们的存储位置和权限级别各不相同。

这些特殊类型的应用包括:

应用类型 存储路径 权限级别 是否可被用户卸载 特点
系统预装应用 /system/app 系统预装
特权系统应用 /system/priv-app 最高 系统预装、且具有特权签名
用户安装应用 /data/app 普通 通过商店或手动安装
平台签名应用 /system/app/system/priv-app 高至最高 取决于存储位置 使用与系统相同的签名密钥
Android文件系统概述

Android文件系统是一种基于Linux的文件系统,它用于管理设备上的文件和目录。Android文件系统可以分为两个主要部分:系统分区和数据分区。系统分区是指存储设备上的一块固定大小的空间,它用于存储Android系统的核心组件,如内核,引导加载器,恢复模式,系统应用等。数据分区是指存储设备上的剩余空间,它用于存储用户数据,如应用,照片,音乐,文档等。

Android目录结构和主要目录的作用

Android文件系统包含多个主要目录,如根目录、系统分区、数据分区、外部存储、缓存和设备文件目录。每个目录都有其特定的作用和访问权限。

目录名称 描述 访问权限 主要用途
/ 根目录 取决于子目录 所有其他目录的父目录
/system 系统分区根目录 通常只读 (除非有root权限 umount) 存储Android系统核心组件和配置
/data 数据分区根目录 可读写 (需要权限) 存储用户数据和应用数据
/sdcard 外部存储根目录 可读写 (需要权限) 存储用户在外部存储的文件
/cache 临时缓存目录 可读写 存储临时文件,如更新包
/dev 设备文件目录 通常只读 (需要特殊权限) 表示设备上的硬件

此外,还有其他目录如/proc/sys/mnt等,用于特定的系统任务和功能。

/system/app目录的作用和特性

/system/app目录存储系统预装或通过刷机安装的应用。这些应用具有高权限,不可被用户卸载,且在设备启动时自动加载。它们通常使用系统签名,不需申请运行时权限,并可通过sharedUserId共享数据。安装应用到此目录可以通过adb命令或刷机包。

特性/操作 描述
目录作用与特性
访问权限 通常只读,需要root/remount权限进行修改
加载时机 设备启动时自动加载
权限与API 可访问系统保护的权限和API
文件访问 可访问所有文件和目录
应用特点
签名 通常使用与系统相同的签名
权限请求 使用AndroidManifest.xml声明,无需运行时权限
数据共享 使用sharedUserId共享UID和进程空间
安装方法
使用adb 使用adb命令复制应用到目录,修改权限和所有者
预置 系统打包固件的时候预置进系统

/system/priv-app目录的作用和特性

/system/priv-app目录存储具有特权签名的系统预装或刷机安装应用。这些应用具有最高权限,不可被用户卸载。它们在设备启动时加载,可访问所有权限/API,并通常使用系统签名。

/data/app目录的作用和特性

特性/操作 描述
目录作用与特性
访问权限 通常只读,需要root或刷机操作进行修改
加载时机 设备启动时自动加载
权限与API 可访问所有权限和API,包括特权权限
文件访问 可访问所有文件和目录
应用特点
签名 必须使用与系统相同的签名,并声明android:sharedUserId="android.uid.system"
权限请求 可直接使用任何权限,无需声明
数据共享 使用sharedUserId共享UID和进程空间
安装方法
使用adb 使用adb命令复制应用到目录,修改权限和所有者
预置 系统打包固件的时候预置进系统

/data/app目录存储用户通过商店或其他渠道安装的应用。这些应用具有普通权限,可被用户卸载。它们在安装或更新时加载,可访问普通权限/API,但需申请运行时权限。

特性/操作 描述
目录作用与特性
访问权限 可读写,需root或adb shell权限
加载时机 用户安装或更新时加载
权限与API 可访问普通权限/API,不可访问系统保护权限
文件访问 可访问专属目录/特定媒体,需特权或SAF访问其他
应用特点
签名 使用自己的签名密钥
权限请求 需声明和申请运行时权限
数据共享 通常不使用sharedUserId共享UID/进程空间
安装方法
商店/其他渠道 使用Google Play等商店安装应用
使用adb 使用adb命令复制应用到目录,修改权限和所有者
预置 系统打包固件的时候预置进系统

平台签名的app使用与系统相同的签名密钥,允许它们访问特权权限和API。这些应用通常位于/system/app/system/priv-app。它们可以直接使用任何权限,不需申请运行时权限,并可能使用sharedUserId共享数据。

平台签名的app的权限特性

特性/操作 描述
权限特性
权限与API 可访问所有权限和API,包括特权权限
权限请求 不需使用AndroidManifest.xml声明或申请运行时权限
数据共享 使用sharedUserId共享UID和进程空间
请求与使用方法
使用AndroidManifest.xml 声明所需权限,无需用户授权
使用代码 直接调用API,无需权限检查

普通app的权限特性

普通app是指使用自己的签名密钥签名的应用,它们没有任何特殊的存储路径或者权限特性。这些应用可以存储在任何目录中,但是通常存储在/data/app中。例如,一些自己开发或者下载的应用,都是普通app。

普通app的权限特性有以下几点:

  • 普通app可以访问一些普通的权限和API,例如访问网络,读取位置,拍照等。但是它们不能访问一些系统保护的权限和API,例如修改系统设置,访问电话状态,读取联系人等。
  • 普通app需要使用AndroidManifest.xml文件中声明的权限和运行时权限来请求和使用权限。运行时权限是指一些敏感的权限,它们需要在应用运行时向用户申请授权才能使用。例如,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE等。
  • 普通app通常不使用AndroidManifest.xml文件中声明的sharedUserId属性来共享UID和进程空间的,因为这样会增加安全风险和兼容性问题。

普通app如何请求和使用权限呢?有以下几种方法:

  • 使用AndroidManifest.xml文件:需要在AndroidManifest.xml文件中声明想要使用的权限,并且根据不同版本的Android系统来申请运行时权限。例如,如果想要使用READ_EXTERNAL_STORAGE权限,需要在AndroidManifest.xml文件中添加以下代码:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 使用代码:需要在代码中检查并申请运行时权限,并且处理用户的授权结果。例如,如果想要读取外部存储空间中的文件,需要在代码中使用以下代码:
// 定义一个常量作为请求码
private static final int REQUEST_CODE_READ_EXTERNAL_STORAGE = 1;
// 检查是否已经有READ_EXTERNAL_STORAGE权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
    // 如果已经有了,直接读取文件
    readFileFromExternalStorage();
} else {
    // 如果没有,向用户申请
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_READ_EXTERNAL_STORAGE);
}
// 重写onRequestPermissionsResult方法来处理用户的授权结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    // 判断请求码是否匹配
    if (requestCode == REQUEST_CODE_READ_EXTERNAL_STORAGE) {
        // 判断授权结果是否成功
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 如果成功,读取文件
            readFileFromExternalStorage();
        } else {
            // 如果失败,提示用户
            Toast.makeText(this, "You need to grant READ_EXTERNAL_STORAGE permission to read files", Toast.LENGTH_SHORT).show();
        }
    }
}
// 定义一个方法来读取外部存储空间中的文件
private void readFileFromExternalStorage() {
    // 获取外部存储空间的根目录
    File externalStorageDirectory = Environment.getExternalStorageDirectory();
    // 创建一个文件对象表示要读取的文件
    File file = new File(externalStorageDirectory, "test.txt");
    // 创建一个输入流对象来读取文件内容
    try (FileInputStream fis = new FileInputStream(file)) {
        // 创建一个字节数组来存储文件内容
        byte[] buffer = new byte[fis.available()];
        // 将文件内容读取到字节数组中
        fis.read(buffer);
        // 将字节数组转换为字符串
        String content = new String(buffer);
        // 显示文件内容
        Toast.makeText(this, content, Toast.LENGTH_SHORT).show();
    } catch (IOException e) {
        // 处理异常情况
        e.printStackTrace();
    }
}

不同类型应用的存储路径和权限区别

不同的应用存储路径如/system/app, /system/priv-app, 和 /data/app具有不同的存储和权限特性。系统和特权应用通常存储在系统分区,具有更高的权限,而普通应用存储在数据分区,权限较低。选择应用的安装位置和权限应基于应用的类型、需求和安全性。

表格:

特性/操作 /system/app & /system/priv-app /data/app
存储特性
存储位置 系统分区 数据分区
存储方式 刷机/adb命令 商店/其他渠道
用户操作 需要root/刷机操作 用户自由安装/卸载
权限特性
权限级别 高级权限 & API 普通权限 & API
权限申请 不需运行时权限 需要运行时权限
数据共享 可使用sharedUserId 通常不使用sharedUserId
建议
权限最小化
使用普通权限
使用运行时权限
  1. 普通应用使用了系统平台签名 但不使用android:sharedUserId=“android.uid.system”:
  • 这种应用使用了与系统相同的签名密钥,因此它可以被视为一个平台签名的app。但由于它没有使用android:sharedUserId="android.uid.system",它不会具有与系统应用相同的UID,所以它不是特权应用。
  1. 普通应用使用了系统平台签名 使用android:sharedUserId=“android.uid.system”:
  • 这种应用使用了与系统相同的签名密钥并且使用了android:sharedUserId="android.uid.system",因此它可以被视为一个特权应用
  1. 普通应用如果Android源码预置到/system/app & /system/priv-app:
  • 如果预置在/system/app,它仍然是一个系统应用,但可能没有特权应用的所有权限。
  • 如果预置在/system/priv-app,它是一个特权应用,因为这个目录是为具有特权签名的应用预留的。
  1. 查看 /system/app, /system/priv-app 和 /data/app 中的应用:
  • 首先,确保你的设备已经连接到电脑并且 ADB 正在运行。
  • 打开命令行或终端。
  • 输入以下命令:
adb shell
  • 然后,你可以使用 ls 命令来查看各个目录中的内容:
ls /system/app
ls /system/priv-app
ls /data/app
  1. 区分 shareid 和签名:
  • Android 的应用可以使用相同的 sharedUserId 来共享数据和代码。这通常在 AndroidManifest.xml 文件中定义。要查看应用的 sharedUserId,你可以使用以下命令:
dumpsys package <package_name> | grep Share
其中 `<package_name>` 是你想要查询的应用的包名。
  • 对于签名,你可以使用以下命令来获取应用的签名信息:
dumpsys package <package_name> | grep Sign
  1. 注意:这些命令可能会返回大量的信息,所以你可能需要仔细查看或使用更多的 grep 命令来过滤结果。

希望这篇文章能对您有所帮助。如果还有其他问题或建议,请留言与私信。


相关实践学习
阿里云百炼xAnalyticDB PostgreSQL构建AIGC应用
通过该实验体验在阿里云百炼中构建企业专属知识库构建及应用全流程。同时体验使用ADB-PG向量检索引擎提供专属安全存储,保障企业数据隐私安全。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
12天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
12天前
|
算法 JavaScript Android开发
|
12天前
|
存储 搜索推荐 Java
打造个性化安卓应用:从设计到实现
【10月更文挑战第30天】在数字化时代,拥有一个个性化的安卓应用不仅能够提升用户体验,还能加强品牌识别度。本文将引导您了解如何从零开始设计和实现一个安卓应用,涵盖用户界面设计、功能开发和性能优化等关键环节。我们将以一个简单的记事本应用为例,展示如何通过Android Studio工具和Java语言实现基本功能,同时确保应用流畅运行。无论您是初学者还是希望提升现有技能的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧。
|
14天前
|
安全 搜索推荐 Android开发
揭秘安卓与iOS系统的差异:技术深度对比
【10月更文挑战第27天】 本文深入探讨了安卓(Android)与iOS两大移动操作系统的技术特点和用户体验差异。通过对比两者的系统架构、应用生态、用户界面、安全性等方面,揭示了为何这两种系统能够在市场中各占一席之地,并为用户提供不同的选择。文章旨在为读者提供一个全面的视角,理解两种系统的优势与局限,从而更好地根据自己的需求做出选择。
36 2
|
13天前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
13天前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
15天前
|
安全 Android开发 iOS开发
安卓系统与iOS系统的比较####
【10月更文挑战第26天】 本文将深入探讨安卓(Android)和iOS这两大主流移动操作系统的各自特点、优势与不足。通过对比分析,帮助读者更好地理解两者在用户体验、应用生态、系统安全等方面的差异,从而为消费者在选择智能手机时提供参考依据。无论你是技术爱好者还是普通用户,这篇文章都将为你揭示两大系统背后的故事和技术细节。 ####
36 0
|
6月前
|
移动开发 安全 Android开发
构建高效Android应用:Kotlin协程的实践与优化策略
【5月更文挑战第30天】 在移动开发领域,性能优化始终是关键议题之一。特别是对于Android开发者来说,如何在保证应用流畅性的同时,提升代码的执行效率,已成为不断探索的主题。近年来,Kotlin语言凭借其简洁、安全和实用的特性,在Android开发中得到了广泛的应用。其中,Kotlin协程作为一种新的并发处理机制,为编写异步、非阻塞性的代码提供了强大工具。本文将深入探讨Kotlin协程在Android开发中的应用实践,以及如何通过协程优化应用性能,帮助开发者构建更高效的Android应用。
|
6月前
|
API 调度 Android开发
打造高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第27天】在移动开发领域,性能优化和响应速度是衡量应用质量的关键因素。随着Kotlin语言的普及,协程作为其核心特性之一,为Android开发者提供了一种全新的并发处理方式。本文深入探讨了Kotlin协程在Android应用开发中的优势,并通过实例演示如何在实际项目中有效利用协程提升应用性能和用户体验。
|
6月前
|
移动开发 Android开发 开发者
构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第21天】在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着Kotlin语言在Android平台的广泛采纳,其并发处理的强大工具—协程(Coroutines),已成为提升应用响应性和效率的关键因素。本文将深入分析Kotlin协程的核心原理,探讨其在Android开发中的优势,并通过实例演示如何有效利用协程来优化应用性能,打造更加流畅的用户体验。
66 4