2017-02-08 9 views
1

私たちの目標は、AndroidTest(AndroidJUnit4)を使用して自動テストを実行することです。PACKAGE_USAGE_STATS権限を持つAndroidTest

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

この目標を達成するにはどうすればよいですか?

答えて

1

。最後に成功しました。

承認されたタップをシミュレートするために "adbシェル入力タップ[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"); 
     } 
    } 
} 
0

アプリの使用状況が有効になっていることを確認してください。これを確認するには、Usage Statsアクティビティを起動します。ボタンのクリックであなたのonCreate方法であなたのコードにこれを追加したり、可能性:私たちは、承認された多くのを試してみました

Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS); 
startActivity(intent); 
+0

アクティビティを開始してユーザーがアクセス権を許可することができますが、私たちの目標は自動テストを実行することです。ユーザーが既に許可を与えていることをプログラムでシミュレーションします。 – Wade

関連する問題