因為要做自動化測試,需要對已發布的包進行回歸手測,這個時候需要手動安裝APK,但是紅米會彈出繼續安裝的按鈕,手點一次比較煩,想自動點"繼續安裝"按鈕!
感謝先行者們的分享
本文參考:
http://blog.csdn.net/itfootball/article/details/21953763
https://testerhome.com/topics/3800
http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html
0. 干貨區
如果你想知道一下什么是AccessibilityService,可自行搜索學習或看官方介紹 http://developer.android.com/reference/android/accessibilityservice/AccessibilityService.html
開啟方法:
普通手機: 設置 -> 無障礙/輔助功能 -> 服務 -> AutoInstall -> 開啟 -> 確定
某些手機:設置 -> 其它高級設置 -> 輔助功能 -> 服務 -> AutoInstall -> 開啟 -> 確定
注意:
開啟自動安裝不僅適用於adb install,也適用於主動點擊apk來啟動安裝。所以有安全風險,建議僅在測試機器上安裝
git地址 https://github.com/guhan121/autoinstall.git
1. 代碼區
不需要Activity,僅需要一個繼承AccessibilityService的服務,在服務里兼聽onAccessibilityEvent,當出現安裝界面的時候,自動去點擊。在安裝完成后,到輔助功能里開啟即可。
AutoInstallService.java
package com.mrqyoung.autoinstall; import android.accessibilityservice.AccessibilityService; import android.util.Log; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import java.util.List; public class AutoInstallService extends AccessibilityService { private static final String TAG = "AutoInstallService"; private static String PACKAGE_INSTALLER = "com.miui.securitycenter"; public AutoInstallService() { } @Override public void onAccessibilityEvent(AccessibilityEvent event) { //log(event.toString()); if (event.getSource() == null) { log("<null> event source"); return; } int eventType = event.getEventType(); if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { log("event Perform: " + event.getPackageName()); if( event.getPackageName().equals(PACKAGE_INSTALLER)) { boolean r = performInstallation(event); log("Action Perform: " + r); } } } @Override public void onInterrupt() { log("AutoInstallServiceInterrupted"); } private void log(String s) { Log.d(TAG, s); } private boolean performInstallation(AccessibilityEvent event) { List<AccessibilityNodeInfo> nodeInfoList; String[] labels = new String[]{"確定", "繼續安裝", "下一步", "完成"}; for (String label : labels) { nodeInfoList = event.getSource().findAccessibilityNodeInfosByText(label); if (nodeInfoList != null && !nodeInfoList.isEmpty()) { boolean performed = performClick(nodeInfoList); if (performed) return true; } } return false; } private boolean performClick(List<AccessibilityNodeInfo> nodeInfoList) { for (AccessibilityNodeInfo node : nodeInfoList) { if (node.isClickable() && node.isEnabled()) { return node.performAction(AccessibilityNodeInfo.ACTION_CLICK); } } return false; } }
AndroidManifest里面要聲明權限,除了上面從代碼里面可以過濾,通過meta-data的xml里也可直接配置過濾
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.mrqyoung.autoinstall" > <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Black" > <service android:name=".AutoInstallService" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"> <intent-filter> <action android:name="android.accessibilityservice.AccessibilityService" /> </intent-filter> <meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibilityservice" /> </service> </application> </manifest>
在AndroidManifest里面引用的meta-data文件,樣例。
@xml/accessibilityservice.xml
<?xml version="1.0" encoding="utf-8"?> <accessibility-service android:accessibilityEventTypes="typeWindowStateChanged" android:description="@string/description" android:accessibilityFeedbackType="feedbackVisual" android:notificationTimeout="1000" android:accessibilityFlags="flagDefault" android:canRetrieveWindowContent="true" xmlns:android="http://schemas.android.com/apk/res/android" />
<!-- 第3行等同於過濾 AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED -->
<!--
android:packageNames="com.android.packageinstaller" 無這個參數主要是開始也不知道那個包在管理安裝
-->
gradle build 編譯,使用的是2.2版本的gradle
adb uninstall com.mrqyoung.autoinstall 卸載這個應用
adb install app-debug.apk 將這個應用直接從PC機安裝到手機上,當然第一次你需要手動點"繼續安裝"