zoukankan      html  css  js  c++  java
  • Uiautomator

    问题:在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;
            }
        }
    }
    View Code

    最后这里贴出官网上系统权限部分>>>>>>>>>>>>

  • 相关阅读:
    计算机编程基础
    css3 压缩及验证工具
    BFC
    【原创】bootstrap框架的学习 第五课
    曼珠沙华
    仓央嘉措
    waiting for spring......
    一天
    21-chttp连接池该取多大
    守护线程会不会执行finally?默认情况new thread怎么样确定守护状态?
  • 原文地址:https://www.cnblogs.com/zeo-to-one/p/8322114.html
Copyright © 2011-2022 走看看