Android侦听应用(Package)变化的方法(2)实现PackageMonitor
来源:互联网 发布:2013网络歌手 编辑:程序博客网 时间:2024/05/16 14:36
先看看PackageMonitor的基本定义:
package com.android.internal.content;/** * Helper class for monitoring the state of packages: adding, removing, * updating, and disappearing and reappearing on the SD card. */public abstract class PackageMonitor extends android.content.BroadcastReceiverstatic { sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED); sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED); sPackageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED); sPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); sPackageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED); sPackageFilt.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); sPackageFilt.addDataScheme("package"); sNonDataFilt.addAction(Intent.ACTION_UID_REMOVED); sNonDataFilt.addAction(Intent.ACTION_USER_STOPPED); sNonDataFilt.addAction(Intent.ACTION_PACKAGES_SUSPENDED); sNonDataFilt.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED); sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);}
可以看到PackageMonitor是一个内部API,并且它实际上是一个BroadcastReceiver,在框架内部注册了接收上述Action的Intent广播。虽然目前没有对第三方App开放,但其设计思想可以借鉴,毕竟注册各种Package相关的Intent比较琐碎,在一个工程中封装一个类似的Monitor作为基本框架模块供复用很有必要。PackageMonitor的主要工作是将注册/解析Intent广播封装,对外暴露成需要实现的有语义的回调。看一下他的注册和有代表性的回调。
(1)注册
PackageMonitor有三个注册方法:public void register(Context context, Looper thread, boolean externalStorage) public void register(Context context, Looper thread, UserHandle user, boolean externalStorage)public void register(Context context, UserHandle user, boolean externalStorage, Handler handler)
可以看到提供了注册回调执行的线程、注册侦听的用户(支持安卓多用户体系)、选择是否侦听外置存储空间(譬如SD卡)中的package变化等配置项。(2)有代表性的回调
/** * Called when a package is really added (and not replaced). */public void onPackageAdded(String packageName, int uid) {}/** * Called when a package is really removed (and not replaced). */public void onPackageRemoved(String packageName, int uid) {}/** * Direct reflection of {@link Intent#ACTION_PACKAGE_CHANGED * Intent.ACTION_PACKAGE_CHANGED} being received, informing you of * changes to the enabled/disabled state of components in a package * and/or of the overall package. * * @param packageName The name of the package that is changing. * @param uid The user ID the package runs under. * @param components Any components in the package that are changing. If * the overall package is changing, this will contain an entry of the * package name itself. * @return Return true to indicate you care about this change, which will * result in {@link #onSomePackagesChanged()} being called later. If you * return false, no further callbacks will happen about this change. The * default implementation returns true if this is a change to the entire * package. */public boolean onPackageChanged(String packageName, int uid, String[] components) { if (components != null) { for (String name : components) { if (packageName.equals(name)) { return true; } } } return false;}public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { return false;}public void onHandleUserStop(Intent intent, int userHandle) {}public void onUidRemoved(int uid) {}public void onPackagesAvailable(String[] packages) {}public void onPackagesUnavailable(String[] packages) {}public void onPackagesSuspended(String[] packages) {}public void onPackagesUnsuspended(String[] packages) {}
可以根据自己的需求进行重写方法。针对其中几个研究一下:-onUidRemoved(int uid):自从android引入对多用户的支持,uid和user就成了容易混淆的概念。参见我的另2篇:Android下uid与多用户释疑(一) Android下uid与多用户释疑(二) 这里的uid是指应用程序。uid removed即指应用程序被删除(卸载)。如果某些业务逻辑中对于应用程序是通过uid标识管理的,可以使用这个回调。 对应的Intent Action是Intent.ACTION_UID_REMOVED。-onPackagesSuspended()/onPackagesUnsuspended():对应Intent.ACTION_PACKAGES_SUSPENDED/ACTION_PACKAGES_UNSUSPENDED。查看PMS、PackageManager的源代码看到是在调用这个api时触发的Intent广播:
/** * Puts the package in a suspended state, where attempts at starting activities are denied. * * <p>It doesn't remove the data or the actual package file. The application notifications * will be hidden, the application will not show up in recents, will not be able to show * toasts or dialogs or ring the device. * * <p>The package must already be installed. If the package is uninstalled while suspended * the package will no longer be suspended. * * @param packageNames The names of the packages to set the suspended status. * @param suspended If set to {@code true} than the packages will be suspended, if set to * {@code false} the packages will be unsuspended. * @param userId The user id. * * @return an array of package names for which the suspended status attemptis not set as requested in * this method. * * @hide */public abstract String[] setPackagesSuspendedAsUser( String[] packageNames, boolean suspended, @UserIdInt int userId);
关于应用挂起,后续会有文章跟进。以一个系统服务SearchManagerService为例看下对于PackageMonitor的使用:/** * Refreshes the "searchables" list when packages are added/removed. */class MyPackageMonitor extends PackageMonitor { @Override public void onSomePackagesChanged() { updateSearchables(); } @Override public void onPackageModified(String pkg) { updateSearchables(); } private void updateSearchables() { final int changingUserId = getChangingUserId(); synchronized (mSearchables) { // Update list of searchable activities for (int i = 0; i < mSearchables.size(); i++) { if (changingUserId == mSearchables.keyAt(i)) { mSearchables.valueAt(i).updateSearchableList(); break; } } } // Inform all listeners that the list of searchables has been updated. Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mContext.sendBroadcastAsUser(intent, new UserHandle(changingUserId)); }}
上述参看代码版本为android7.1。
1 0
- Android侦听应用(Package)变化的方法(2)实现PackageMonitor
- Android侦听应用(Package)变化的方法(1)侦听广播
- android 侦听文件变化
- csma(载波侦听)侦听的是什么?
- 就Android项目基本成型后,更换应用包名(package)的方法
- Android --(7),Action Bar,侦听UI组件的动作
- JavaScript侦听Html元素Attribute的变化
- Android媒体应用(七)--处理音频输出的变化
- android --activity 中的控件设置侦听(onclickListener)无效,自定义adapter不执行getView 方法
- Android---------ViewPager+Fragment实现界面的转换(颜色变化)
- android 系统的电池侦听
- Android开发之查看应用包名package和入口activity名称的方法
- Android开发之查看应用包名package和入口activity名称的方法
- Android开发之查看应用包名package和入口activity名称的方法
- Android开发之查看应用包名package和入口activity名称的方法
- Android开发之查看应用包名package和入口activity名称的方法
- Android查看应用包名package和入口activity名称的方法
- Android开发之查看应用包名package和入口activity名称的方法
- 图存储1 临接矩阵
- 北邮人论坛搜索
- java面试之2
- 顶尖程序员与普通程序员的区别
- 工作流框架--activiti(一)--建库
- Android侦听应用(Package)变化的方法(2)实现PackageMonitor
- 原装Win8本改装Win7不完全指南
- 深入浅出RPC
- 极光推送getRegistrationID为空,UnsatisfiedLinkError异常
- iOS学习笔记-057.自定义View04——刷帧动画
- 关于数组,sizeof(),strlen的计算问题
- Android复习-fragment声明周期与Activity生命周期(个人笔记)
- Linux3.2.81内核移植(2440)
- 其他,備忘