问题:在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. cocos2d 图片模糊

    CCSprite texture setAliasTexParameters -->opengl 的功能 将图片柔化

  2. Kaldi的nnet2 Component

    FixedAffineComponent:类 LDA-like 的非相关转换,由标准的 weight matrix plus bias 组成(即Wx+b),通过标准的 stochastic gradi ...

  3. shell实现带颜色输出的进度条

    1.基础版 #!/bin/bash b='' ;$i<=;i+=)) do printf "执行进度 :[%-50s]%d%%\r" $b $i sleep 0.001 b= ...

  4. 将web项目导入到eclipse中常见错误

     将web项目导入到eclipse中常见错误  错误1:string cannot be resolved to a type  原因:这种情况一般是因为你的JDK版本没有设置好,或者设置的有不一致的 ...

  5. Java创建文件和文件夹

    java代码: import java.io.*;//导入所需的包public class IOTest {//类 public static void main(String[] args){//主 ...

  6. Applet、Scriptlet与Servlet

    Applet.Scriptlet与Servlet - 青春念邵的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/mo_fan_qing_wa/article/deta ...

  7. linux 日志管理

  8. 创建 Pull Request

    Pull Request 是开发者使用 GitHub 进行协作的利器.这个功能为用户提供了友好的页面,让提议的更改在并入官方项目之前,可以得到充分的讨论. 最简单地来说,Pull Request 是一 ...

  9. webgl开发中添加IIS的mime类型

    1.在iis中直接设置 .obj application/octet-stream .mtl application/octet-stream 2.在配置文件中加 <?xml version=& ...

  10. 关于iframe的相关操作

    1.判断当前页面是否在iframe当中 if (top.location != self.location) { alert("in iframe") }