Android Accessibility(輔助功能) --實現Android應用自動安裝、解除安裝 .
對於那些由於視力、聽力或其它身體原因導致不能方便使用Android智慧手機的使用者,Android提供了Accessibility功能和服務幫助這些使用者更加簡單地操作裝置,包括文字轉語音、觸覺反饋、手勢操作、軌跡球和手柄操作。開發者可以搭建自己的Accessibility服務,這可以加強可用性,例如聲音提示,物理反饋,和其他可選的操作模式。
隨著Android版本的不斷升級,Android Accessibility功能也越來越強大,Android 4.0版本以前,系統輔助服務功能比較單一,僅僅能過單向獲取視窗元素資訊,比如獲取輸入框使用者輸入內容。到Android 4.1版本以後,系統輔助服務增加了與視窗元素的雙向互動,此時可以通過輔助功能服務操作視窗元素,比如點選按鈕等。
由於系統輔助服務能夠實時獲取您當前操作應用的視窗元素資訊,這有可能給你帶來隱私資訊的洩露風險,比如獲取非密碼輸入框的輸入內容等。同時通過輔助功能也可以模擬使用者自動化點選應用內元素,也會帶來一定的安全風險。
本文實現了一種通過系統輔助服務完成應用的自動安裝、解除安裝、強行停止的功能。
1、AndroidManifest.xml檔案配置自己實現的MyAccessibilityService服務。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jack.accessibility"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.jack.accessibility.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:label="@string/acc_service_name" android:name=".MyAccessibilityService" 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/phone_accessibility" />
</service>
</application>
</manifest>
2、在res/xml/phone_accessibility.xml配置相應的引數資訊。
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service android:description="@string/accessibility_service_description"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="100"
android:accessibilityFlags=""
android:canRetrieveWindowContent="true"
xmlns:android="http://schemas.android.com/apk/res/android" />
3、MainActivity實現安裝、解除安裝、強行停止動作的發起。
package com.jack.accessibility;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.view.View;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.findViewById(R.id.activeButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent killIntent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(killIntent);
}
});
this.findViewById(R.id.installButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
MyAccessibilityService.INVOKE_TYPE = MyAccessibilityService.TYPE_INSTALL_APP;
String fileName = Environment.getExternalStorageDirectory() + "/test.apk";
File installFile = new File(fileName);
if(installFile.exists()){
installFile.delete();
}
try {
installFile.createNewFile();
FileOutputStream out = new FileOutputStream(installFile);
byte[] buffer = new byte[512];
InputStream in = MainActivity.this.getAssets().open("test.apk");
int count;
while((count= in.read(buffer))!=-1){
out.write(buffer, 0, count);
}
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");
startActivity(intent);
}
});
this.findViewById(R.id.uninstallButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
MyAccessibilityService.INVOKE_TYPE = MyAccessibilityService.TYPE_UNINSTALL_APP;
Uri packageURI = Uri.parse("package:com.example.test");
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
}
});
this.findViewById(R.id.killAppButton).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
MyAccessibilityService.INVOKE_TYPE = MyAccessibilityService.TYPE_KILL_APP;
Intent killIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri packageURI = Uri.parse("package:com.example.test");
killIntent.setData(packageURI);
startActivity(killIntent);
}
});
}
}
4、MyAccessibilityService中通過自動化點選實現應用安裝、解除安裝、強行停止功能。
package com.jack.accessibility;
import java.util.List;
import android.accessibilityservice.AccessibilityService;
import android.annotation.SuppressLint;
import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@SuppressLint("NewApi")
public class MyAccessibilityService extends AccessibilityService {
public static int INVOKE_TYPE = 0;
public static final int TYPE_KILL_APP = 1;
public static final int TYPE_INSTALL_APP = 2;
public static final int TYPE_UNINSTALL_APP = 3;
public static void reset(){
INVOKE_TYPE = 0;
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
// TODO Auto-generated method stub
this.processAccessibilityEnvent(event);
}
private void processAccessibilityEnvent(AccessibilityEvent event) {
Log.d("test", event.eventTypeToString(event.getEventType()));
if (event.getSource() == null) {
Log.d("test", "the source = null");
} else {
Log.d("test", "event = " + event.toString());
switch (INVOKE_TYPE) {
case TYPE_KILL_APP:
processKillApplication(event);
break;
case TYPE_INSTALL_APP:
processinstallApplication(event);
break;
case TYPE_UNINSTALL_APP:
processUninstallApplication(event);
break;
default:
break;
}
}
}
@Override
protected boolean onKeyEvent(KeyEvent event) {
// TODO Auto-generated method stub
return true;
}
@Override
public void onInterrupt() {
// TODO Auto-generated method stub
}
private void processUninstallApplication(AccessibilityEvent event) {
if (event.getSource() != null) {
if (event.getPackageName().equals("com.android.packageinstaller")) {
List<AccessibilityNodeInfo> ok_nodes = event.getSource().findAccessibilityNodeInfosByText("確定");
if (ok_nodes!=null && !ok_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for(int i=0; i<ok_nodes.size(); i++){
node = ok_nodes.get(i);
if (node.getClassName().equals("android.widget.Button") && node.isEnabled()) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
}
}
private void processinstallApplication(AccessibilityEvent event) {
if (event.getSource() != null) {
if (event.getPackageName().equals("com.android.packageinstaller")) {
List<AccessibilityNodeInfo> unintall_nodes = event.getSource().findAccessibilityNodeInfosByText("安裝");
if (unintall_nodes!=null && !unintall_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for(int i=0; i<unintall_nodes.size(); i++){
node = unintall_nodes.get(i);
if (node.getClassName().equals("android.widget.Button") && node.isEnabled()) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
List<AccessibilityNodeInfo> next_nodes = event.getSource().findAccessibilityNodeInfosByText("下一步");
if (next_nodes!=null && !next_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for(int i=0; i<next_nodes.size(); i++){
node = next_nodes.get(i);
if (node.getClassName().equals("android.widget.Button") && node.isEnabled()) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
List<AccessibilityNodeInfo> ok_nodes = event.getSource().findAccessibilityNodeInfosByText("開啟");
if (ok_nodes!=null && !ok_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for(int i=0; i<ok_nodes.size(); i++){
node = ok_nodes.get(i);
if (node.getClassName().equals("android.widget.Button") && node.isEnabled()) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
}
}
private void processKillApplication(AccessibilityEvent event) {
if (event.getSource() != null) {
if (event.getPackageName().equals("com.android.settings")) {
List<AccessibilityNodeInfo> stop_nodes = event.getSource().findAccessibilityNodeInfosByText("強行停止");
if (stop_nodes!=null && !stop_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for(int i=0; i<stop_nodes.size(); i++){
node = stop_nodes.get(i);
if (node.getClassName().equals("android.widget.Button")) {
if(node.isEnabled()){
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
}
}
}
List<AccessibilityNodeInfo> ok_nodes = event.getSource().findAccessibilityNodeInfosByText("確定");
if (ok_nodes!=null && !ok_nodes.isEmpty()) {
AccessibilityNodeInfo node;
for(int i=0; i<ok_nodes.size(); i++){
node = ok_nodes.get(i);
if (node.getClassName().equals("android.widget.Button")) {
node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
Log.d("action", "click ok");
}
}
}
}
}
}
}
相關文章
- 使用Android Accessibility實現免Root自動批量安裝功能Android
- 濫用Accessibility service自動安裝應用
- 免root解除安裝Android預裝應用Android
- Android靜默安裝應用和靜默解除安裝應用Android
- Android應用如何監聽自己是否被解除安裝及解除安裝反饋功能的實現(第三版)Android
- Android程式碼實現APK檔案的安裝與解除安裝AndroidAPK
- android 程式碼安裝和解除安裝apkAndroidAPK
- android apk靜默安裝和解除安裝AndroidAPK
- Android應用如何監聽自己是否被解除安裝Android
- Android靜默安裝和靜默解除安裝Android
- Win10 - 解除安裝自帶應用Win10
- Android 解除安裝監聽詳解Android
- autodesk桌面應用程式可以解除安裝嗎 autodesk桌面應用程式怎麼解除安裝
- ubuntu如何完全解除安裝和安裝 Java及android環境?UbuntuJavaAndroid
- win10 自帶照片應用如何解除安裝_win10內建照片應用的解除安裝教程Win10
- win10 自帶的商店怎麼解除安裝_如何解除安裝win10自帶應用商店Win10
- Android 高仿豌豆莢 一鍵安裝app 功能 實現AndroidAPP
- Android O 讓安裝應用更安全Android
- 如何安裝與解除安裝鐵威馬NAS應用程式
- solaris 10 應用軟體的安裝/解除安裝方法(轉)
- Android中如何在應用A中啟動或安裝應用BAndroid
- Android客戶端apk自動檢測更新自動下載自動安裝的實現方法Android客戶端APK
- Mac 解除安裝應用程式(AppCleaner)MacAPP
- android 安裝Android
- Android應用例項之----基於BroadCastReceiver的SD卡裝載解除安裝例項!AndroidASTSD卡
- win10怎麼解除安裝應用商店_如何將win10的應用商店解除安裝Win10
- win10 應用商店怎麼解除安裝_如何將win10的應用商店解除安裝Win10
- win10應用商店解除安裝了怎麼找回 如何裝回win10解除安裝的應用商店Win10
- win10 商店應用怎麼解除安裝 win10 商店解除安裝方法Win10
- C++程式安裝解除安裝WDM驅動C++
- Win10內建應用3種解除安裝方法 Win10自帶軟體怎麼解除安裝 ?Win10
- 3種解除安裝Win10內建應用方法 Win10自帶軟體怎麼解除安裝?Win10
- docker安裝及解除安裝Docker
- Ubuntu解除安裝和安裝Ubuntu
- Oracle 安裝與解除安裝Oracle
- solaris mysql 安裝 解除安裝MySql
- JDK安裝和解除安裝JDK
- win10怎麼解除安裝app應用_win10如何解除安裝內建app應用Win10APP