问题:在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. html页面设置<span>的高度和宽度

    <span>标签属于行内元素(inline),所以无法设置高度和宽度:如果需要改变其宽高,就需要将其转变为块体元素(block)或行内块体元素(inle-block): 1 span{di ...

  2. @Component注解的解析

    今天在写程序的时候看见一个以前没有见过的注解(@Component),在网上查找过后,经过实践,决定把它记录下来. 1.@controller 控制器(注入服务) 用于标注控制层,相当于struts中 ...

  3. python常用模块之os模块

    全部参考~~~~~~~ 1. 解释说明版:https://www.cnblogs.com/yufeihlf/p/6179547.html 2. 简洁版: https://www.cnblogs.com ...

  4. springboot-菜鸟学习1

    一.SpringBoot 快速开始 进入 https://start.spring.io/ 给项目命名 引入所需要的jar包支持 一般需要 jpa.freemarker.mysql.web等 在IDE ...

  5. 使用recyclerView item布局match_parent属性失效的问题

    https://blog.csdn.net/overseasandroid/article/details/51840819

  6. 832B Petya and Exam

    题意:给你两个串,第一个串里面的字母都是good 字母, 第二个串是模式串,里面除了字母还有?和*(只有一个) ?可以替换所有good字母, *可以替换所有坏字母和空格(可以是多个坏字母!!!这点卡了 ...

  7. git 上传代码

    1.注册GitHub账号 2.在GitHub上建立github仓库 3.下载git 4.配置git 5.生成SSH密钥,并把密钥添加SSH密钥到GitHub上 6.创建本地仓库并上传代码到github ...

  8. 使用@RequestBody将请求体映射到Action方法参数中

    @PostMapping("/user") public User create(@RequestBody User user){ System.out.println(user. ...

  9. 【转】python模块分析之hashlib加密(二)

    [转]python模块分析之hashlib加密(二) hashlib模块是用来对字符串进行hash加密的模块,明文与密文是一一对应不变的关系:用于注册.登录时用户名.密码等加密使用.一.函数分析:1. ...

  10. Linker Scripts3--MEMORY Command

    1.前言 链接器的默认配置允许所有有效内存的分配,你可以使用MEMORY命令来重新定义它 2.MEMORY命令 MEMORY命令描述了一个内存块的位置和大小.你可以用它来描述哪块内存区域可以被链接器使 ...