我正在尝试添加OBB文件支持,但我遇到了一个奇怪的情况。当我拨打getExternalStorageDirectory()
时,它会返回我设备上不存在的路径。
我在我的应用程序开头调用它:
Log.i( LOG_ID, "XXXXXXXXXXXXXXXX <--- "+Environment.getExternalStorageDirectory().getAbsolutePath() );
它返回:
XXXXXXXXXXXXXXXX <--- /storage/emulated/0
但是当我通过adb -d shell
连接并运行ls -al /storage/emulated
时,我得到了:
lrwxrwxrwx root root 2013-12-04 15:17 legacy -> /mnt/shell/emulated/0
正如您所看到的,返回的路径getExternalStorageDirectory()
在我的设备上无效。知道为什么会这样,以及如何在没有硬编码的情况下找到OBB文件/mnt/sdcard/
?
编辑:
我刚刚进行了一些测试:
Works - stat( "/sdcard/Android/obb" );
Fails - stat( "/sdcard/Android/obb/uk.co.mycomp.myapp" );
shell@android:/mnt/shell $ ls -ald /sdcard/Android/obb/
drwxrwxr-x root sdcard_rw 2013-12-18 16:42
shell@android:/mnt/shell $ ls -ald /sdcard/Android/obb/uk.co.mycomp.myapp
drwxrwxr-x root sdcard_rw 2013-12-18 18:36
正如您所看到的,两个目录相同但我只能访问父目录。这可能与我的问题有任何关联......
答案 0 :(得分:7)
在最近的Android版本中,不同用户ID的安装实际上是不同的,这会使您尝试调查此问题的方式无效。
最近的Android版本利用Linux内核的“每进程命名空间”功能为不同的进程系统提供不同的安装集,这使得调查存储路径的尝试受挫。这可能与支持多个(人)用户帐户的努力有关,包括外部存储的唯一和共享子部分。
运行adb shell时,会获得一组从adbd继承的挂载。
但相比之下,由应用程序运行的代码(在其进程或子进程中)获取不同的安装集,显然要么从zygote继承,要么很快就会被进程区分配置代码将一个刚刚萌芽的合子变成你的应用程序。
要了解您的应用程序所看到的内容,请安装connectbot
之类的内容,您可以使用这些内容从应用程序进程获取本地shell,并运行mount命令或任何其他感兴趣的调查。例如:
u0_a99@build:/ $ mount
/dev/fuse /storage/emulated/0 fuse rw....
/dev/fuse /storage/emulated/legacy fuse rw.....
相比之下,从adb shell检查:
shell@build:/mnt $ mount
/dev/fuse /mnt/shell/emulated fuse rw.....
令人困惑,因为坐标是由进程的祖先决定的,而不是它的用户ID ,使用的是run-as
工具adb 不会为您提供与申请流程或孩子相同的观点,而是会为您提供adb的观点。
但是,如果您拥有正在运行的应用程序进程的pid,则可以使用run-as查看其/proc/pid##/mounts
文件,而无需实际从应用程序获取shell。