具有 PACKAGE_USAGE_STATS 权限的 AndroidTest
AndroidTest with PACKAGE_USAGE_STATS permission
我们的目标是使用 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
虽然在Settings/Security/Appswith usage access中,我们的应用是开启的,但是当我们使用这段代码来检查权限时,它仍然没有那个权限。
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())
我怎样才能实现这个目标?
确保您的应用启用了使用情况统计信息。您可以通过启动 Usage Stats Activity 来检查这一点。在您的 onCreate
方法中将其添加到您的代码中,或者可能在单击按钮时添加:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
我们试了很多都认可。终于,我们成功了。
批准的是使用"adb shell input 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);
}
我们已经在 SDK 23 和 24 上使用 hdip、xhdip 和 xxhdip 尝试了 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");
}
}
}
我们的目标是使用 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
虽然在Settings/Security/Appswith usage access中,我们的应用是开启的,但是当我们使用这段代码来检查权限时,它仍然没有那个权限。
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())
我怎样才能实现这个目标?
确保您的应用启用了使用情况统计信息。您可以通过启动 Usage Stats Activity 来检查这一点。在您的 onCreate
方法中将其添加到您的代码中,或者可能在单击按钮时添加:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
我们试了很多都认可。终于,我们成功了。
批准的是使用"adb shell input 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);
}
我们已经在 SDK 23 和 24 上使用 hdip、xhdip 和 xxhdip 尝试了 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");
}
}
}