简而言之,您应该为应用程序的清单和测试项目的清单添加相同的android:sharedUserId,并为测试项目声明必要的权限。
这种解决方法源于 Android 实际上将权限分配给 linux 用户帐户 (uid) 而不是应用程序本身(默认情况下,每个应用程序都有自己的 uid,因此看起来权限是针对每个应用程序设置的)。
使用相同证书签名的应用程序可以共享相同的 uid。因此,它们具有一组共同的权限。例如,我可以拥有请求 WRITE_EXTERNAL_STORAGE 权限的应用程序 A 和请求 INTERNET 权限的应用程序 B。 A 和 B 都由同一个证书签名(比如说调试一个)。在 A 和 B 的 AndroidManifest.xml 文件中,android:sharedUserId="test.shared.id" 在 <manifest> 标记中声明。然后 A 和 B 都可以访问网络并写入 sdcard,即使他们只声明了部分所需权限,因为权限是按 uid 分配的。当然,这只有在实际安装了 A 和 B 时才有效。
以下是测试项目的设置示例。应用程序的 AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="com.example.testproject.uid">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity
android:name="com.example.testproject.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
还有一个测试项目的 AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testproject.test"
android:sharedUserId="com.example.testproject.uid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.example.testproject" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
此解决方案的缺点是安装测试包时应用程序也能够写入外部存储。如果它不小心将某些内容写入存储,它可能会一直被忽视,直到发布时,包将使用不同的密钥进行签名。
有关共享 UID 的更多信息,请访问 http://developer.android.com/guide/topics/security/permissions.html#userid。