android非root方式静默安装和卸载

1.AccessibilityService这个类

需要写一个类继承AccessibilityService这个类,模拟用户点击安装和卸载的界面上的按钮,如下:包括了安装、卸载、清理进程。
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) {

		Log.e("hxk", event.getPackageName().toString());
		if (event.getSource() != null) {// 此处是为了适配三星手机
			if (event.getPackageName().equals("com.android.packageinstaller") || event.getPackageName().equals("com.samsung.android.packageinstaller")) {
				List ok_nodes = event.getSource()
						.findAccessibilityNodeInfosByText("确定");
				if(ok_nodes.size() == 0){
					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);
						}
					}

				}
				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 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 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 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 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 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");
						}
					}

				}
			}
		}
	}

}

其中,event.getPackageName()拿到的包名是android系统安装应用包名:com.android.packageinstaller。
     但是个别厂商会修改,比如三星手机com.samsung.android.packageinstaller。

2.清单文件配置

  • 添加权限:
    
    
    
    

  • 注册MyAccessibilityService服务:
    android:label="@string/acc_service_name"
           android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
           
                
           
    
           	    android:resource="@xml/phone_accessibility" />
    
    其中label是手机辅助功能里代表本应用的名字
    resource内容为:
    
    android:description="@string/accessibility_service_description"
        android:notificationTimeout="100" />
    description是对本应用开启辅助功能时的描述

3.开始调用此服务来静默安装和卸载

安装和卸载都是正常调用普通的安装和下载方法,需要注意的是给MyAccessibilityService.INVOKE_TYPE赋值
  1. 静默安装
    MyAccessibilityService.INVOKE_TYPE = MyAccessibilityService.TYPE_INSTALL_APP;
    String fileName = Environment.getExternalStorageDirectory() + "/test.apk";
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive"); 
    startActivity(intent); 

  2. 静默卸载
    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); 

  3. kill进程
    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);

你可能感兴趣的:(学习)