问题:在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 以上权限受限问题的更多相关文章

  1. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  2. Android6.0获取权限

    照着<第一行代码>打代码,然并卵,感叹技术进步的神速.最后提醒一点:IT类的书籍一定要注意出版时间!出版时间!出版时间!重要的事情说三遍 问题出在android6.0的权限获取问题上,以前 ...

  3. xcode7.3 升级 xcode8.0 后权限设置问题(升级xcode 8.0 后构建版本不显示问题)

    xcode7.3 升级 xcode8.0 后权限设置问题(升级xcode 8.0 后构建版本不显示问题) 前两天为了适配 iOS10 的系统 我将xcode 7.3 升级到了 xcode 8.0 但是 ...

  4. MongoDB 3.0安全权限访问控制(Windows版)

    MongoDB 3.0安全权限访问控制(Windows版) 1.首先,不使用 –auth 参数,启动 mongoDB: mongod --dbpath "d:\mongodb\data\db ...

  5. 安装robotframework时提示权限受限

    mba下准备装robotframework,python已默认装好,按照如下的教程继续按照robotframework,发现会提示权限受限,如图. 第二步: 安装 robotframework下载地址 ...

  6. Android 6.0之权限管理

    安卓6.0的权限体系分为非敏感权限和敏感权限,非敏感权限默认获取,可以手动关闭. 敏感权限必须由app在运行时动态申请.而存储读写空间权限是一个敏感权限,不是一个“很正常的必须权限”. 安卓并不是想要 ...

  7. Android 6.0的权限问题

    Android 6.0的权限获取不同于别的版本,具体的实例如下: if (ContextCompat.checkSelfPermission(this, Manifest.permission.REA ...

  8. Android开发之深入理解Android 7.0系统权限更改相关文档

    http://www.cnblogs.com/dazhao/p/6547811.html 摘要: Android 6.0之后的版本增加了运行时权限,应用程序在执行每个需要系统权限的功能时,需要添加权限 ...

  9. android 6.0+ 动态权限 拒绝不再询问后跳转设置应用详情页面

    android 6.0+ 的权限 需要动态申请 这里的权限针对的是 敏感权限: SMS(短信) SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEI ...

随机推荐

  1. Django的csrf中间件

    csrf中间件 ​ csrf 跨站请求伪造 ​ 补充两个装饰器: ​ from django.views.decorators.csrf import csrf_exempt,csrf_protect ...

  2. Hbase思维导图之数据存储

  3. java中的绝对路径和相对路径

    1.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件或目录在硬盘上真正的路径,(URL和物理路径)例如:C:/xyz/test.txt 代表了test.txt文件的绝对路径.http://www ...

  4. git操作手册

    git教案链接:https://git-scm.com/book/zh/v2 1.1 起步 - 关于版本控制 于是分布式版本控制系统(Distributed Version Control Syste ...

  5. Javascript入门(三)函数

    Javascript函数 一.函数定义与执行 <script type="text/javascript"> //define function fun1(){ ale ...

  6. MyBatis中---数据库配置的属性名冲突问题

    一.db.properties 属性文件中 最好加特殊的标志前缀  jdbc.username ,如果单纯的username有可能影响到 mapper.xml中的 ${username}; 举例   ...

  7. Vue.js简单记录

    官网:https://cn.vuejs.org/ https://cn.vuejs.org/v2/api/#methods v-bind 缩写 <!-- 完整语法 --> <a v- ...

  8. Maven多模块项目管理小结

    原文地址:http://blog.csdn.net/whuslei/article/details/7989102 题记 最近刚完成一个用Maven构建的Web项目,看了一些Maven方面的书,比如& ...

  9. Django学习手册 - 创建Django工程项目以及APP

    前置步骤: 下载python,django 并且安装好 python 解释器以及django模块. 整体步骤阐述: 创建django工程项目 步骤一:进入安装的python目录 步骤二:输入创建工程的 ...

  10. 【转载】使用python库--Graphviz为论文画出漂亮的示意图

    原文: Drawing Graphs using Dot and Graphviz 1 License Copyright (C) 2013, 2014, 2015, 2016, 2017, 2018 ...