我们的目标是使用AndroidTest(AndroidJUnit4)来运行自动测试。
我们在SDK> = 23
时使用此代码授予权限public static void grantPermission(String permission) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!hasPermission(permission))
getInstrumentation().getUiAutomation()
.executeShellCommand("pm grant " + getTargetContext().getPackageName() + " " + permission);
}
}
@Before
public void setUp() throws Exception {
grantPermission("android.permission.ACCESS_NETWORK_STATE");
grantPermission("android.permission.CHANGE_NETWORK_STATE");
grantPermission("android.permission.CAMERA ");
grantPermission("android.permission.INTERNET");
grantPermission("android.permission.READ_EXTERNAL_STORAGE ");
grantPermission("android.permission.WRITE_EXTERNAL_STORAGE");
grantPermission("android.permission.PACKAGE_USAGE_STATS");
}
该方法适用于
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.CAMERA
虽然在具有使用权限的设置/安全/应用中,我们的应用已开启,但是当我们使用此代码检查权限时,它仍然没有该权限。
AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
// return MODE_DEFAULT, not MODE_ALLOWED
int result = appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), context.getPackageName())
如何才能成功实现这一目标?
答案 0 :(得分:1)
我们已经尝试了许多批准。最后,我们成功了。
批准使用“adb shell输入tap [x],[y]”来模拟点击,这就像人类点击屏幕来触发切换。
这是我们使用的代码。
private void grantPermission() throws InterruptedException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Context context = InstrumentationRegistry.getTargetContext();
final AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
// check if the app doesn't have permission
if (appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), context.getPackageName()) != AppOpsManager.MODE_ALLOWED) {
UiAutomation automation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
//Open UsageAccessSettingsActivity
automation.executeShellCommand("am start com.android.settings/.Settings$UsageAccessSettingsActivity");
Thread.sleep(1000);
//Open the setting of the first app
automation.executeShellCommand(String.format("input tap %s %s", dpToPx(100), dpToPx(138)));
Thread.sleep(1000);
//Tap permit usage access
automation.executeShellCommand(String.format("input tap %s %s", dpToPx(100), dpToPx(164)));
Thread.sleep(1000);
}
}
}
public static int dpToPx(int dp) {
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
我们已经使用hdip,xhdip和xxhdip在SDK 23和24上尝试了6个AVD。一切正常。
<强>更新的[2/10]:强>
我们找到了另一种更简单的方法。使用“adb shell appops”表示赞扬。 这是我们的代码。
@Before
public void setUp() throws Exception {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Context context = InstrumentationRegistry.getTargetContext();
final AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
if (appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), context.getPackageName()) != AppOpsManager.MODE_ALLOWED) {
InstrumentationRegistry
.getInstrumentation()
.getUiAutomation()
.executeShellCommand("appops set " + context.getPackageName() + " android:get_usage_stats allow");
}
}
}
答案 1 :(得分:0)
确保您的应用已启用使用情况统计信息。您可以通过启动Usage Stats Activity来检查这一点。将其添加到onCreate
方法的代码中,或者点击按钮时添加:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);