Android(安卓)广播接收器(Broadcast Receiver)
广播接收器(Broadcast Receiver)仅响应来自其他应用程序或系统本身的广播消息。这些消息有时称为事件或意图。例如,应用程序还可以启动广播,以让其他应用程序知道一些数据已下载到设备并可供其使用,因此这是广播接收器,它将拦截此通信并启动适当的操作。
要使广播接收器为系统广播意图工作,有以下两个重要步骤:
- 创建广播接收器。
- 注册广播接收器
如果您要实现自定义意图,还有一个额外的步骤,那么您必须创建并广播这些意图。
创建广播接收器
广播接收器实现为 BroadcastReceiver
类的子类,并且重写onReceive()方法,在该方法中,每个消息均作为 Intent
对象参数接收。
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}
注册广播接收器
应用程序通过在 AndroidManifest.xml 文件中注册广播接收器来侦听特定的广播意图(indent)。考虑一下,我们将为系统生成的事件 ACTION_BOOT_COMPLETED
注册 MyReceiver
,一旦 Android 系统完成启动过程,系统就会触发该事件。
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
</intent-filter>
</receiver>
</application>
现在,无论何时启动 Android 设备,它都会被广播接收器 MyReceivers
截获,并执行 onReceive()
内的实现逻辑。
有几个系统生成的事件定义为 Intent
类中的最终静态字段。下表列出了一些重要的系统事件。
编号 | 事件常量 & 描述 |
---|---|
1 | android.intent.action.BATTERY_CHANGED 粘滞广播,包含充电状态、电量和其他有关电池的信息。 |
2 | android.intent.action.BATTERY_LOW 表示设备电池电量不足。 |
3 | android.intent.action.BATTERY_OKAY 表示电池电量低后现在正常。 |
4 | android.intent.action.BOOT_COMPLETED 这在系统完成启动后广播一次。 |
5 | android.intent.action.BUG_REPORT 显示报告 bug 的 activity 活动。 |
6 | android.intent.action.CALL 呼叫数据指定的人。 |
7 | android.intent.action.CALL_BUTTON 用户按下 "呼叫" 按钮,转到拨号器或其他合适的用户界面进行呼叫。 |
8 | android.intent.action.DATE_CHANGED 数据已修改。 |
9 | android.intent.action.REBOOT 重新启动设备。 |
广播自定义意图(Intents)
如果您希望应用程序本身应生成并发送自定义意图,则必须使用 Activity
类中的 sendBroadcast()
方法来创建并发送这些意图(Indent)。如果您使用 sendStickyBroadcast(Intent)
方法,则该 Intent 是粘性的,这意味着您要发送的 Intent 在广播完成后仍然存在。
public void broadcastIntent(View view) {
Intent intent = new Intent();
intent.setAction("com.cankaoshouce.CUSTOM_INTENT");
sendBroadcast(intent);
}
这个意图 com.cankaoshouce.CUSTOM_INTENT
也可以通过类似于我们重新注册系统生成的意图的方式进行注册。
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="com.cankaoshouce.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
实例
下面的实例将解释如何创建广播接收器以拦截自定义意图。一旦熟悉了自定义意图,就可以对应用程序进行编程,以拦截系统生成的意图。因此,让我们按照以下步骤修改我们在 Hello World 实例 一章中创建的 Android 应用程序:
步骤 | 描述 |
---|---|
1 | 您将使用 Android Studio 创建一个 Android 应用程序,并将其命名为 HelloWorld,位于 com.example.cankaoshouce.myapplication 包下。 |
2 | 修改主 activity 文件 MainActivity.java 来添加 broadcastIntent() 方法。 |
3 | 在包 com.example.cankaoshouce.myapplication 下创建一个新的 java 文件 MyReceiver.java 来定义广播接收器。 |
4 | 应用程序可以处理一个或多个自定义和系统意图,而没有任何限制。您要拦截的每个意图都必须使用 <receiver … /> 标记注册到您的 AndroidManifest.xml 文件中 |
5 | 修改 res/layout/activity_main.xml 文件的默认内容,来包含一个用于广播意图的按钮。 |
6 | 无需修改字符串文件,Android studio 会处理字符串 xml 文件。 |
7 | 运行应用程序以启动 Android 模拟器,并验证应用程序中所做更改的结果。 |
以下是修改后的主 activity 文件 MainActivity.java 的内容。该文件可以包括每个基本生命周期方法。我们添加了 broadcastIntent()
方法来广播自定义意图。
package com.example.cankaoshouce.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// broadcast a custom intent.
public void broadcastIntent(View view){
Intent intent = new Intent();
intent.setAction("com.cankaoshouce.CUSTOM_INTENT"); sendBroadcast(intent);
}
}
MyReceiver.java 的内容如下:
package com.example.cankaoshouce.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* Created by cankaoshouce on 10/18/2022.
*/
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}
以下是 AndroidManifest.xml 文件的修改内容。这里我们添加了 <receiver…/>
标签来包含我们的服务:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cankaoshouce.myapplication">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="com.cankaoshouce.CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
</manifest>
以下是 res/layout/activity_main.xml 文件的内容,其中包含一个按钮来广播我们的自定义意图:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Example of Broadcast"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="参考手册 "
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_above="@+id/imageButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/abc"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="广播意图"
android:onClick="broadcastIntent"
android:layout_below="@+id/imageButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
让我们尝试运行我们修改过的 Hello World!我们刚刚修改的应用程序。我假设您在进行环境设置时创建了 AVD。要从 Android studio 运行应用程序,请打开项目的活动文件之一,然后从工具栏中单击 图标。Android Studio 在您的 AVD 上安装应用程序并启动它,如果您的设置和应用程序一切正常,它将显示模拟器窗口。
现在启动广播接收器,让我们单击 “广播意图” 按钮,这将启动广播接收器,一条广播消息将出现在模拟器的底部。
您可以尝试实现其他广播接收器来拦截系统生成的意图,如系统启动、更改日期、电池电量不足等。