一、前言
在Android的开发中,我们的程序需要得到网络状态变化、电池状态、屏幕状态、电池、系统启动完成、U盘等外设接入状态、apk安装等这些信息,除了主动去找到这些节点的信息,还可以通过安卓的广播机制被动去得到。
Android广播机制包含三个基本要素:广播(Broadcast) - 用于发送广播,广播接收器(BroadcastReceiver) - 用于接收广播,关心内容(Intent)-用于保存广播相关信息的媒介。广播是一种广泛运用的在应用程序之间传输信息的机制。而接收器是对发送出来的广播进行过滤接受并响应的一类组件。
要随时注意安卓的版本,比如安卓8及以上要得到apk安装信息只能通过动态注册的方式。
二、静态注册
静态注册需要在AndroidManifest.xml文件中添加标签,以获取媒体信息为例:
<receiver android:name="com.tbbpower.android.USBReceiver"><intent-filter><action android:name="android.intent.action.MEDIA_MOUNTED"/><action android:name="android.intent.action.MEDIA_UNMOUNTED"/><data android:scheme="file"/></intent-filter>
</receiver>
这里声明了接收器的java类,关心的广播内容,然后我们新建一个java类,继承BroadcastReceiver,在onReceive函数中,一旦发生MEDIA_MOUNTED和MEDIA_UNMOUNTED事件,这里就会被动得到广播,下面是部分实例代码:
public class USBReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent){Log.d(TAG, "enter USBReceiver onReceive: ");try{String action = intent.getAction();if (action != null){String path=intent.getData().getPath();if(action.equals(Intent.ACTION_MEDIA_MOUNTED))//插入handleMediaStateChange(MediaState.MEDIA_MOUNTED,intent.getData().getPath());else if(action.equals(Intent.ACTION_MEDIA_UNMOUNTED))//拔出handleMediaStateChange(MediaState.MEDIA_UNMOUNTED,intent.getData().getPath());else if(action.equals(Intent.ACTION_MEDIA_EJECT))//handleMediaStateChange(MediaState.MEDIA_EJECT,intent.getData().getPath());else if(action.equals(Intent.ACTION_MEDIA_BAD_REMOVAL))//handleMediaStateChange(MediaState.MEDIA_BAD_REMOVAL,intent.getData().getPath());}}catch (Exception ex){Log.d(TAG, "onReceive-failed "+ex.getMessage());}
}
三、动态注册
动态注册原理是一样的,我们先创建一个java程序,该类中,我们通过一个静态函数进行注册,实例化BroadcastReceiver,然后一样是在onReceive中进行处理:
package com.tbbpower.android;public class ReceiverManager {private static final String TAG = "ReceiverManager";private static BroadcastReceiver appReceiver;public static void registerBroadcastReceiver(Context context) {// 创建广播接收器实例appReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {Log.d(TAG, "enter APPReceiver onReceive : ");try{String action = intent.getAction();if (action != null){if (action.equals(Intent.ACTION_PACKAGE_REPLACED)) {String packageName = intent.getData().getSchemeSpecificPart();Log.d(TAG,"ACTION_PACKAGE_REPLACED:"+packageName);Intent intent1 = context.getPackageManager().getLaunchIntentForPackage(packageName);intent1.setPackage(null);context.startActivity(intent1);}if (action.equals(Intent.ACTION_PACKAGE_ADDED)) {String packageName = intent.getData().getSchemeSpecificPart();Log.d(TAG, "ACTION_PACKAGE_ADDED:" + packageName);}if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) {String packageName = intent.getData().getSchemeSpecificPart();Log.d(TAG,"ACTION_PACKAGE_REMOVED:"+packageName);}}}catch (Exception ex){Log.d(TAG, "onReceive-failed "+ex.getMessage());}}};// 创建意图过滤器并添加行为IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_PACKAGE_ADDED);filter.addAction(Intent.ACTION_PACKAGE_REMOVED);filter.addAction(Intent.ACTION_PACKAGE_REPLACED);filter.addDataScheme("package");// 注册广播接收器context.registerReceiver(appReceiver, filter);}public static void unregisterPackageBroadcastReceiver(Context context) {// 在合适的时候注销广播接收器,以避免内存泄漏if (appReceiver != null) {context.unregisterReceiver(appReceiver);appReceiver = null;}}
}
在Qt层,我们调用该静态函数即可:
QAndroidJniObject activity = QtAndroid::androidActivity();
if (activity.isValid())
{QAndroidJniObject::callStaticMethod<void>("com/tbbpower/android/ReceiverManager","registerBroadcastReceiver","(Landroid/content/Context;)V",activity.object<jobject>());
}