pbelov
pbelov

Reputation: 455

How to request permissions on Android Marshmallow for JUnit tests

I want to execute JUnit tests against my lib and want to ask user to grant all required permissions before the test starts (because I need to read some files from device storage during the automated tests for example).

I know how to make it by adding a task to gradle and run it from cmd, it is working well. But I need to ask user (or do it automatically) when I ran my tests using IDE.

I've tried to add permission request to MainActivity.onCreate() of test app but no luck because MainActivity starts not for all tests.

Do anyone have any ideas?

Also, please do not talk about adding gradle grant task to execution configuration. it is working but unusable, needs something more unified.

Upvotes: 1

Views: 1925

Answers (4)

SakurajimaMaii
SakurajimaMaii

Reputation: 61

Here is a example in kotlin:

@RunWith(AndroidJUnit4::class)
class CameraTest {

    @Rule
    fun runtimePermissionRule() = GrantPermissionRule.grant(Manifest.permission.CAMERA)

}

Or like this:

val runtimePermissionRule: GrantPermissionRule
    @Rule get() = GrantPermissionRule.grant(Manifest.permission.CAMERA)

Upvotes: 0

Monster Brain
Monster Brain

Reputation: 2119

Logcat warning seems to be recommending uiAutomation.grantRuntimePermission instead of pm grant.

Instead of adb shell command, we can use (without deprecated methods) in kotlin ..

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
getInstrumentation().uiAutomation.grantRuntimePermission(ApplicationProvider.getApplicationContext<Context>().packageName, "android.permission.BLUETOOTH")
}

Upvotes: 0

Eyal Cinamon
Eyal Cinamon

Reputation: 949

A better way, since API version 23 (Android M):

@Rule
public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(Manifest.permission.ACCESS_FINE_LOCATION);
...

Upvotes: 3

pbelov
pbelov

Reputation: 455

I found a solution to my problem. It was easy:

needs to create a new task in app-level build.gradle file like this:

android.applicationVariants.all { variant ->
    def applicationId = variant.applicationId
    def adb = android.getAdbExe().toString()
    def variantName = variant.name.capitalize()
    def grantPermissionTask = tasks.create("create${variantName}Permissions") << {
        println "Granting permissions"
        "${adb} shell pm grant ${applicationId} android.permission.ACCESS_FINE_LOCATION".execute()
        "${adb} shell pm grant ${applicationId} android.permission.WRITE_EXTERNAL_STORAGE".execute()
        "${adb} shell pm grant ${applicationId} android.permission.READ_EXTERNAL_STORAGE".execute()
    }
}

then add the following dependency:

preBuild.dependsOn "createDebugPermissions"

after that, all required permissions will be granted when you run any test

Upvotes: 2

Related Questions