Android(安卓)Launcher 应用的安装、更新、移除介绍
Android Launcher 应用的安装、更新、移除介绍--LauncherAppsCompat
- 说明
- 实现方法
- LauncherAppsCompat
- LauncherAppsCompatV16
- LauncherAppsCompatVL
- 总结
说明
当进行Laucher开发时,不可避免的需要对应用的安装、移除、更新等进行处理,此时我们用到了LauncherAppsCompat。由于Android 21前后对于应用更新操作的处理有所不同,所以LauncherAppsCompat只声明了抽像方法面由其子类来实现,子类为LauncherAppsCompatVL、LauncherAppsCompatV16。
LauncherAppsCompatVL针对Android 21 及以上版本的实现方法
LauncherAppsCompatV16 对于Android 16到21版本的实现方法
实现方法
LauncherAppsCompat
LauncherAppsCompat声明为单例模式,在取得单例的时候需要判断Android的版本号,当Android版本号>=21时直接声明返回 LauncherAppsCompatVL,否则返回LauncherAppsCompatV16代码如下:
public static LauncherAppsCompat getInstance(Context context) { synchronized (sInstanceLock) { if (sInstance == null) { if (Utilities.ATLEAST_LOLLIPOP) { sInstance = new LauncherAppsCompatVL(context.getApplicationContext()); } else { sInstance = new LauncherAppsCompatV16(context.getApplicationContext()); } } return sInstance; }}
在LauncherAppsCompat 中声明对于应用的处理
public interface OnAppsChangedCallbackCompat {
//应用移除
void onPackageRemoved(String packageName, UserHandleCompat user);
//应用添加
void onPackageAdded(String packageName, UserHandleCompat user);
//应用更新
void onPackageChanged(String packageName, UserHandleCompat user);
//应用移动
void onPackagesAvailable(String[] packageNames, UserHandleCompat user, boolean replacing);
//应用移动过程当中
void onPackagesUnavailable(String[] packageNames, UserHandleCompat user, boolean replacing);
}
说明:UserHandleCompat 是UserHandle的实现类,UserHandler是针对多用户的类。
LauncherAppsCompatV16
LauncherAppsCompatV16通过广播机制接收系统关于应用更新发送了来的广播,
LauncherAppsCompatV16 继承LauncherAppsCompat,在构造方法中注册广播并设置过滤条件接收应用更新广播,并调用父类的OnAppsChangedCallbackCompat接口。
广播注册代码如下:
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme(“package”);
mContext.registerReceiver(mPackageMonitor, filter);
filter = new IntentFilter();
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mPackageMonitor, filter);
过滤条件说明:
Intent.ACTION_PACKAGE_REMOVED;
//成功的删除某个APK之后发出的广播
//一个已存在的应用程序包已经从设备上移除,包括包名(正在被安装的包程序不能接收到这个广播)
Intent.ACTION_PACKAGE_CHANGED;
//一个已存在的应用程序包已经改变,包括包名
Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;
////移动APP完成之后,发出的广播(移动是指:APP2SD)
Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
//正在移动APP时,发出的广播(移动是指:APP2SD)
广播接收对于不现条件下的action分别处理,实现代码如下:
@Thunk
class PackageMonitor extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
Log.d(TAG, "onReceive: " + action + " - " + intent.getData().toString());
final UserHandleCompat user = UserHandleCompat.myUserHandle(); if (Intent.ACTION_PACKAGE_CHANGED.equals(action) || Intent.ACTION_PACKAGE_REMOVED.equals(action) || Intent.ACTION_PACKAGE_ADDED.equals(action)) { final String packageName = intent.getData().getSchemeSpecificPart(); final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); if (packageName == null || packageName.length() == 0) { // they sent us a bad intent return; } if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) { callback.onPackageChanged(packageName, user); } } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { if (!replacing) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) { callback.onPackageRemoved(packageName, user); } } // else, we are replacing the package, so a PACKAGE_ADDED will be sent // later, we will update the package at this time } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { if (!replacing) { for (OnAppsChangedCallbackCompat callback : getCallbacks()) { callback.onPackageAdded(packageName, user); } } else { for (OnAppsChangedCallbackCompat callback : getCallbacks()) { callback.onPackageChanged(packageName, user); } } } } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) { // EXTRA_REPLACING is available Kitkat onwards. For lower devices, it is broadcasted // when moving a package or mounting/un-mounting external storage. Assume that // it is a replacing operation. final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, !Utilities.ATLEAST_KITKAT); String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); for (OnAppsChangedCallbackCompat callback : getCallbacks()) { callback.onPackagesAvailable(packages, user, replacing); } } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { // This intent is broadcasted when moving a package or mounting/un-mounting // external storage. // However on Kitkat this is also sent when a package is being updated, and // contains an extra Intent.EXTRA_REPLACING=true for that case. // Using false as default for Intent.EXTRA_REPLACING gives correct value on // lower devices as the intent is not sent when the app is updating/replacing. final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); for (OnAppsChangedCallbackCompat callback : getCallbacks()) { callback.onPackagesUnavailable(packages, user, replacing); } } }}
LauncherAppsCompatVL
LauncherAppsCompatVL继承LauncherAppsCompat并利用回调方法处理应用更新的消息
LauncherAppsCompatVL 在构造函数中获取系统服务"launcherapps",实现回调函数代码如下:
private static class WrappedCallback extends LauncherApps.Callback {
private LauncherAppsCompat.OnAppsChangedCallbackCompat mCallback;
public WrappedCallback(LauncherAppsCompat.OnAppsChangedCallbackCompat callback) { mCallback = callback; } public void onPackageRemoved(String packageName, UserHandle user) { mCallback.onPackageRemoved(packageName, UserHandleCompat.fromUser(user)); } public void onPackageAdded(String packageName, UserHandle user) { mCallback.onPackageAdded(packageName, UserHandleCompat.fromUser(user)); } public void onPackageChanged(String packageName, UserHandle user) { mCallback.onPackageChanged(packageName, UserHandleCompat.fromUser(user)); } public void onPackagesAvailable(String[] packageNames, UserHandle user, boolean replacing) { mCallback.onPackagesAvailable(packageNames, UserHandleCompat.fromUser(user), replacing); } public void onPackagesUnavailable(String[] packageNames, UserHandle user, boolean replacing) { mCallback.onPackagesUnavailable(packageNames, UserHandleCompat.fromUser(user), replacing); }}
总结
以上LauncherAppsCompat需要在LaucherMode中注册使用。
更多相关文章
- android onConfigurationChanged的那点事
- Android(安卓)和 前端的类似点(持续更新)
- Android(安卓)Lint
- android之在activity中控制另一个activity的UI更新_如何在activi
- 曾经的笔记——android的学习笔记(广播接收者)
- Android(安卓)MediaScannerConnection,Android(安卓)MediaScanner
- Android关于疑难bug处理方法之一(搜索不到相同bug解决方案)
- Android(安卓)view的移动和画布的移动原理 适用于制作各种效果
- Android(安卓)Local Service