Android M and permissions

Has anyone else started looking into using Appium with Android M? With the new permissions model, any app that requires non-normal permissions will need to have them added. I’d like Appium to detect that the Android version is >= 6.0 and use the -g flag during install to make certain it gets all desired permissions.

3 Likes

Any news on this? It would be nice to have something like iOS’s autoAcceptAlerts capability to dismiss the permission dialogs.

In the scenario where I’m using Appium we rely on other components that will keep adb and well as appium server up and running. So for the automation solution Appium is the only interface interacting with Android device.

Not being able to set permission via appium is creating huge blocker. Any news how this could be solved without using adb shell commands?

We’ve added the screens to our work flow. We have a screen factory which detects the screen type based on the activity. Once we know it’s a permission request, we parse the text to determine which one so we can take the appropriate action (usually “accept”).

2 Likes

So your approach is to check the screen for permission popup dialogs after application has started and dismiss/accept? You are able to access these dialogs using Appium?

@mkoppel: Yes, and yes.

@willosser I made a simple example on how to accept the android Marshmallow request permissions,
check it out:

Hope this helps,

1 Like

@vrunoa, that looks great.

Back to my original point, I believe it would be preferable to have a capability that installs the application with all permissions by default. I’ve extended the use of adb on our project so I can do just that.

@willosser
On Android 6 you can no longer use all the dangerous permissions by default. Every android app should use the ActivityCompat.requestPermissions before use any dangerous API.
For example; if you try to use the camera without the write_external permission accepted by the user, the camera will silently fail by giving you a null pointer to the taken picture. It can also crash with other permission not accepted.

The request permission flow is quite important now because you may want to take different action if the user did not accept any of some of them. So, my opinion is that you should definitely test this flow, instead of trying to set all the permission by default. That just my opinion.

Is there any other upadate on this permissions issue with Android M. I am stuck with this issue.
@vrunoa could you please provide the above code in Java.
I would really appreciate it.

Thanks

1 Like

@vrunoa, I have lots of tests that verify we can add the permissions, that we don’t have expected functionality without the permissions, and that taking those steps without those permissions will cause the app to prompt the user for the necessary permissions. I have far more tests that require all the permissions to be present, and I frequently have to reinstall the app. Adding the permissions each time takes time, and I’d prefer my tests be as quick as possible.

@willosser, can you please share your java code to read the permission alert text and click on accept / dismiss ?

I can’t, @kskrishnan, because our code is written in Ruby :slight_smile:

Appium gives you an API that detects the activity. Depending upon the device, you could get two different activities - the package name may get stripped off or not:

‘com.android.packageinstaller.permission.ui.GrantPermissionsActivity’,
‘.permission.ui.GrantPermissionsActivity’

When you detect this activity, you need to find an element by id:

‘com.android.packageinstaller:id/permission_message’

Then you can obtain the text of that message if you are interested in it. If you care which permission it is, you can match it against expected strings or regular expressions. If not, you can blindly accept by finding and clicking the element by id:

‘com.android.packageinstaller:id/permission_allow_button’

If you’d rather not click ‘allow’ on all those windows, you can use adb to add all the permissions at once before you start testing (but after Appium has installed your app). If you know all the perms your app will need, you can add them with one command:

pm grant $app_name $space_delimited_set_of_perms

Or you can add all perms one at a time, which takes 1.5-2 seconds per attempt.

1 Like

@willosser - Thanks a ton, works like a charm. However, I wonder it might just be easier if autoAcceptAlerts is made to work in this case. Nevertheless, thanks a lot for your tip - really helped.

Facing the following issue:
Waiting for pkg: ‘com.sample.testapp’ and activity: ‘com.sample.testapp.MainActivity’ to be focused
2016-10-12 12:11:18:231 - [debug] [ADB] Possible activities, to be checked: com.sample.testapp.MainActivity, .com.sample.testapp.MainActivity

Found package: ‘com.android.packageinstaller’ and activity: ‘.permission.ui.GrantPermissionsActivity’ 2016-10-12 11:27:05:996 - [debug] [ADB] Incorrect package and activity. Retrying.

After Opening an app there is a permission request dialog appearing, i tried to click using the following line of code in java:
driver.findElement(By.id(“com.android.packageinstaller:id/permission_allow_button”)).click();

This is not working. Getting the same error on the appium server as the correct package is not found. can any one suggest me an idea of how to choose the accept button.

Facing this issue in Android N and in Marshmallow.

our client asking permissions on start. how we do it.

  1. Start driver with:

Android 6.0:

capabilities.setCapability(“appWaitPackage”, “com.android.packageinstaller”);
capabilities.setCapability(“appWaitActivity”, “.permission.ui.GrantPermissionsActivity”);

Android 7.0:

capabilities.setCapability(“appWaitPackage”, “com.google.android.packageinstaller”);
capabilities.setCapability(“appWaitActivity”, “com.android.packageinstaller.permission.ui.GrantPermissionsActivity”);

Buttons in dialog have ids:

  • “permission_deny_button”
  • “permission_allow_button”

use:

driver.findElement(MobileBy.id(“permission_allow_button”)).click();

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(“platformName”, “Android”);
capabilities.setCapability(CapabilityType.VERSION, “7.0”);
capabilities.setCapability(“newCommandTimeout”, 1800);
capabilities.setCapability(“appWaitPackage”, “com.google.android.packageinstaller”);
capabilities.setCapability(“appWaitActivity”, “com.android.packageinstaller.permission.ui.GrantPermissionsActivity”);
// capabilities.setCapability(“appWaitDuration”, 4000);
capabilities.setCapability(“autoAcceptAlerts”, true);
capabilities.setCapability(“deviceName”, “Android 7.0”);
capabilities.setCapability(“app”, app.getAbsolutePath());

AndriodDriver
driver = new AndroidDriver(address, getDesiredCapabilities(app));
driver.manage().timeouts().implicitlyWait(80, TimeUnit.SECONDS);
driver.findElement(MobileBy.id(“permission_allow_button”)).click();

This is my code.

But still getting the same error.

2016-10-12 13:28:03:442 - [debug] [UiAutomator] Starting UIAutomator
2016-10-12 13:28:03:443 - [debug] [ADB] Creating ADB subprocess with args: -P, 5037, -s, 00d7c559893a2190, shell, uiautomator, runtest, AppiumBootstrap.jar, -c, io.appium.android.bootstrap.Bootstrap, -e, pkg, com.bits42.admob, -e, disableAndroidWatchers, false, -e, acceptSslCerts, false
2016-10-12 13:28:04:431 - [debug] [UiAutomator] Moving to state ‘online’
2016-10-12 13:28:04:437 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] json loading complete.
2016-10-12 13:28:04:439 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Registered crash watchers.
2016-10-12 13:28:04:443 - [AndroidBootstrap] Android bootstrap socket is now connected
2016-10-12 13:28:04:451 - [debug] [ADB] Device API level: 24
2016-10-12 13:28:04:452 - [debug] [ADB] Getting connected devices…
2016-10-12 13:28:04:459 - [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Client connected
2016-10-12 13:28:04:461 - [debug] [ADB] 2 device(s) connected
2016-10-12 13:28:04:462 - [debug] [ADB] Running ‘/home/afrin/Android/Sdk/platform-tools/adb’ with args: ["-P",5037,"-s",“00d7c559893a2190”,“shell”,“am”,“start”,"-W","-n","'com.sample.testapp/'com.sample.testapp.MainActivity","-S","-a",“android.intent.action.MAIN”,"-c",“android.intent.category.LAUNCHER”,"-f",“0x10200000”]
2016-10-12 13:28:06:218 - [debug] [ADB] Waiting for pkg: ‘com.google.android.packageinstaller’ and activity: ‘com.android.packageinstaller.permission.ui.GrantPermissionsActivity’ to be focused
2016-10-12 13:28:06:221 - [debug] [ADB] Possible activities, to be checked: com.android.packageinstaller.permission.ui.GrantPermissionsActivity, .com.android.packageinstaller.permission.ui.GrantPermissionsActivity
2016-10-12 13:28:06:225 - [debug] [ADB] Getting focused package and activity
2016-10-12 13:28:06:227 - [debug] [ADB] Getting connected devices…
2016-10-12 13:28:06:236 - [debug] [ADB] 2 device(s) connected
2016-10-12 13:28:06:237 - [debug] [ADB] Running ‘/home/afrin/Android/Sdk/platform-tools/adb’ with args: ["-P",5037,"-s",“00d7c559893a2190”,“shell”,“dumpsys”,“window”,“windows”]
2016-10-12 13:28:06:293 - [debug] [ADB] Found package: ‘com.android.packageinstaller’ and activity: ‘.permission.ui.GrantPermissionsActivity’
2016-10-12 13:28:06:294 - [debug] [ADB] Incorrect package and activity. Retrying.
2016-10-12 13:28:07:047 - [debug] [ADB] Getting focused package and activity
2016-10-12 13:28:07:049 - [debug] [ADB] Getting connected devices…
2016-10-12 13:28:07:066 - [debug] [ADB] 2 device(s) connected
2016-10-12 13:28:07:067 - [debug] [ADB] Running ‘/home/afrin/Android/Sdk/platform-tools/adb’ with args: ["-P",5037,"-s",“00d7c559893a2190”,“shell”,“dumpsys”,“window”,“windows”]

you have android 6.0

No i am currently running this test in Android 7.0 Android device.

no matter then try what i wrote for Android 6.0 capabilities.