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

简介: 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 命令来过滤结果。

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


相关实践学习
使用CLup和iSCSI共享盘快速体验PolarDB for PostgtreSQL
在Clup云管控平台中快速体验创建与管理在iSCSI共享盘上的PolarDB for PostgtreSQL。
AnalyticDB PostgreSQL 企业智能数据中台:一站式管理数据服务资产
企业在数据仓库之上可构建丰富的数据服务用以支持数据应用及业务场景;ADB PG推出全新企业智能数据平台,用以帮助用户一站式的管理企业数据服务资产,包括创建, 管理,探索, 监控等; 助力企业在现有平台之上快速构建起数据服务资产体系
相关文章
|
2天前
|
存储 安全 Android开发
构建高效的Android应用:Kotlin与Jetpack的结合
【5月更文挑战第31天】 在移动开发的世界中,Android 平台因其开放性和广泛的用户基础而备受开发者青睐。随着技术的进步和用户需求的不断升级,开发一个高效、流畅且易于维护的 Android 应用变得愈发重要。本文将探讨如何通过结合现代编程语言 Kotlin 和 Android Jetpack 组件来提升 Android 应用的性能和可维护性。我们将深入分析 Kotlin 语言的优势,探索 Jetpack 组件的核心功能,并通过实例演示如何在实际项目中应用这些技术。
|
2天前
|
Java Android开发 开发者
构建高效Android应用:Kotlin协程的实践指南
【5月更文挑战第31天】在现代Android开发中,异步编程和性能优化成为关键要素。Kotlin协程作为一种在JVM上实现轻量级线程的方式,为开发者提供了简洁而强大的并发处理工具。本文深入探讨了如何在Android项目中利用Kotlin协程提升应用的响应性和效率,包括协程的基本概念、结构以及实际运用场景,旨在帮助开发者通过具体实例理解并掌握协程技术,从而构建更加流畅和高效的Android应用。
|
2天前
|
数据库 Android开发 开发者
构建高效Android应用:Kotlin协程的全面指南
【5月更文挑战第31天】 在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着Kotlin语言在Android开发中的普及,其提供的协程功能已成为简化异步编程、提高应用响应性和效率的强大工具。本文将深入探讨Kotlin协程的概念、优势以及如何在Android应用中实现它们。通过实际案例分析,我们将展示如何利用协程提升数据处理能力,同时保持UI线程不被阻塞,确保用户界面流畅无阻。
|
2天前
|
JSON Android开发 开发者
构建高效Android应用:采用Kotlin协程优化网络请求
【5月更文挑战第31天】 在移动开发领域,尤其是针对Android平台,网络请求的管理和性能优化一直是开发者关注的焦点。随着Kotlin语言的普及,其提供的协程特性为异步编程提供了全新的解决方案。本文将深入探讨如何利用Kotlin协程来优化Android应用中的网络请求,从而提升应用的响应速度和用户体验。我们将通过具体实例分析协程与传统异步处理方式的差异,并展示如何在现有项目中集成协程进行网络请求优化。
|
3天前
|
物联网 区块链 Android开发
构建高效Android应用:Kotlin与Jetpack的实践之路未来技术的融合潮流:区块链、物联网与虚拟现实的交汇点
【5月更文挑战第30天】 在移动开发领域,效率和性能始终是开发者追求的核心。随着技术的不断进步,Kotlin语言以其简洁性和现代化特性成为Android开发的新宠。与此同时,Jetpack组件为应用开发提供了一套经过实践检验的库、工具和指南,旨在简化复杂任务并帮助提高应用质量。本文将深入探索如何通过Kotlin结合Jetpack组件来构建一个既高效又稳定的Android应用,并分享在此过程中的最佳实践和常见陷阱。
|
2天前
|
Android开发 开发者 UED
探索安卓应用开发中的UI设计趋势
随着移动应用市场的不断发展和用户需求的变化,安卓应用的UI设计趋势也在不断演进。本文将深入探讨当前安卓应用开发中的UI设计趋势,包括暗黑模式、原生化设计、动效设计等方面的发展趋势,为开发者提供参考和启发。
|
2天前
|
安全 网络安全 量子技术
网络安全与信息安全:漏洞、加密技术与安全意识的探索安卓应用开发中的内存管理策略
【5月更文挑战第31天】随着互联网的普及,网络安全问题日益严重。本文将深入探讨网络安全漏洞、加密技术以及安全意识等方面的问题,以期提高公众对网络安全的认识和防范能力。
|
2天前
|
机器学习/深度学习 算法 Android开发
安卓应用开发:打造高效通知管理系统
【5月更文挑战第31天】在移动应用的海洋中,用户经常被各种推送通知所困扰。一个精心设计的通知管理系统对于提升用户体验至关重要。本文将探讨如何在安卓平台上开发一个高效的通知管理系统,包括系统设计原则、实现机制以及性能优化策略,旨在为开发者提供一套可行的解决方案,以减少用户干扰并提高应用的用户留存率。
|
3天前
|
缓存 监控 Android开发
Android 开发中的内存优化策略
【5月更文挑战第30天】在移动应用的开发过程中,性能和用户体验始终是核心关注点。对于基于Android平台的应用程序,有效的内存管理是确保流畅运行和优异性能的关键因素之一。本文将深入探讨Android开发中常见的内存问题,并提出一系列实用的内存优化策略。我们将从内存泄漏的识别与防止开始,到合理使用内存缓存技巧,以及高效的数据结构选择等方面进行详细阐述。通过这些策略的实施,开发者可以显著减少应用的内存占用,提升应用的稳定性和响应速度,进而改善最终用户的体验。