問題:在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; } } }
最後這裏貼出官網上系統權限部分>>>>>>>>>>>>