Android 简明教程

Android - Broadcast Receivers

以下两个步骤非常重要,可以使 BroadcastReceiver 处理系统广播的意图 −

  1. Creating the Broadcast Receiver.

  2. Registering Broadcast Receiver

如果您要实现自定义意图,则还需要一个附加步骤,即必须创建并广播这些意图。

Creating the 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();
   }
}

Registering Broadcast Receiver

应用程序通过在 AndroidManifest.xml 文件中注册广播接收器来侦听特定广播意图。假设我们要为 Android 系统已完成启动过程后系统触发的系统生成事件 ACTION_BOOT_COMPLETED 注册 MyReceiver。

broadcast
<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 设备启动时,都将由广播接收器 MyReceiver 拦截,并将执行 onReceive() 中实现的逻辑。

Intent 类中,有几个以 final static 域定义的系统生成事件。下表列出了几个重要的系统事件。

Sr.No

Event Constant & Description

1

android.intent.action.BATTERY_CHANGED 包含充电状态、电量和其他有关电池的信息的 Sticky 广播。

2

android.intent.action.BATTERY_LOW 指示设备电量低。

3

android.intent.action.BATTERY_OKAY 指示电池电量低后现在已恢复正常。

4

android.intent.action.BOOT_COMPLETED 系统启动完毕后,会广播一次。

5

android.intent.action.BUG_REPORT 显示用于举报错误的活动。

6

android.intent.action.CALL 向数据指定的人员拨打电话。

7

android.intent.action.CALL_BUTTON 用户按“通话”按钮转到拨号器或其他合适的拨打电话的 UI。

8

android.intent.action.DATE_CHANGED The date has changed.

9

android.intent.action.REBOOT Have the device reboot.

Broadcasting Custom Intents

如果您希望应用程序自身生成并发送自定义事件,则必须在活动类中使用 sendBroadcast() 方法创建并发送这些事件。如果您使用 sendStickyBroadcast(Intent) 方法,则 sticky 意图即可确保发送的意图在广播完成后仍存在。

public void broadcastIntent(View view) {
   Intent intent = new Intent();
   intent.setAction("com.tutorialspoint.CUSTOM_INTENT");
   sendBroadcast(intent);
}

此意图 com.tutorialspoint.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.tutorialspoint.CUSTOM_INTENT">
         </action>
      </intent-filter>

   </receiver>
</application>

Example

本例将说明如何创建 BroadcastReceiver 以拦截自定义意图。一旦熟悉了自定义意图,您便可对应用程序进行编程以拦截系统生成的意图。因此,让我们按照以下步骤修改在 Hello World Example 章节中创建的 Android 应用程序 −

Step

Description

1

您将使用 Android studio 创建一个 Android 应用程序,并在程序包 com.example.tutorialspoint7.myapplication 下将其命名为 My Application,如 Hello World Example 章节中所述。

2

修改主活动文件 MainActivity.java 以添加 broadcastIntent() 方法。

3

在程序包 com.example.tutorialspoint7.myapplication 下创建一个名为 MyReceiver.java 的新 java 文件以定义 BroadcastReceiver。

4

一个应用程序可以毫无限制地处理一个或多个自定义意图和系统意图。您要拦截的每个意图都必须在您的 AndroidManifest.xml 文件中使用 <receiver…​/> 标签注册。

5

修改 res/layout/activity_main.xml 文件的默认内容,以 inclusion 一个用于广播意图的按钮。

6

无需修改字符串文件,Android studio 处理 string.xml 文件。

7

运行应用,以启动 Android 模拟器,并验证应用中已执行的更改。

以下是已修改的主活动文件 MainActivity.java 的内容。该文件可以包含每个基本生命周期方法。我们已添加了 broadcastIntent() 方法来广播自定义意图。

package com.example.tutorialspoint7.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.tutorialspoint.CUSTOM_INTENT"); sendBroadcast(intent);
   }
}

以下是 MyReceiver.java 的内容:

package com.example.tutorialspoint7.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

/**
 * Created by TutorialsPoint7 on 8/23/2016.
 */
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.tutorialspoint7.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.tutorialspoint.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="Tutorials point "
      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="Broadcast Intent"
      android:onClick="broadcastIntent"
      android:layout_below="@+id/imageButton"
      android:layout_centerHorizontal="true" />

</RelativeLayout>

让我们尝试运行刚刚修改的 Hello World! 应用程序。我假设你在执行环境设置时已创建了 AVD 。要从 Android 工作室运行该应用,打开项目的其中一个活动文件并单击工具栏中的运行图标。Android 工作室会在 AVD 上安装该应用并启动该应用,如果设置和应用程序一切正常,便会显示以下仿真器窗口 −

broadcast1

现在,若要广播我们的自定义意图,请单击 Broadcast Intent 按钮,这会广播我们的自定义意图“com.tutorialspoint.CUSTOM_INTENT”,我们的已注册 BroadcastReceiver(即 MyReceiver)会拦截此意图,并根据我们实现的逻辑,会在仿真器的底部显示一个吐司,如下所示 −

broadcast2

你可以尝试实现其他 BroadcastReceiver 以拦截系统生成的意图,如系统启动、日期更改、电量不足等。