从安卓8.0(Android Oreo)开始,应用安装和卸载事件的广播接收需要从静态注册转向动态注册。这是为了提高系统的性能和安全性。
本文将通过动态注册应用安装卸载广播,单例模式注册应用安装、卸载广播,并采用接口注册回调方式,监听到应用广播需要做的事务放到实现类中。
一、AppInstallerSensor
public class AppInstallerSensor {
/**
* 存储屏幕亮暗监听回调
*/
private final ArrayList<WeakReference<InstallerCallback>> mSensorCallbacks = new ArrayList<>();
private AppInstallerSensor() {
registerReceiver();
}
private static class Holder {
static AppInstallerSensor sAppInstallerSensor = new AppInstallerSensor();
}
public static AppInstallerSensor getInstance() {
return Holder.sAppInstallerSensor;
}
private void registerReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addDataScheme("package");
Utils.getApp().registerReceiver(new InstallerReceiver(), intentFilter);
LogUtil.d("AppInstallerSensor registerReceiver");
}
public void registerSensor(InstallerCallback callback) {
if (callback == null) {
return;
}
WeakReference<InstallerCallback> weakReference = new WeakReference<>(callback);
synchronized (mSensorCallbacks) {
mSensorCallbacks.add(weakReference);
}
}
public void unRegisterSensor(InstallerCallback callback) {
if (callback == null) {
return;
}
for (WeakReference<InstallerCallback> sensorCallbackWf : mSensorCallbacks) {
if (sensorCallbackWf == null || sensorCallbackWf.get() == null) {
mSensorCallbacks.remove(sensorCallbackWf);
continue;
}
InstallerCallback sensorCallback = sensorCallbackWf.get();
if (sensorCallback != callback) {
continue;
}
mSensorCallbacks.remove(sensorCallbackWf);
}
}
private class InstallerReceiver extends BroadcastReceiver {
private static final String SEPARATOR = ":";
@Override
public void onReceive(Context context, Intent intent) {
LogUtil.d("InstallerReceiver", "onReceive intent=" + intent.getAction());
if (TextUtils.isEmpty(intent.getAction()) || (!TextUtils.equals(intent.getAction(), Intent.ACTION_PACKAGE_ADDED) &&
!TextUtils.equals(intent.getAction(), Intent.ACTION_PACKAGE_REMOVED))) {
return;
}
String data = intent.getDataString();
String pkgName = null;
if (data != null && !TextUtils.isEmpty(data) && data.contains(SEPARATOR)) {
pkgName = data.substring(data.indexOf(SEPARATOR) + 1);
}
// 如果包名获取异常,则直接返回
if (TextUtils.isEmpty(pkgName)) {
return;
}
boolean isInstall = TextUtils.equals(Intent.ACTION_PACKAGE_ADDED, intent.getAction());
for (WeakReference<InstallerCallback> sensorCallbackWf : mSensorCallbacks) {
if (sensorCallbackWf == null || sensorCallbackWf.get() == null) {
mSensorCallbacks.remove(sensorCallbackWf);
continue;
}
InstallerCallback sensorCallback = sensorCallbackWf.get();
if (isInstall) {
sensorCallback.onAppInstall(context, pkgName);
} else {
sensorCallback.onAppUninstall(context, pkgName);
}
}
}
}
/**
* 应用安装卸载监听
*/
public interface InstallerCallback {
/**
* 应用安装卸载监听
*
* @param context 上下文
* @param packageName 应用包名
*/
void onAppInstall(Context context, String packageName);
/**
* 应用卸载监听
*
* @param context 上下文
* @param packageName 应用包名
* 应用卸载监听
*/
void onAppUninstall(Context context, String packageName);
}
}
AppInstallerSensor类,它的主要功能是监控应用的安装和卸载事件。类中包含了以下几个关键部分:
-
mSensorCallbacks: 一个弱引用列表,用于存储注册的回调(InstallerCallback)对象,这样可以防止内存泄露。 -
静态持有模式 (
Holder) 和getInstance()方法:提供单例实例访问,保证只有一个AppInstallerSensor实例存在,方便其他模块调用。 -
registerReceiver(): 注册了一个BroadcastReceiver,它会接收ACTION_PACKAGE_ADDED和ACTION_PACKAGE_REMOVED这两个意图(Intent),当有新的应用程序安装或卸载时会被触发。 -
registerSensor()和unRegisterSensor(): 方法用于添加和移除安装/卸载监听器(InstallerCallback)。registerSensor()保存回调到mSensorCallbacks,unRegisterSensor()则从列表中移除指定的回调。 -
InstallerReceiver: 该内部类是BroadcastReceiver的实际实现,当接收到intent时,解析出包名并根据ACTION_PACKAGE_ADDED或ACTION_PACKAGE_REMOVED调用相应的监听方法。 -
InstallerCallback: 定义了两个接口方法,onAppInstall()和onAppUninstall(),这是外部组件(如Activity、Fragment等)为了接收安装和卸载通知而需要实现的。
总结来说,这个类是一个简单的系统监控工具,用于跟踪应用商店内的新应用安装和旧应用卸载,并通过回调机制通知注册的监听者。
二、使用方式
在需要监听应用安装卸载的地方直接使用如下两行代码,具体业务逻辑放到AppInstallerCallback实现类中(当然你可以自己定义实现类,实现接口AppInstallerSensor.InstallerCallback)。
- 在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
- 在Application的onCreate中注册
AppInstallerCallback installerCallback = new AppInstallerCallback();
AppInstallerSensor.getInstance().registerSensor(installerCallback);
注销方式,笔者仅提供注销回调接口的函数,因为我们是在Application中注册安装、卸载广播的,不需要注销广播,若有需要可自行修改。
如下为继承AppInstallerSensor.InstallerCallback接口的实现类,监听到应用安装和卸载时分别会执行onAppInstall方法和onAppUninstall方法。安装、卸载的应用包名通过packageName传递。
public class AppInstallerCallback implements AppInstallerSensor.InstallerCallback {
@Override
public void onAppInstall(Context context, String packageName) {
//to do some thing
}
@Override
public void onAppUninstall(Context context, String packageName) {
//to do some thing
}
}
3264

被折叠的 条评论
为什么被折叠?



