Uiautomator - 6.0 以上權限受限問題

問題:在android studio中使用UiAutomator 2.0 編寫測試用例時,要實現截圖(非命令方式),寫入文件時出現權限被拒絕的提示。例如:html

java.io.FileNotFoundException: /storage/emulated/0/uidump.xml (Permission denied)java

注:經過命令的方式進行截圖/建立文件不會出現權限受限問題,凡是經過IO流、File類進行文件讀寫等方式的操做,都須要添加權限並打開權限,才能正常運行成功。android

解決:在當前測試腳本所在的 module的AndroidManifest.xml文件中添加讀寫權限shell

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

你覺得只要添加以上權限就夠了嗎?NO,那僅僅是添加了該app的讀寫權限而已,並無打開權限,因此仍是被拒絕的。下面則經過幾種方式進行打開權限:app

1.手動打開權限:設置->應用->目標應用->權限->存儲 。打開該權限便可。dom

2.腳本中打開權限:經過UI界面操做打開 或者 使用命令進行打開。這裏用命令的方式打開權限。ide

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獲取程序的全部權限,而後再打開全部權限便可)ui

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

 

 

 

 

 

最後這裏貼出官網上系統權限部分>>>>>>>>>>>>

相關文章
相關標籤/搜索