Android revoke permission at start of each test Android revoke permission at start of each test android android

Android revoke permission at start of each test


You should not revoke any permission before the tests start. This will restart the entire test app process and the test will be marked as failure.

Instead you can revoke the permission after test execution is completed i.e. in @After method as follows:

@Afterfun tearDown(){    InstrumentationRegistry.getInstrumentation().uiAutomation.            executeShellCommand("pm revoke ${getTargetContext().packageName} android.permission.WRITE_EXTERNAL_STORAGE")}

Alternatively, you can use Android Test Orchestrator version 1.0.2 and set

 testInstrumentationRunnerArguments clearPackageData: 'true'

this will clear the package data after each test.

Note: Android Test Orchestrator v1.0.2 has issues when it comes to managing code coverage reports via Jacoco.


ADB has the capability to revoke permissions, but it can't be called from an instrumentation test because revoking a permission will restart the entire app process and end the test with failure. The following Kotlin code will perform the revocation, but will crash your test if a permission gets revoked.

/** *  Will revoke, but also CRASH if called by a test *  Revocation requires a full process restart, which crashes your test process. */fun revokePermissions(vararg permissions: String) {    permissions.forEach {        InstrumentationRegistry.getInstrumentation().uiAutomation.                executeShellCommand("pm revoke ${getTargetContext().packageName} $it")    }}

If you run your tests from a shell script, you can simply use ONE of the following shell commands before starting each test.

adb shell pm revoke com.package.appname android.permission.CAMERAadb shell pm reset-permissions com.package.appnameadb shell pm clear com.package.appname

The same crash happens whether you revoke permissions from a custom AndroidJUnitRunner's onCreate() or onStart() or from the middle of a test. You cannot revoke permissions during an instrumentation test without crashing even when the activity is not opened yet.

It seems like the best option is to revoke all permissions from Gradle before running any instrumentation test and then you can re-enable any permissions you want set before the test starts using a GrantPermissionRule.

The Android Test Orchestrator was planned to clear all data automatically between each test, but that feature is still not there today. I filed a bug you can vote up to have automatic cleanup between tests.


I'm not sure on how to do that at runtime without prompting the user. However, you stated in the title that it is for test purposes. Therefore I have some options i can suggest you

a)When testing need be done without permissions, just revoke it manually using the settings of your device.

b) You could check and ask for permission, then refuse to give permission. I'd give you some code I use to check and ask for camera permission. You'd just have to change the permission name, and maybe the condition to check :

public static boolean checkCameraPermission(MainActivity thisActivity) {    return ContextCompat.checkSelfPermission(thisActivity,            Manifest.permission.CAMERA)            == PackageManager.PERMISSION_GRANTED;}public static void checkAndAskCameraPermission(final MainActivity thisActivity) {    if (!checkCameraPermission(thisActivity)) {        //No right is granted        // Should we show an explanation?        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,                Manifest.permission.CAMERA)) {            //Open a dialog explaining why you are asking permission then when when positive button is triggered, call this line            ActivityCompat.requestPermissions(thisActivity,                            new String[]{Manifest.permission.CAMERA},                            CHECK_FOR_CAMERA_PERMISSION);        } else {            // No explanation needed, we can request the permission.            ActivityCompat.requestPermissions(thisActivity,                    new String[]{Manifest.permission.CAMERA},                    CHECK_FOR_CAMERA_PERMISSION);        }    }}

I could give you some more links about the b) (how to ask permissions) if you need so (just comment it). However as i'm not sure this answer would interest you, i won't spend time to document this option.

But then, maybe someone will be able to explain you how to do it directly at runtime without prompting, but I though it may be interesting to provide you at least this information.