Android系统启动阶段如何在storage/emulated/0创建文件夹并执行挂载?
问题根本原因
/storage/emulated/0是Android的共享存储路径,它的挂载时机远晚于on init、on post-fs-data阶段:
- 低版本Android由vold进程挂载fuse/sdcardfs类型的共享存储
- Android 10+高版本由MediaProvider进程负责挂载虚拟共享存储
你之前选择的触发时机早于共享存储初始化完成时间,操作的是未被挂载的空目录,等共享存储挂载完成后原有操作会被覆盖,所以看不到效果。
可行的系统级实现方案
方案1:init.rc监听挂载完成属性触发(全版本兼容)
在init.rc末尾添加如下配置,监听共享存储挂载完成的系统属性再执行操作:
# 适配大部分Android版本,vold完成存储挂载后触发 on property:vold.post_fs_data_done=1 mkdir /storage/emulated/0/avtmp 0771 media_rw media_rw mount tmpfs tmpfs /storage/emulated/0/avtmp size=10m mode=0771 uid=1023 gid=1023
注:权限配置为media_rw(uid/gid 1023)是为了保证普通应用有权限访问该目录,可根据需求自行调整参数
如果是Android 12+设备,可换用监听用户存储解锁完成的属性:
# Android 12+适配,用户0的加密存储解锁、共享存储挂载完成后触发 on property:sys.user.0.ce_available=1 mkdir /storage/emulated/0/avtmp 0771 media_rw media_rw mount tmpfs tmpfs /storage/emulated/0/avtmp size=10m mode=0771 uid=1023 gid=1023
方案2:修改MediaProvider源码(仅Android10+适用)
如果是高版本用MediaProvider挂载共享存储的场景,直接在挂载完成的回调中加逻辑:
- 找到
packages/providers/MediaProvider/src/com/android/providers/media/MediaService.java的onMountCompleted方法 - 新增代码通过
Runtime.getRuntime().exec()执行对应的mkdir、mount命令即可,MediaProvider本身拥有系统权限,可直接执行特权操作。
方案3:新增开机自启native服务(兼容性最高)
写一个轻量的native系统服务,配置为开机自启,循环检测/storage/emulated/0/Android目录是否存在(该目录为共享存储挂载完成的标志性目录),检测到存在后再执行mkdir、mount操作,该方案不需要修改核心框架代码,适配所有Android版本。
原有方案失效说明
- 修改Android.mk的
LOCAL_POST_INSTALL_CMD是编译阶段在你的编译主机上执行的命令,不会运行在用户设备上,完全不会生效 - init、post-fs-data阶段的操作都在共享存储挂载之前,操作的是根文件系统里的临时目录,共享存储挂载后原有内容会被完全覆盖,自然看不到效果
内容的提问来源于stack exchange,提问作者Sikesky
相关产品推荐
相关产品推荐

