安卓应用安装卸载工具类

从安卓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类,它的主要功能是监控应用的安装和卸载事件。类中包含了以下几个关键部分:

  1. mSensorCallbacks: 一个弱引用列表,用于存储注册的回调(InstallerCallback)对象,这样可以防止内存泄露。

  2. 静态持有模式 (Holder) 和 getInstance()方法:提供单例实例访问,保证只有一个AppInstallerSensor实例存在,方便其他模块调用。

  3. registerReceiver(): 注册了一个BroadcastReceiver,它会接收ACTION_PACKAGE_ADDED和ACTION_PACKAGE_REMOVED这两个意图(Intent),当有新的应用程序安装或卸载时会被触发。

  4. registerSensor()unRegisterSensor(): 方法用于添加和移除安装/卸载监听器(InstallerCallback)。registerSensor()保存回调到mSensorCallbacksunRegisterSensor()则从列表中移除指定的回调。

  5. InstallerReceiver: 该内部类是BroadcastReceiver的实际实现,当接收到intent时,解析出包名并根据ACTION_PACKAGE_ADDED或ACTION_PACKAGE_REMOVED调用相应的监听方法。

  6. InstallerCallback: 定义了两个接口方法,onAppInstall()onAppUninstall(),这是外部组件(如Activity、Fragment等)为了接收安装和卸载通知而需要实现的。

总结来说,这个类是一个简单的系统监控工具,用于跟踪应用商店内的新应用安装和旧应用卸载,并通过回调机制通知注册的监听者。

二、使用方式

在需要监听应用安装卸载的地方直接使用如下两行代码,具体业务逻辑放到AppInstallerCallback实现类中(当然你可以自己定义实现类,实现接口AppInstallerSensor.InstallerCallback)。

  1. 在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
  1. 在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
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值