做一个简单的记录:
这边主要是考虑到一些设备没有root的情况下,借助Android提供的辅助功能,开启无障碍服务来处理,借鉴了这位大神的一些步骤:https://blog.csdn.net/guolin_blog/article/details/47803149
1.编写一个服务类(MyAccessibilityService)
package com.example.administrator.medx_media.upapkdata;
import android.accessibilityservice.AccessibilityService;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import java.util.HashMap;
import java.util.Map;
/**
* 智能安装功能的实现类。
* 原文地址:http://blog.csdn.net/guolin_blog/article/details/47803149
* @author guolin
* @since 2015/12/7
*/
public class MyAccessibilityService extends AccessibilityService {
Map handledMap = new HashMap<>();
public MyAccessibilityService() {
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
AccessibilityNodeInfo nodeInfo = event.getSource();
if (nodeInfo != null) {
int eventType = event.getEventType();
if (eventType== AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED ||
eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
if (handledMap.get(event.getWindowId()) == null) {
boolean handled = iterateNodesAndHandle(nodeInfo);
if (handled) {
handledMap.put(event.getWindowId(), true);
}
}
}
}
}
private boolean iterateNodesAndHandle(AccessibilityNodeInfo nodeInfo) {
if (nodeInfo != null) {
int childCount = nodeInfo.getChildCount();
if ("android.widget.Button".equals(nodeInfo.getClassName())) {
String nodeContent = nodeInfo.getText().toString();
Log.d("TAG", "content is " + nodeContent);
if ("安装".equals(nodeContent) || "完成".equals(nodeContent)) {
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
return true;
}
} else if ("android.widget.ScrollView".equals(nodeInfo.getClassName())) {
nodeInfo.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
}
for (int i = 0; i < childCount; i++) {
AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
if (iterateNodesAndHandle(childNodeInfo)) {
return true;
}
}
}
return false;
}
@Override
public void onInterrupt() {
}
}
2.在文件清单,添加该服务:
3.在res目录下,新建xml文件夹,创建文件:
4.下载好apk,执行安装,弹出安装界面
5.为了解决,监听到安装完成,之后,弹框停留不能取消隐藏的问题,加入一个广播接收者,5秒钟之后,再去重启软件:
/**
* 检测软件卸载和安装测试
*/
public class MyReceiver2 extends BroadcastReceiver {
private String rootfilepath;
Context mcontext;
String packageName;
Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
// Log.i(TAG, "handleMessage: 执行了");
forceStopApp(packageName);
Intent LaunchIntent = mcontext.getPackageManager().getLaunchIntentForPackage(packageName);
LaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//.testDemo.TestFrag_ShowhidedActivity
LaunchIntent.setClassName("com.example.administrator.xxx", "com.example.administrator.xxx.xxx");
mcontext.startActivity(LaunchIntent);
break;
}
}
};
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
mcontext = context;
PackageManager manager = context.getPackageManager();
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
packageName = intent.getData().getSchemeSpecificPart();
Log.i(TAG, "123456安装成功: " + packageName);
}
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)) {
packageName = intent.getData().getSchemeSpecificPart();
Log.i(TAG, "123456卸载成功: " + packageName);
}
if (intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
packageName = intent.getData().getSchemeSpecificPart();
Log.i(TAG, " 123456替换成功: " + packageName);
handler.sendEmptyMessageDelayed(1, 2000);
}
}
// 传入应用的包名即可kill掉应用
private void forceStopApp(String packageName) {
ActivityManager am = (ActivityManager) mcontext
.getSystemService(Context.ACTIVITY_SERVICE);
try {
Method method = Class.forName("android.app.ActivityManager").getMethod("forceStopPackage", String.class);
method.invoke(am, packageName);
// am.forceStopPackage(packageName);
} catch (Exception e) {
e.printStackTrace();
}
}
public void deletefile() {
//具体文件路径引用
if (isSDCardMounted()) {
rootfilepath = Environment.getExternalStorageDirectory().getPath() + UitlData.MEADIA_VIDEO;
} else {
rootfilepath = Environment.getDataDirectory().getPath() + UitlData.MEADIA_VIDEO;
}
Log.i(TAG, "deletefile: 删除了文件夹=" + rootfilepath);
deleteDir(rootfilepath);
}
/**
* 删除文件夹
*
* @param path
*/
public static void deleteDir(String path) {
File dir = new File(path);
deleteDirWihtFile(dir);
}
/**
* 删除文件及文件夹
*/
public static void deleteDirWihtFile(File dir) {
if (dir == null || !dir.exists() || !dir.isDirectory())
return;
for (File file : dir.listFiles()) {
System.gc();
if (file.isFile())
file.delete(); // 删除所有文件
else if (file.isDirectory())
deleteDirWihtFile(file); // 递规的方式删除文件夹
}
dir.delete();// 删除目录本身
}
}
6.启动app前,判断是否开启无障碍服务:
int enable = Settings.Secure.getInt(this.getApplication().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, 0);
if (enable == 1) {
Log.i(TAG, "onCreate: 无障碍开启");
// 开始安装
} else {
Log.i(TAG, "onCreate: 无障碍没开启");
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);
}
,虽然到这一步,基本解决了这个安装完之后,弹框不消失的问题,但实际上它还是没有取消那框,只是检测安装了相同的apk,开个重启的方法,只是隐藏了,实际上退出软件之后,它一样还是存在的,但是不阻挡该app的正常使用。当然没有十全十美的办法,在没有root的Android 系统上,是我们暂时的办法,当然可以去root的情况下,又有谁会去用这个“本方法”,如果你有更好的方法和思路,可以留言一起交流学习。