在Android的开发中,我们的程序需要得到网络状态变化、电池状态、屏幕状态、电池、系统启动完成、U盘等外设接入状态、apk安装等这些信息,除了主动去找到这些节点的信息,还可以通过安卓的广播机制被动去得到。
Android广播机制包含三个基本要素:广播(Broadcast) - 用于发送广播,广播接收器(BroadcastReceiver) - 用于接收广播,关心内容(Intent)-用于保存广播相关信息的媒介。广播是一种广泛运用的在应用程序之间传输信息的机制。而接收器是对发送出来的广播进行过滤接受并响应的一类组件。
要随时注意安卓的版本,比如安卓8及以上要得到apk安装信息只能通过动态注册的方式。
静态注册需要在AndroidManifest.xml文件中添加标签,以获取媒体信息为例:
这里声明了接收器的java类,关心的广播内容,然后我们新建一个java类,继承BroadcastReceiver,在onReceive函数中,一旦发生MEDIA_MOUNTED和MEDIA_UNMOUNTED事件,这里就会被动得到广播,下面是部分实例代码:
public class USBReceiver extends BroadcastReceiver {
@Override
public 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() {
@Override
public 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("com/tbbpower/android/ReceiverManager",
"registerBroadcastReceiver",
"(Landroid/content/Context;)V",
activity.object());
}