‘壹’ android程序怎样监听自身程序被安装和卸载
好久不搞android了,我前年写了个launcher项目,其中也涉及到如何去知道 app 的卸载 和 安装,我保证就api 是可以实现的。希望楼主不要放弃。我记得当时好像是接受广播,好像可以间接的拿到系统的app 状态信息。
‘贰’ android如何监听到程序安装与卸载的名称,包名
可以使用java轮询检测data下包名是否存在来判断安装与卸载
‘叁’ android 如何监听程序安装完成
android系统中,当应用安装完成以后会发出一个广播action的值为android.intent.action.PACKAGE_ADDED。只要监听这个广播就可以了。
监听方法,创建一个BroadcastReceiver,注册时添加过滤器,过滤器中添加以上action。
完成以上步骤,当应用安装完成后,你的应用就会收到广播。
‘肆’ android通过什么来监听应用程序的启动
在Android中,ActivityManager是一个关键组件,它能够帮助我们了解当前系统中运行的应用程序状况。通过这个组件,我们可以查询到所有正在运行的应用程序的信息,包括它们所在的进程ID和进程名。这里提供一个示例代码,展示如何使用ActivityManager来获取这些信息。
首先,我们需要创建一个方法来查询所有已经安装的应用程序,然后根据包名过滤获取所有真正运行的应用程序。示例代码如下:
private List queryAllRunningAppInfo() { pm = this.getPackageManager(); // 查询所有已经安装的应用程序 List listAppcations = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES); Collections.sort(listAppcations, new ApplicationInfo.DisplayNameComparator(pm)); // 排序 // 保存所有正在运行的包名 以及它所在的进程信息 Map pgkProcessAppMap = new HashMap(); ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); // 通过调用ActivityManager的getRunningAppProcesses()方法获得系统里所有正在运行的进程 List appProcessList = mActivityManager .getRunningAppProcesses(); for (ActivityManager.RunningAppProcessInfo appProcess : appProcessList) { int pid = appProcess.pid; // pid String processName = appProcess.processName; // 进程名 Log.i(TAG, "processName: " + processName + " pid: " + pid); String[] pkgNameList = appProcess.pkgList; // 获得运行在该进程里的所有应用程序包 // 输出所有应用程序的包名 for (int i = 0; i < pkgNameList.length; i++) { String pkgName = pkgNameList[i]; Log.i(TAG, "packageName " + pkgName + " at index " + i + " in process " + pid); // 加入至map对象里 pgkProcessAppMap.put(pkgName, appProcess); } } // 保存所有正在运行的应用程序信息 List runningAppInfos = new ArrayList(); // 保存过滤查到的AppInfo for (ApplicationInfo app : listAppcations) { // 如果该包名存在 则构造一个RunningAppInfo对象 if (pgkProcessAppMap.containsKey(app.packageName)) { // 获得该packageName的 pid 和 processName int pid = pgkProcessAppMap.get(app.packageName).pid; String processName = pgkProcessAppMap.get(app.packageName).processName; runningAppInfos.add(getAppInfo(app, pid, processName)); } } return runningAppInfos; }
此代码片段展示了如何利用ActivityManager获取应用程序的运行状态信息。通过这种方式,开发者可以更好地管理和监控应用程序的运行情况。
在实际应用中,通过监听ActivityManager提供的信息,可以实现对应用程序启动的监听。开发者可以根据需要自定义监听逻辑,例如在应用程序启动时执行特定的操作,或者实时监控应用程序的运行状态。
需要注意的是,获取应用程序的运行状态信息需要相应的权限,开发者在开发过程中需要确保应用程序具有相应的权限配置。
总结来说,Android中通过ActivityManager来监听应用程序的启动,为开发者提供了一种有效的方式,以便更好地管理和监控应用程序的运行状况。
‘伍’ Android IActivityController实现app启动监听
IActivityController.aidl是系统自带的aidl,在Am的内部类MyActivityController有实现这个aidl接口,主要用于app状态监听控制。对于应用开发者来说,此接口为给我们提供了各种可能性,比如统计每个app启动次数,crash次数等。这里我们先看下他的方法:
在项目java文件下创建一个包名为android.app,然后把一下文件粘贴进去
接下来需要新建一个代理类 继承IActivityController.Stub
通过反射设置代理类
借鉴文章
‘陆’ Android应用如何监听自己是否被卸载及卸载反
1,注册BroadcastReceiver,监听"android.intent.action.PACKAGE_REMOVED"系统广播
结果:NO。未写代码,直接分析,卸载的第一步就是退出当前应用的主进程,而此广播是在已经卸载完成后才发出的,此时主进程都没有了,去哪onReceive()呢?
2,若能收到"将要卸载XX包"的系统广播,在主进程被退出之前就抢先进行反馈处理就好了,可惜没有这样的系统广播,不过经过调研,倒是发现了一个办法,读取系统log,当日志中包含"android.intent.action.DELETE"和自己的包名时,意味着自己将要被卸载。
结果:NO。调试时发现此方法有两个缺陷,(1)点击设置中的卸载按钮即发出此Intent,此时用户尚未在弹框中确认卸载;(2)pm命令卸载不出发此Intent,意味着被诸如手机安全管家,豌豆荚等软件卸载时,无法提前得知卸载意图。
3,由于时间点不容易把控,所以干脆不依赖系统广播或log,考虑到卸载过程会删除"/data/data/包名"目录,我们可以用线程直接轮询这个目录是否存在,以此为依据判断自己是否被卸载。
结果:NO。同方法1,主进程退出,相应的线程必定退出,线程还没等到判断目录是否存在就已经被销毁了。
4,改用C端进程轮询"/data/data/包名"目录是否存在
结果:YES。借助Java端进程fork出来的C端进程在应用被卸载后不会被销毁。
二 方案
Android自API1就有的一个类FileObserver,这个类用于监听某个文件的变化状态,如果是目录,这个类还可以监听其子目录及子目录文件的变化状态,通过阅读FileObserver源码,发现其实现利用了Linux内核中一个重要的机制inotify,它是一个内核用于通知用户空间程序文件系统变化的机制,详情可参考http://en.wikipedia.org/wiki/Inotify,里面对inotify有比较详细的说明。
使用inotify的好处就在于不需要每1s的轮询,这样就不会无谓地消耗系统资源,使用inotify时会用read()方法阻塞进程,直到收到IN_DELETE通知,此时进程重新被唤醒,执行反馈处理流程。
三方案
阻塞结束后,通过调用exec函数发出am命令调起浏览器访问网页,在API16(Android 4.1.x)的设备上尚可正常访问网页,而API17(Android 4.2.x)的设备上连浏览器也不能调起。解决方案:增加处理分支,若API>=17,将userSerialNumber传递给C端进程,然后在am命令中带上参数--user userSerialNumber即可
‘柒’ Android 能不能监听到第三方应用App的启动和退出
可以,我原来做的是用一个计时器(为了准确率可以0.1s轮询一次)去监听手机的TopActivity,获取TopActivity的包名(应用的包名是唯一的),当TopActivity发生变化就说明使用的应用发生了改变,就实现了监听第三方应用的启动和退出(其中也包括系统应用,过滤包名就可以了)。有什么问题再问我