Uiautomator - 6.0 以上权限受限问题
问题:在android studio中使用UiAutomator 2.0 编写测试用例时,要实现截图(非命令方式),写入文件时出现权限被拒绝的提示。例如:
java.io.FileNotFoundException: /storage/emulated/0/uidump.xml (Permission denied)
注:通过命令的方式进行截图/创建文件不会出现权限受限问题,凡是通过IO流、File类进行文件读写等方式的操作,都需要添加权限并打开权限,才能正常运行成功。
解决:在当前测试脚本所在的 module的AndroidManifest.xml文件中添加读写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
你以为只要添加以上权限就够了吗?NO,那仅仅是添加了该app的读写权限而已,并没有打开权限,所以还是被拒绝的。下面则通过几种方式进行打开权限:
1.手动打开权限:设置->应用->目标应用->权限->存储 。打开该权限即可。
2.脚本中打开权限:通过UI界面操作打开 或者 使用命令进行打开。这里用命令的方式打开权限。
adb shell pm grant 包名 权限
adb shell pm grant com.android.contacts android.permission.READ_EXTERNAL_STORAGE
adb shell pm grant com.android.contacts android.permission.WRITE_EXTERNAL_STORAGE
顺便这里提及一下查看包名和权限命令(adb命令那篇中也有):
那么Uiautomator脚本中怎么写呢?(这是最直接的写法。如果有多个权限,可以通过Android API获取程序的所有权限,然后再打开所有权限即可)
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
.executeShellCommand("pm grant com.android.contacts android.permission.READ_EXTERNAL_STORAGE");
写一个工具类来打开权限
package com.zzw.systemutils; import android.app.Instrumentation; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.support.annotation.Nullable; import android.support.test.InstrumentationRegistry; import android.support.test.uiautomator.UiDevice; import android.util.Log; import junit.framework.Assert; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * Created by pc-zzw on 2017/12/4. * 权限处理 SDK >= M * pm list permissions : All Permissions * pm list permission-groups : All Permission Groups */ public class Permissions { private static Instrumentation instrument= InstrumentationRegistry.getInstrumentation(); private static UiDevice mDevice= UiDevice.getInstance(instrument); /** * grant 命令处理当前程序(module app)的权限 * @param permission such as : android.permission.WRITE_EXTERNAL_STORAGE * @throws IOException IO */ public static void grantCurrentPermission(String permission) throws IOException { grantPermission(instrument.getTargetContext().getPackageName(),permission); } /** * grant 命令处理当前程序(module app)的所有权限 * @throws IOException IO */ public static void grantCurrentAllPermissions() throws IOException { grantAllPermissions(instrument.getTargetContext().getPackageName()); } /** * grant 命令处理应用的权限 * @param packageName such as : com.zzw.testdome * @param permission such as : android.permission.WRITE_EXTERNAL_STORAGE * @throws IOException IO */ public static void grantPermission(String packageName , String permission) throws IOException { Assert.assertNotNull(packageName); Assert.assertNotNull(permission); Log.e("grantPermission: ",packageName+" "+permission); String cmd = String.format("pm grant %s %s",packageName , permission); String result = mDevice.executeShellCommand(cmd); Assert.assertTrue(result == null || !result.contains("Err")); } /** * 使用命令处理应用的所有权限 * @param packageName Application Package Name */ public static void grantAllPermissions(String packageName) throws IOException { Context context=instrument.getTargetContext(); PackageInfo packageInfo = getPackageInfo(context, packageName); String[] permissions ; if (packageInfo != null) { permissions = packageInfo.requestedPermissions; permissions = extractUnGranted(context, packageName, permissions); if(permissions == null) return; for (String p : permissions) { Log.i("grantAllPermissions: ",packageName+"----"+p); grantPermission(packageName, p); } } } //提取未授权的权限 private static String [] extractUnGranted(Context context,String packageName,String[] declaredPerms){ if (declaredPerms == null || declaredPerms.length == 0) return null; PackageManager packageManager = context.getPackageManager(); List<String> requestList = new ArrayList<>(declaredPerms.length); for (String permName : declaredPerms) { // 检查权限是否已授权 int code = packageManager.checkPermission(permName, packageName); if (code == PackageManager.PERMISSION_GRANTED) continue; requestList.add(permName); } String[] unGranted = new String[requestList.size()]; for (int i = 0; i < requestList.size(); i++) { unGranted[i] = requestList.get(i); } return unGranted; } //获取包的权限信息 @Nullable private static PackageInfo getPackageInfo(Context context, String packageName){ PackageManager packageManager = context.getPackageManager(); try { return packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); } catch (PackageManager.NameNotFoundException e) { return null; } } }
最后这里贴出官网上系统权限部分>>>>>>>>>>>>