• Android Video Tutorials

Android - 广播接收器



广播接收器简单来说就是响应来自其他应用程序或系统本身的广播消息。这些消息有时被称为事件或意图。例如,应用程序也可以启动广播来让其他应用程序知道一些数据已被下载到设备上,并且可供它们使用,所以广播接收器会拦截此通信并启动相应的操作。

要使广播接收器能够处理系统广播的意图,需要执行以下两个重要步骤:

  • 创建广播接收器。

  • 注册广播接收器

如果您要实现自定义意图,则还需要创建一个额外的步骤来创建和广播这些意图。

创建广播接收器

广播接收器实现为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文件中注册广播接收器来监听特定的广播意图。假设我们要为系统生成的事件ACTION_BOOT_COMPLETED注册MyReceiver,该事件在Android系统完成引导过程后由系统触发。

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类中,有几个系统生成的事件被定义为最终静态字段。下表列出了一些重要的系统事件。

序号 事件常量及描述
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

显示报告错误的活动。

6

android.intent.action.CALL

执行对由数据指定的某人的呼叫。

7

android.intent.action.CALL_BUTTON

用户按下“呼叫”按钮以进入拨号器或其他合适的UI进行呼叫。

8

android.intent.action.DATE_CHANGED

日期已更改。

9

android.intent.action.REBOOT

重启设备。

广播自定义意图

如果您希望应用程序本身生成和发送自定义意图,则必须使用活动类中的sendBroadcast()方法创建和发送这些意图。如果您使用sendStickyBroadcast(Intent)方法,则意图是粘性的,这意味着您发送的Intent在广播完成之后仍然存在。

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>

示例

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

步骤 描述
1 您将使用Android Studio创建一个Android应用程序,并将其命名为My Application,包名为com.example.tutorialspoint7.myapplication,这在Hello World 示例章节中有解释。
2 修改主活动文件MainActivity.java以添加broadcastIntent()方法。
3 在包com.example.tutorialspoint7.myapplication下创建一个名为MyReceiver.java的新Java文件以定义BroadcastReceiver。
4 应用程序可以处理一个或多个自定义和系统意图,没有任何限制。您要拦截的每个意图都必须使用<receiver.../>标签在您的AndroidManifest.xml文件中注册
5 修改res/layout/activity_main.xml文件的默认内容,以包含一个用于广播意图的按钮。
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 Studio运行应用程序,请打开项目中的一个活动文件,然后单击工具栏中的运行Eclipse Run Icon图标。Android Studio将应用程序安装到您的AVD并启动它,如果您的设置和应用程序一切正常,它将显示以下模拟器窗口:

Android Broadcast Demo

现在要广播我们的自定义意图,让我们单击广播意图按钮,这将广播我们的自定义意图"com.tutorialspoint.CUSTOM_INTENT",该意图将被我们注册的BroadcastReceiver(即MyReceiver)拦截,根据我们实现的逻辑,一个吐司将出现在模拟器的底部,如下所示:

Android Broadcast Intent

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

广告