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;
}
}
}
最后这里贴出官网上系统权限部分>>>>>>>>>>>>
Uiautomator - 6.0 以上权限受限问题的更多相关文章
- Android 6.0 - 动态权限管理的解决方案
Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...
- Android6.0获取权限
照着<第一行代码>打代码,然并卵,感叹技术进步的神速.最后提醒一点:IT类的书籍一定要注意出版时间!出版时间!出版时间!重要的事情说三遍 问题出在android6.0的权限获取问题上,以前 ...
- xcode7.3 升级 xcode8.0 后权限设置问题(升级xcode 8.0 后构建版本不显示问题)
xcode7.3 升级 xcode8.0 后权限设置问题(升级xcode 8.0 后构建版本不显示问题) 前两天为了适配 iOS10 的系统 我将xcode 7.3 升级到了 xcode 8.0 但是 ...
- MongoDB 3.0安全权限访问控制(Windows版)
MongoDB 3.0安全权限访问控制(Windows版) 1.首先,不使用 –auth 参数,启动 mongoDB: mongod --dbpath "d:\mongodb\data\db ...
- 安装robotframework时提示权限受限
mba下准备装robotframework,python已默认装好,按照如下的教程继续按照robotframework,发现会提示权限受限,如图. 第二步: 安装 robotframework下载地址 ...
- Android 6.0之权限管理
安卓6.0的权限体系分为非敏感权限和敏感权限,非敏感权限默认获取,可以手动关闭. 敏感权限必须由app在运行时动态申请.而存储读写空间权限是一个敏感权限,不是一个“很正常的必须权限”. 安卓并不是想要 ...
- Android 6.0的权限问题
Android 6.0的权限获取不同于别的版本,具体的实例如下: if (ContextCompat.checkSelfPermission(this, Manifest.permission.REA ...
- Android开发之深入理解Android 7.0系统权限更改相关文档
http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...
- android 6.0+ 动态权限 拒绝不再询问后跳转设置应用详情页面
android 6.0+ 的权限 需要动态申请 这里的权限针对的是 敏感权限: SMS(短信) SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEI ...
随机推荐
- 合肥学院第二届卓越IT-程序设计大赛E+J
E链接 小飞有nn的魔法纸片(可以变出糖果), 现在有m个人来找小飞玩游戏, 小飞希望用魔法纸片来使朋友们开心,纸片可以被随便裁剪,nn的魔法纸片可以裁剪成任意大小的小魔法纸片,小飞通过pubgoso ...
- jq的css方法
读属性: $(selector).css(name) 设置属性: 法一: $(selector).css(name,value) 法二: $(selector).css(name,function(i ...
- D - Stone Division HackerRank - stone-division (博弈+搜索)
题目链接:https://cn.vjudge.net/problem/HackerRank-stone-division 题目大意:给你n,m,然后是m个数.每一次你可以选择一个a[i],如果能被n整 ...
- python 微信跳一跳辅助 复现
本来用的是苹果ios得手机,但是步骤较为复杂,没有吃透,最后妥协用了android的机器搞得. 首先找到大牛的github https://github.com/wangshub/wechat_jum ...
- python,类和对象(一)
万物皆对象,在python中也存在对象,首先我们需要知道面向对象的三大特征封装.继承.多态. 封装就是将一种或多种杂乱无序的代码进行有序的分类封装. 继承可以理解为孩子会继承父亲所有的东西. 多态可以 ...
- 安装mysql8.0.12以及修改密码和Navicat的连接
mysql8.0+与安装其他版本不同一.安装mysql8.0.121.到官网https://www.mysql.com/ 下载mysql-8.0.12-winx64.zip(不要.mis),直接解压 ...
- Informatic 使用过程中的问题
1.database driver error ORA-12154 1)检查监听是否启动 2)是否在tnsnames.ora中配置
- JDK源码笔记--Object
public final native Class<?> getClass(); public native int hashCode(); public boolean equals(O ...
- Sql Server中的数据类型和Mysql中的数据类型的对应关系(转)
Sql Server中的数据类型和Mysql中的数据类型的对应关系(转):https://blog.csdn.net/lilong329329/article/details/78899477 一.S ...
- python练习实例
#!/usr/bin/python # -*- coding: UTF-8 -*- try: fh = open("testfile","w") fh.writ ...