在VirtualBox下运行的Android应用权限问题

时间:2018-10-29 15:44:10

标签: android virtualbox android-permissions android-x86

我正在尝试使用VirtualBox上安装的Android ISO运行应用程序的连接测试。我从http://www.android-x86.org/获得了Android 7.1 ISO。它安装在VirtualBox下,并且似乎可以正常工作。

我们的应用程序使用PocketSphinx来创建一些目录并在其中存储一些文件。该应用程序在某些Android 7.0平板电脑上以及在Android Studio随附的模拟器下均可正常运行。有时,它可以在VirtualBox下正常工作,但是会处于某种奇怪的状态,无法读取或写入所需的目录。

AndroidManifest包含此权限(以及其他权限):

<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)

如果在此调用之前设置断点,则可以看到所有这些都返回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提示符下手动删除此文件夹,则下次运行我的App测试时将重新创建该文件夹,但是该应用程序仍然存在相同的问题。

我真是茫然为什么我遇到了这些权限问题。有关发生了什么以及如何修复权限的任何想法?

(注意:我不想使用Android模拟器,因为我们出于其他原因在运行VirtualBox,而这两个将无法相互玩耍。)

(注意:毫不奇怪,从调试器运行应用程序会显示与运行连接的测试时所遇到的相同问题。)

复制步骤:

  1. 设置并启动运行Android 7.1 ISO的VirtualBox映像。
  2. 运行adb connect <ip address>
  3. 运行./gradlew connectAndroidTest
  4. 测试将通过
  5. 运行./gradlew connectAndroidTest
  6. 测试将失败,并且将来所有运行都会失败。

解决方法:

  1. 安装应用程序(如果当前未安装)
  2. 在“设置” =>“应用程序” => [我的应用程序]
  3. 中使用“存储”权限

1 个答案:

答案 0 :(得分:0)

将问题归结为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

读取是隐式授予的。但是,在编写连接的测试时,我使用了授予权限规则:

@Rule public GrantPermissionRule permissionRule2 = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

但是,这 not 不会隐式授予读取权限。因此,当应用程序首次在VM上运行时,它被明确授予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