Android文件管理系统

文件的对外分享

这里的"对外分享"是指 当前我们自己开发的app,试图将某个文件分享到其他三方app(比如分享到微信),此时需要通过FileProvider,目的是实现真实物理目录的隐藏,Operation:

假设我们的应用包名是 com.example.app。 在代码中要分享的文件物理路径是: /data/user/0/com.example.app/cache/test.jpg ,需要在src/xml/file_paths.xml文件中配置:

  • path="." :表示映射整个 Context.getCacheDir() 目录。
  • name="internal_cache" :表示在对外生成的 URI 中,用 internal_cache 这个词来代替真实的路径段
2. 生成的 URI 结果

当调用 FileProvider.getUriForFile(...) 时,生成的 URI 会是:

content://com.example.app.provider/internal_cache/test.jpg

注意:

  • 真实的 /data/user/0/com.example.app/cache/ 消失了
  • 取而代之的是你定义的 name 值:/internal_cache/

如果把配置改成: <cache-path name="secret_folder" path="." />

生成的 URI 就会变成: content://com.example.app.provider/secret_folder/test.jpg

所以,name 的值没有所谓的"每种值的含义",它只是给这段路径起的一个对外显示的代号

真正的"规则":XML 标签的选择

真正决定"含义"的 是包裹 name 的那个XML 标签 。这才是需要根据存储位置严格选择的 ,以下是 Android FileProvider 支持的所有标签及其对应的物理路径(这才是你以为的"固定含义"):

XML 标签 对应的 Java 方法 (物理路径) 含义
<files-path> Context.getFilesDir() 内部存储:/data/data/包名/files/
<cache-path> Context.getCacheDir() 内部存储缓存/data/data/包名/cache/ (即你遇到的问题所在)
<external-path> Environment.getExternalStorageDirectory() 外部存储根目录 (SD卡)
<external-files-path> Context.getExternalFilesDir(null) 外部存储 App 私有目录:/storage/.../Android/data/包名/files/
<external-cache-path> Context.getExternalCacheDir() 外部存储 App 缓存目录:/storage/.../Android/data/包名/cache/

示例总结

<cache-path name="internal_cache" path="." /> 的完整解读如下:

  1. <cache-path ... /> :告诉系统 我要开放 内部存储的缓存目录 (getCacheDir())
  2. path="." :开放该目录下的所有子文件和子文件夹
  3. name="internal_cache" :当生成 URI 给别人看时,把这一长串物理路径伪装成 internal_cache 这个名字

建议 : 虽然 name 可以随便起,但为了代码的可读性 通常建议使用具有语义化的名称,如:

  • 映射 cache-path 时,name 取为 "cache""internal_cache"
  • 映射 files-path 下的 images 文件夹时,name 取为 "my_images"

文件的对外分享和APP内部使用的关系

**沙箱机制(Sandbox)跨进程通信(IPC)

只有当你需要把文件"递给"其他 App(如相机、相册、PDF阅读器)时,才必须这么做。如果你只是自己在 App 内部读写,完全不需要

1. 场景一:App 内部自用(不需要 FileProvider)

如果你只是想在自己的代码里读取、写入、或者打印日志,完全不需要 FileProvider

  • 操作 :可以随意使用 File file = new File(getCacheDir(), "test.jpg")
  • 获取路径 :可以随意调用 file.getAbsolutePath(),打印出来的就是真实的物理路径:/data/user/0/com.example.app/cache/test.jpg
  • 结论:私有路径在 App 内部是完全透明的,没有任何限制,和你在电脑上操作文件一样自由

2. 场景二:分享给外部 App(必须使用 FileProvider)

当试图通过 Intent 启动另一个 App(比如调用系统相机拍照存到你的私有目录,或者调用系统安装器安装 APK)时,情况就变了

为什么要用 content:// 而不是 file://

这不仅仅是为了"避免泄露路径",更是因为Linux 权限壁垒Android 7.0 的严格策略

  • 原因 A:Linux 文件权限(物理隔离) 私有目录(/data/user/0/你的包名/)在 Linux 文件系统中,默认权限是 rwx------。这意味着只有你自己 能读写。 如果把一个真实的物理路径(file:///data/user/0/你的包名/...)扔给相册 App,相册 App 拿到这个路径后,试图去读取,操作系统会直接拒绝:Permission Denied。因为它没有权限进入你的私有领地
  • 原因 B:FileUriExposedException(系统强制) 从 Android 7.0 (Nougat) 开始,Google 引入了 StrictMode 策略。一旦系统检测到你的 Intent 里面夹带了 file:// 开头的 URI 跨越了 App 边界,它会直接抛出 FileUriExposedException 让你崩溃。 目的:Google 强制开发者放弃"直接给路径"这种不安全的做法
FileProvider 到底做了什么?

FileProvider 就像是一个临时授权的签证官

  1. 封装 :它把私有的物理路径 /data/.../test.jpg 包装成一个虚拟的 content://.../internal_cache/test.jpg
  2. 授权 :当其他 App 拿着这个 content:// URI 来访问时,FileProvider 会检查,并临时授予那个 App 读/写权限 (基于 FLAG_GRANT_READ_URI_PERMISSION
  3. 数据流转:其他 App 不需要知道文件到底在哪里,它只需要通过这个 URI 拿到文件的数据流(Stream)。

3. 关于你提到的"外部路径"对比

即使是外部存储(SD卡),在现代 Android 开发中,也建议(甚至强制)使用 FileProvider 进行分享。

  • 虽然外部存储的文件可能被其他 App 读取(取决于 Android 版本和分区存储 Scoped Storage 策略),但 Android 7.0 的 FileUriExposedException 是一视同仁的
  • 只要通过 Intent 跨 App 传递文件,无论文件在私有目录还是外部存储 ,只要你敢传 file:// URI,系统就敢让你崩溃

总结

  1. 内部操作 :你可以随意获取和打印私有路径的 absolutePath,没有任何限制。
  2. 外部泄露FileProvider 的确隐藏了真实路径,但它更重要的作用是**"带着临时钥匙(权限)把文件递出去"**。
  3. 强制性 :这是 Android 7.0+ 跨进程共享文件的唯一标准姿势,不是可选项,而是必选项

内部存储私有路径和外部存储路径

内部存储私有路径 (Internal Storage)和外部存储路径(External Storage)

一、 场景对比:App 内部自用(自产自销)

在这个场景下,App 是文件的"主人"。无论是私有目录还是外部目录,只要有权限,操作方式几乎没有区别

特性 内部存储私有路径 (Internal Private) 外部存储路径 (External Storage)
典型路径 /data/user/0/com.example/files/ /storage/emulated/0/Android/data/com.example/files//storage/emulated/0/DCIM/
获取路径 完全自由 。 调用 file.getAbsolutePath() 会直接返回上述真实字符串。 完全自由 。 调用 file.getAbsolutePath() 同样直接返回真实字符串。
读写方式 直接使用 Java 的 File API 或 FileInputStream/FileOutputStream 同左。直接使用 File API(但在 Android 10+ 公共目录需用 MediaStore/SAF)。
权限要求 无需任何权限。这是你的绝对领地。 App专属目录Android/data/...)无需权限。 公共目录可能需要存储权限。
安全性 极高 。Linux 文件系统权限默认为 rwx------,其他 App 无法通过路径访问。 较低。用户可以通过文件管理器看到,其他拥有权限的 App(在旧版本)也能扫描到。

总结: 在 App 内部,私有路径并不神秘。完全可以打印它的绝对路径,甚至在 Log 里输出它。系统不会因为你"知道"或"打印"了这个路径而报错


二、 场景对比:对外分享(跨进程交互)

当需要把文件交给第三方 App(如调用系统相机、裁剪图片、安装 APK)时,规则发生了剧变

特性 内部存储私有路径 (Internal Private) 外部存储路径 (External Storage)
直接传递路径 (file://) 绝对禁止 。 1. 权限墙 :对方 App 没有 Linux 权限读取你的 /data/ 目录,会报 Permission Denied。 2. 系统墙 :Android 7.0+ 抛出 FileUriExposedException 崩溃。 同样禁止 。 虽然在旧版本 Android 中,外部路径可能被对方读取,但 Android 7.0+ 也是一视同仁 ,强制抛出 FileUriExposedException 崩溃。
正确做法 (content://) 必须使用 FileProvider 。 将路径包装为 content://com.example.../internal/test.jpg 必须使用 FileProvider 。 将路径包装为 content://com.example.../external/test.jpg
FileProvider 的作用 "穿透"沙箱 。 它不仅隐藏了路径,更重要的是它利用 FLAG_GRANT_READ_URI_PERMISSION 给了对方一把临时钥匙 "规范"访问 。 即使文件在外部存储,为了符合 Android 的安全规范(StrictMode),也必须通过 URI 授权的方式传递。
路径泄露风险 如果不用 Provider,直接给路径,对方也读不到(因为 Linux 权限),所以物理上是安全的,但逻辑上是行不通的 如果不用 Provider,直接给路径,在旧系统或特定条件下,对方可能读到,存在隐私泄露风险。

总结: "私有路径不被允许如此操作"是因为物理隔离 (Linux 权限)和系统策略 (Android 7.0+)的双重限制。 而外部路径虽然没有物理隔离(在某些情况下),但系统策略 依然强制要求你使用 FileProvider

所以结论是: 只要是跨 App 分享文件 ,无论文件是在私有目录(/data/)还是外部目录(/storage/),都必须 使用 FileProvider 搭配 content:// URI。这不仅仅是为了防止路径泄露,更是为了赋予对方读取文件的临时权限


私有路径外部路径在权限配置上的差异

以 Android 12+ 为基准详细拆解这两者在申请配置上的巨大差异

一、 内部存储私有路径 (Internal Private Path)

路径示例: /data/user/0/com.example/files/, 对于这个目录,系统的态度非常明确:这是你的私人领地,闲人免进

1. 清单文件配置 (AndroidManifest.xml)
  • 不需要任何配置。
  • 不需要声明 <uses-permission>,也不需要申请读写权限
2. 动态权限申请 (Runtime Request)
  • 不需要任何申请。
  • 无论是在 Android 6.0 还是 Android 15,都可以在代码中直接调用 File API 进行读写
3. 特点总结
  • 零打扰:用户根本不知道你在读写这些文件,系统设置里的"权限管理"也不会显示存储权限的使用记录
  • 绝对安全:其他 App 即使拥有最高权限(非 Root 情况下),也无法申请权限来访问你的这个目录

二、 外部存储路径 (External Storage)

路径示例: /storage/emulated/0/...

到了这里,情况变得极其复杂。Android 12+ 强制执行分区存储(Scoped Storage) ,将外部存储划分为"私有区域"和"公共区域"

1. 外部存储中的"私有区域" (App-Specific Directory)
  • 路径: /storage/emulated/0/Android/data/com.example/files/

  • 权限现状:

    • 配置与申请: 完全不需要
    • 区别: 虽然它在"外部"存储(物理上可能是 SD 卡或大容量分区),但 Android 将其视为 App 的专属空间。读写这里的文件,不需要申请任何权限
    • 注意: 当 App 被卸载时,这里的内容会被系统直接抹除
2. 外部存储中的"公共区域" (Public Directory)
  • 路径: DCIM/, Pictures/, Music/, Documents/, Download/
  • 权限现状: 这里是权限管控的"重灾区"
操作类型 清单文件配置 (AndroidManifest.xml) 动态权限申请 (Java/Kotlin 代码) 备注 (Android 12+ 特性)
写文件 (保存图片/视频) 无需权限 无需申请 只要是通过 MediaStore API 写入文件,你就是文件的"拥有者",不需要权限即可写入。
读文件 (自己创建的) 无需权限 无需申请 你访问自己 App 刚才写入到相册的图片,不需要任何权限。
读文件 (别人创建的) 必须配置 <uses-permission android:name="..." /> 必须申请 ActivityCompat.requestPermissions(...) Android 13+ 巨变: 不再使用 READ_EXTERNAL_STORAGE。 需根据文件类型申请细分权限: - READ_MEDIA_IMAGES (图片) - READ_MEDIA_VIDEO (视频) - READ_MEDIA_AUDIO (音频)
修改/删除 (别人创建的) 无需配置 无需常规申请 需使用 RecoverableSecurityException 特殊机制: 不能直接删除。需要捕获异常,弹出一个系统级的弹窗,询问用户:"是否允许某App修改这张照片?"

三、 核心区别总结:Android 12+ 的"双标"现场

为了更直观地理解,这里总结三个关键维度的对比:

1. "写"的区别
  • 私有路径:想写就写,像在自己笔记本上写字

  • 外部路径

    • Android/data:想写就写。
    • 公共目录(如相册) :不能直接用 File 路径去写(会报错),必须像"填表"一样,通过 MediaStore 告诉系统你要存一张图,系统帮你存进去
2. "读"的区别
  • 私有路径:直接读取,无需打招呼

  • 外部路径

    • Android 12 :可能还需要 READ_EXTERNAL_STORAGE
    • Android 13+ :权限被拆碎了。如果你只想选一张头像,申请"图片权限"即可,不要去碰"音频权限"。这体现了参考资料中提到的权限精细化控制
3. 用户感知的区别
  • 私有路径 :用户无感知

  • 外部路径

    • 用户会在安装或运行时看到弹窗
    • 在 Android 12+ 的系统设置中,用户可以在"隐私仪表盘"或"敏感权限使用记录"中,清晰地看到你的 App 在几点几分读取了外部存储(参考资料 2)

内外路径的选择 Reasonable建议

在 Android 12+ 时代 建议是:

  1. 能用私有路径,绝不用外部路径。 既省去了适配权限的麻烦,又保护了数据安全
  2. 如果非要对外分享 (比如生成一张海报保存到相册),请使用 MediaStore API 将文件插入到公共目录,而不是申请权限后用 File 流硬写
  3. 如果只是想让用户选个文件 (比如上传附件),请使用 SAF (Storage Access Framework) ,也就是调用系统文件选择器 (Intent.ACTION_OPEN_DOCUMENT)。这种方式完全不需要申请任何存储权限,是 Google 最推荐的"绿色"做法

分区存储(Scoped Storage)机制

文件一旦被创建,系统确实会"标记"它是哪个 App 创建的 详细拆解一下:

1. 数据库层面的"户籍登记" (MediaStore Database)

这是 Android 12+ 处理外部公共存储(如相册、视频、音频目录)时的关键机制。

  • 标记方式 : 当通过 MediaStore API 创建一张图片时,Android 系统不仅会在硬盘上写入文件数据,还会同时在系统的媒体数据库 (一个巨大的 SQLite 数据库)中插入一条记录。 这条记录中有一个关键字段(类似于 owner_package_name),明确记录了:"这个文件是由 com.example.myapp 创建的"

  • 作用: 这就是为什么访问自己创建的文件不需要权限的原因。 当你试图修改一张图片时,系统会去查数据库:"这个 App 是当初创建这张图的那个 App 吗?"

    • -> 放行,允许修改/删除
    • 不是 -> 拦截,要求申请权限或弹窗询问用户
  • 持久性: 这种标记是持久的。只要文件还在媒体库中,这个"所有权"关系就存在。但如果用户在系统设置中清除了你的 App 数据,或者卸载了App,这种关联可能会被重置或标记为"孤儿文件"(Orphaned),此时控制权通常会交还给系统

2. 文件系统层面的"指纹烙印" (Linux UID/GID)

这是 Android 处理内部私有存储Android/data 目录时的底层机制

  • 标记方式 : Android 是基于 Linux 内核的。在 Linux 中,每一个安装的 App 都会被分配一个唯一的 UID (用户ID) 。 正如参考资料 3 和 4 所述,创建文件时,操作系统会分配资源并记录元数据。在 Android 中,App 创建的每一个私有文件,其文件系统层面的 Owner 属性都会被强制设置为该 App 的 UID

  • 作用: 这是 Linux 文件权限机制(rwx 权限)的直接体现

    • 你的 App (UID: 10050) 试图读取文件
    • 系统检查文件属性:Owner 是 UID 10050
    • 匹配成功,允许访问
    • 如果是另一个 App (UID: 10051) 试图访问,系统发现 UID 不匹配,且该文件通常权限设置为"其他人不可读",于是直接拒绝访问

总结

所以,所谓的"自己创建"和"别人创建",并不是一种抽象的概念,而是实实在在写在系统里的数据:

  1. 在公共区域(相册等): 依靠 MediaStore 数据库 中的"所有者包名"字段来标记
  2. 在私有区域(沙盒): 依靠 Linux 文件系统 的 UID(用户ID)属性来标记

正是因为有了这个不可篡改的"出生证明",Android 12+ 才能在不询问用户的情况下,精准地判断出你是"主人"还是"客人"

安卓手机的根目录结构

以下两张截图,展示的是 Android 操作系统最底层的根目录(Root Directory,即 / 。这通常只有在获取了 Root 权限,或者使用特定的文件管理器(如 MT管理器、ES文件浏览器)浏览系统分区时才能看到

里的命名非常容易产生歧义,因为它们是历史遗留产物

一、 核心概念辨析:内部 vs 外部

在 Android 开发和文件系统中,这两个词的含义如下:

  1. 内部存储 (Internal Storage)

    • 定义:这是系统保留的、受保护的区域
    • 特点 :这里存放着系统文件、App 的私有数据(数据库、SharedPreference)。普通用户和没有 Root 权限的其他 App 无法访问这里
    • 对应你截图中的路径 :主要是 /data 目录
  2. 外部存储 (External Storage)

    • 定义:这是面向用户的、共享的区域
    • 特点:这里存放着你的照片、下载的文件、音乐等。虽然叫"外部",但现在它通常是手机内置闪存的一部分(以前是指 SD 卡)
    • 对应你截图中的路径 :主要是 /sdcard/storage/emulated/0

二、 截图路径详解(基于你的文件结构)

关键目录分为三类:系统核心层(只读/受保护)内部数据层(私有)外部映射层(共享)

1. 内部数据层(真正的"内部路径")

这是 App 的"家",与"外部路径"相对的概念

  • /data (截图第一张中间位置):

    • 作用:这是最核心的用户数据分区
    • 结构 :当安装一个 App 时,系统会在 /data/data/包名/ 下创建一个专属文件夹
    • 权限:极其严格。只有 App 自己和系统(以及 Root 用户)能进
    • 举例:微信的聊天记录数据库、你的登录 Token 都存在这里。这就是所谓的"沙盒"
2. 外部映射层(所谓的"外部路径")

这是用户平时能看到的文件区域

  • /sdcard

    • 作用 :这是一个软链接(Symlink) ,你可以把它理解为 Windows 的"快捷方式"
    • 指向 :它通常指向 /storage/self/primary/storage/emulated/0
    • 内容 :点击进去,你就会看到 DCIM(相册)、Download(下载)、Android(外部数据)等熟悉的文件夹
    • 注意:虽然它叫 sdcard,但它现在指的是手机内置的存储空间,而不是插拔的物理卡
  • /storage

    • 作用:这是挂载点。所有的存储设备(内置存储、外置 SD 卡、OTG U盘)都会挂载到这里
  • /mnt

    • 作用 :Mount(挂载)的缩写。这是更底层的挂载点,历史遗留较多,现在的 Android 系统主要使用 /storage 来管理存储
3. 系统核心层(支撑手机运行的基础)

这些目录构成了 Android 系统的骨架,通常是只读的(Read-Only)。

  • /system

    • 存放 Android 系统的核心框架、系统 App(如设置、电话)、字体、媒体库等
  • /vendor

    • 存放厂商(如高通、联发科)提供的底层驱动程序和硬件抽象层代码
  • /product/odm/oem

    • 这些是厂商定制分区。比如你截图中的 my_bigballmy_heytap(看起来像是 OPPO/OnePlus/Realme 系的 ColorOS 专有目录),存放的是手机厂商自己的特色功能、预装应用和资源
  • /dev

    • Device(设备)的缩写。这里全是文件形式的硬件接口(如 CPU、内存、传感器)
  • /proc/sys

    • 这是虚拟文件系统,存在于内存中。它们展示了系统当前的运行状态(如 CPU 频率、电池电量)。

三、 总结:你的"内部"与"外部"地图

回到你的问题,文件路径的对应关系如下:

概念 路径示例 谁能访问? 你的截图中在哪里?
内部路径 /data/data/com.example.app/ 仅 App 自己 (沙盒) /data 文件夹里
外部路径 /sdcard/Download/ (实际是 /storage/emulated/0/Download/) 用户、拥有权限的 App 点击 /sdcard 或者是 /storage
系统路径 /system/bin/ 系统进程 (只读) /system 文件夹里

对截图中文件系统的观察: 从截图中的 my_heytapmy_bigball 等文件夹来看,截图中使用的应该是一台 OPPO、OnePlus 或 Realme 手机(ColorOS 系统)。这些 my_ 开头的目录是该厂商特有的分区挂载点,用于存放他们定制的系统资源,这是标准 Android 结构之外的"私货"

看到的这个根目录结构,确实不完全是物理硬盘上的真实分区结构 。这其中充斥着大量的软链接(Symbolic Link)挂载点(Mount Point)

这就像是一个精心设计的"虚拟大厅",为了兼容旧软件的历史习惯,同时又要配合新系统的安全隔离机制,Android 不得不制造很多"传送门"

关于 Android 文件系统"虚拟化"与"真实物理路径"的解析

1. 为什么说它"不是真实的物理路径"?

在 Linux(Android 的内核)中,文件系统是一棵巨大的树,但这棵树并不直接等同于硬盘分区。

  • 挂载(Mounting) :物理分区(比如闪存上的某个区块 /dev/block/sda15)必须"挂载"到目录树的某个节点上才能被访问。
  • 软链接(Symlink) :为了保持兼容性,系统会创建一个快捷方式指向真正的挂载点。

你看到的根目录 /,实际上是一个RootFS(根文件系统) ,它只存在于内存中(Ramdisk),或者是一个只读的系统镜像。它负责把各个真实的物理分区"组装"起来。

2. /sdcard 的确是 Shortcut

/sdcard 是最典型的例子。它的演变历史就是一部 Android 的兼容史:

  • 表象 :你在根目录看到 /sdcard
  • 第一层跳转 :它通常是一个软链接,指向 /storage/self/primary
  • 第二层跳转/storage/self/primary 往往又指向 /mnt/user/0/primary 或者 /storage/emulated/0
  • 真实物理位置 :最终,数据是存储在 /data/media/0 这个物理位置上的

为什么要这么绕? 因为早期的 Android App 写死了路径叫 /sdcard。后来 Android 取消了物理 SD 卡插槽,改用内置存储,为了不让旧 App 崩溃,系统必须保留 /sdcard 这个入口,把它强行"链接"到新的存储位置。

3. 关于 /data 的特殊性:它通常是"真身",但也包含"假象"

起初我怀疑 /data 也是 shortcut,这个情况比较复杂,通常分为两部分:

  • /data 目录本身 : 在绝大多数现代 Android 手机中,/data 通常是一个真实的挂载点 。 它直接对应着手机闪存中最大的那个物理分区(Userdata 分区)。当你进入 /data,你实际上就是直接站在了用户数据分区的"地基"上

  • /data 内部的玄机 : 虽然 /data 是真的,但它里面的内容可能有"假"

    • /data/data:这是存放 App 私有数据的真实目录
    • /data/user/0 :这是为了支持多用户(Multi-user)功能而引入的路径。实际上,/data/user/0 往往是一个软链接,它指向的就是 /data/data
    • /data/media/0 :这才是你"外部存储"(即 /sdcard)的真正物理藏身之处 。Android 通过一种叫 FUSEsdcardfs 的文件系统技术,把 /data/media/0 模拟成 /sdcard 给用户看
4. 为什么要做这些"Shortcut"?

除了兼容性,还有一个核心原因是沙盒隔离(Sandbox)多用户机制

  • 不同的人看到不同的风景 : 当你在手机上开启"应用分身"或"访客模式"时,系统会利用这些链接技术。 比如,主用户看到的 /sdcard 指向 /storage/emulated/0,而访客看到的 /sdcard 可能指向 /storage/emulated/10路径名字一样,但指向的物理区域完全不同。 这就是虚拟路径的强大之处

总结: Android 的文件系统就像是一个精密设计的"超链接"网页

  • /sdcard 是为了骗过旧 App 的"快捷方式"
  • /storage 是现代 Android 管理存储的"集散中心"
  • /data 是真实的物理分区挂载点,但它是通过"投影"技术把一部分空间(/data/media)伪装成了外部存储
相关推荐
冬奇Lab2 小时前
【Kotlin系列02】变量与数据类型:从val/var到空安全的第一课
android·kotlin·编程语言
alonewolf_992 小时前
深入理解MySQL事务与锁机制:从原理到实践
android·数据库·mysql
深海呐2 小时前
Android WebView吊起软键盘遮挡输入框的问题解决
android·webview·android 键盘遮挡·webview键盘遮挡
摘星编程2 小时前
RAG的下一站:检索增强生成如何重塑企业知识中枢?
android·人工智能
fatiaozhang95273 小时前
基于slimBOXtv 9.19 V2(通刷S905L3A/L3AB)ATV-安卓9-通刷-线刷固件包
android·电视盒子·刷机固件·机顶盒刷机·slimboxtv9.19v2·slimboxtv
左绍骏3 小时前
01.学习预备
android·java·学习
鹏程十八少3 小时前
破解Android悬浮窗遮挡无障碍服务难题:我在可见即可说上踩过的坑
android·前端·面试
Kapaseker3 小时前
前端已死...了吗
android·前端·javascript
Winston Wood4 小时前
Android图形与显示系统经典故障解决方案:从源码到实操
android·图形系统·显示系统