Android VirtualBox 下的应用权限问题运行
Android app permission problem running under VirtualBox
我正在尝试 运行 使用安装在 VirtualBox 上的 Android ISO 为我的应用程序进行连接测试。我从 http://www.android-x86.org/ 获得了 Android 7.1 ISO。它安装在 VirtualBox 下,似乎工作正常。
我们的应用程序使用 PocketSphinx 创建一些目录并在其中存储一些文件。该应用程序可在某些 Android 7.0 平板电脑和 Android Studio 附带的模拟器下正常运行。有时,它在 VirtualBox 下可以正常工作,但它会进入某种奇怪的状态,无法读取或写入所需的目录。
Android清单包含此权限(以及其他权限):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
权限在设置=>应用程序=>[我们的应用程序]=>权限中显示为已启用。
这是实际的错误消息:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.hcs.android.orconnect/files/sync/cmudict-en-us.dict (No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at edu.cmu.pocketsphinx.Assets.copy(Assets.java:224)
at edu.cmu.pocketsphinx.Assets.syncAssets(Assets.java:269)
如果我在这个调用之前设置断点,我可以看到所有这些 return false:
new File("/storage/emulated/0/Android/data/").canRead()
new File("/storage/emulated/0/Android/data/").canWrite()
new File("/storage/emulated/0/Android/data/com.hcs.android.orconnect").canRead()
new File("/storage/emulated/0/Android/data/com.hcs.android.orconnect").canWrite()
但是,某些东西创建了 /storage/emulated/0/Android/data/com.hcs.android.orconnect/files 文件夹。如果我从 adb shell 提示中手动删除此文件夹,它将在我的应用程序测试的下一个 运行 中重新创建,但该应用程序仍然存在相同的问题。
我真的不知道为什么我会遇到这些权限问题。关于正在发生的事情以及如何修复权限有什么想法吗?
(注意:我不想使用Android模拟器,因为我们运行宁VirtualBox出于其他原因,两者不会互相玩。)
(注意:不出所料,从调试器 运行 运行应用程序显示的问题与我 运行 连接测试时遇到的问题相同。)
重现步骤:
- 设置并启动 VirtualBox 映像 运行使用 Android 7.1 ISO。
- 运行
adb connect <ip address>
- 运行
./gradlew connectAndroidTest
- 测试将通过
- 运行
./gradlew connectAndroidTest
- 测试将失败并且所有未来的 运行s 也会失败。
解决方法:
- 安装应用程序(如果当前未安装)
- 在设置 => 应用 => [我的应用]
中调整 "Storage" 权限
将问题追踪到 Android 对权限的处理不一致。
我们应用程序的清单包含:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这导致 /data/system/users/0/runtime-permissions.xml 包含:
<item name="android.permission.READ_EXTERNAL_STORAGE" granted="true" flags="0" />^M
<item name="android.permission.WRITE_EXTERNAL_STORAGE" granted="true" flags="0" />^M
读取是隐式 g运行ted。但是,在编写连接测试时,我使用了 g运行t 权限规则:
@Rule public GrantPermissionRule permissionRule2 = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
然而,这 不是 隐含 g运行t 读取权限。因此,当应用程序首次在 VM 上 运行 时,它被 g运行ted 显式 WRITE 和隐式 READ。但是,gradlew 运行 第一次测试后,它会卸载应用程序。然后下一个测试 运行 将重新安装该应用程序,但根据规则只授予它 WRITE 权限。然后如上所述测试失败。
所以,解决方法是在测试中请求读写权限:
@Rule public GrantPermissionRule permissionRule2 = GrantPermissionRule.grant(android.Manifest.permission.READ_EXTERNAL_STORAGE);
@Rule public GrantPermissionRule permissionRule25 = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
没关系,这与我的 AndroidManifest.xml 文件不匹配。 Google的左手和右手从未见过面,所以行为不同。
谢谢,Google! /s
我正在尝试 运行 使用安装在 VirtualBox 上的 Android ISO 为我的应用程序进行连接测试。我从 http://www.android-x86.org/ 获得了 Android 7.1 ISO。它安装在 VirtualBox 下,似乎工作正常。
我们的应用程序使用 PocketSphinx 创建一些目录并在其中存储一些文件。该应用程序可在某些 Android 7.0 平板电脑和 Android Studio 附带的模拟器下正常运行。有时,它在 VirtualBox 下可以正常工作,但它会进入某种奇怪的状态,无法读取或写入所需的目录。
Android清单包含此权限(以及其他权限):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
权限在设置=>应用程序=>[我们的应用程序]=>权限中显示为已启用。
这是实际的错误消息:
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.hcs.android.orconnect/files/sync/cmudict-en-us.dict (No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:169)
at edu.cmu.pocketsphinx.Assets.copy(Assets.java:224)
at edu.cmu.pocketsphinx.Assets.syncAssets(Assets.java:269)
如果我在这个调用之前设置断点,我可以看到所有这些 return false:
new File("/storage/emulated/0/Android/data/").canRead()
new File("/storage/emulated/0/Android/data/").canWrite()
new File("/storage/emulated/0/Android/data/com.hcs.android.orconnect").canRead()
new File("/storage/emulated/0/Android/data/com.hcs.android.orconnect").canWrite()
但是,某些东西创建了 /storage/emulated/0/Android/data/com.hcs.android.orconnect/files 文件夹。如果我从 adb shell 提示中手动删除此文件夹,它将在我的应用程序测试的下一个 运行 中重新创建,但该应用程序仍然存在相同的问题。
我真的不知道为什么我会遇到这些权限问题。关于正在发生的事情以及如何修复权限有什么想法吗?
(注意:我不想使用Android模拟器,因为我们运行宁VirtualBox出于其他原因,两者不会互相玩。)
(注意:不出所料,从调试器 运行 运行应用程序显示的问题与我 运行 连接测试时遇到的问题相同。)
重现步骤:
- 设置并启动 VirtualBox 映像 运行使用 Android 7.1 ISO。
- 运行
adb connect <ip address>
- 运行
./gradlew connectAndroidTest
- 测试将通过
- 运行
./gradlew connectAndroidTest
- 测试将失败并且所有未来的 运行s 也会失败。
解决方法:
- 安装应用程序(如果当前未安装)
- 在设置 => 应用 => [我的应用] 中调整 "Storage" 权限
将问题追踪到 Android 对权限的处理不一致。
我们应用程序的清单包含:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这导致 /data/system/users/0/runtime-permissions.xml 包含:
<item name="android.permission.READ_EXTERNAL_STORAGE" granted="true" flags="0" />^M
<item name="android.permission.WRITE_EXTERNAL_STORAGE" granted="true" flags="0" />^M
读取是隐式 g运行ted。但是,在编写连接测试时,我使用了 g运行t 权限规则:
@Rule public GrantPermissionRule permissionRule2 = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
然而,这 不是 隐含 g运行t 读取权限。因此,当应用程序首次在 VM 上 运行 时,它被 g运行ted 显式 WRITE 和隐式 READ。但是,gradlew 运行 第一次测试后,它会卸载应用程序。然后下一个测试 运行 将重新安装该应用程序,但根据规则只授予它 WRITE 权限。然后如上所述测试失败。
所以,解决方法是在测试中请求读写权限:
@Rule public GrantPermissionRule permissionRule2 = GrantPermissionRule.grant(android.Manifest.permission.READ_EXTERNAL_STORAGE);
@Rule public GrantPermissionRule permissionRule25 = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
没关系,这与我的 AndroidManifest.xml 文件不匹配。 Google的左手和右手从未见过面,所以行为不同。
谢谢,Google! /s