Android BroadcastReceiver示例教程

时间:2020-02-23 14:28:47  来源:igfitidea点击:

今天,我们将讨论和实现Android BroadcastReceiver,它是Android Framework的非常重要的组成部分。

Android BroadcastReceiver

Android BroadcastReceiver是android的休眠组件,用于监听系统范围内的广播事件或者意图。

这些事件中的任何一个发生时,它都会通过创建状态列通知或者执行任务来使应用程序生效。

与活动不同,AndroidBroadcastReceiver不包含任何用户界面。
通常,广播接收器的实现是根据接收到的意图数据的类型将任务委托给服务。

以下是一些在系统范围内产生的重要意图。

  • android.intent.action.BATTERY_LOW:指示设备的电池电量不足。

  • android.intent.action.BOOT_COMPLETED:系统完成启动后,将广播一次

  • android.intent.action.CALL:对数据指定的某人执行呼叫

  • android.intent.action.DATE_CHANGED:日期已更改

  • android.intent.action.REBOOT:重启设备

  • android.net.conn.CONNECTIVITY_CHANGE:移动网络或者wifi连接已更改(或者重置)

Android中的广播接收器

要在android应用程序中设置广播接收器,我们需要做以下两件事。

  • 创建一个BroadcastReceiver
  • 注册广播接收器

创建一个BroadcastReceiver

让我们快速实现一个自定义的BroadcastReceiver,如下所示。

public class MyReceiver extends BroadcastReceiver {
  public MyReceiver() {
  }
 
  @Override
  public void onReceive(Context context, Intent intent) {
    
      Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_SHORT).show();
  }
}

BroadcastReceiver是一个抽象类,其中的onReceiver()方法是抽象的。

发生任何事件时,首先在已注册的广播接收器上调用onReceiver()方法。

意向对象与所有其他数据一起传递。
上下文对象也是可用的,它分别用于使用" context.startActivity(myIntent);"或者" context.startService(myService);"来启动活动或者服务。

在Android应用中注册BroadcastReceiver

可以通过两种方式注册BroadcastReceiver。

  • 通过在AndroidManifest.xml文件中对其进行定义,如下所示。
<receiver android:name=".ConnectionReceiver" >
           <intent-filter>
               <action android:name="android.net.conn.CONNECTIVITY_CHANGE" 
           </intent-filter>
</receiver>

使用意图过滤器,我们告诉系统任何与子元素匹配的意图都应传递到该特定广播接收器。

  • 通过编程定义

下面的代码片段显示了一个示例示例,以编程方式注册广播接收器。

IntentFilter filter = new IntentFilter();
intentFilter.addAction(getPackageName() + "android.net.conn.CONNECTIVITY_CHANGE");
 
MyReceiver myReceiver = new MyReceiver();
registerReceiver(myReceiver, filter);

要在活动的" onStop()"或者" onPause()"中注销广播接收器,可以使用以下代码段。

@Override
protected void onPause() {
  unregisterReceiver(myReceiver);
  super.onPause();
}

从活动发送广播意图

以下代码段用于向所有相关的BroadcastReceivers发送意图。

Intent intent = new Intent();
    intent.setAction("com.theitroad.CUSTOM_INTENT");
    sendBroadcast(intent);

不要忘记在列表的意图过滤器标签中或者以编程方式添加上述操作。

让我们开发一个应用程序,该程序可以侦听网络更改事件,还可以侦听自定义意图并相应地处理数据。

Android项目结构中的BroadcastReceiver

Android BroadcastReceiver代码

" activity_main.xml"由位于中心的按钮组成,用于发送广播意图。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
  xmlns:tools="https://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context="com.theitroad.broadcastreceiver.MainActivity">

  <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/button"
      android:text="Send Broadcast"
      android:layout_centerVertical="true"
      android:layout_centerHorizontal="true" 
</RelativeLayout>

MainActivity.java在下面给出。

package com.theitroad.broadcastreceiver;

import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {
  ConnectionReceiver receiver;
  IntentFilter intentFilter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      ButterKnife.inject(this);

      receiver = new ConnectionReceiver();
      intentFilter = new IntentFilter("com.theitroad.broadcastreceiver.SOME_ACTION");

  }

  @Override
  protected void onResume() {
      super.onResume();
      registerReceiver(receiver, intentFilter);

  }

  @Override
  protected void onDestroy() {
      super.onDestroy();

      unregisterReceiver(receiver);
  }

  @OnClick(R.id.button)
  void someMethod() {

      Intent intent = new Intent("com.theitroad.broadcastreceiver.SOME_ACTION");
      sendBroadcast(intent);
  }
}

在上面的代码中,我们以编程方式注册了另一个自定义操作。

如下所示,在AndroidManifest.xml文件中定义了ConnectionReceiver。

<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
  package="com.theitroad.broadcastreceiver">

  <uses-permission android:name="android.permission.INTERNET" 
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" 

  <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=".ConnectionReceiver">
          <intent-filter>
              <action android:name="android.net.conn.CONNECTIVITY_CHANGE" 
          </intent-filter>
      </receiver>

  </application>
</manifest>

下面定义了ConnectionReceiver.java类。

public class ConnectionReceiver extends BroadcastReceiver {
  @Override
  public void onReceive(Context context, Intent intent) {

      Log.d("API123",""+intent.getAction());

      if(intent.getAction().equals("com.theitroad.broadcastreceiver.SOME_ACTION"))
          Toast.makeText(context, "SOME_ACTION is received", Toast.LENGTH_LONG).show();

      else {
          ConnectivityManager cm =
                  (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

          NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
          boolean isConnected = activeNetwork != null &&
                  activeNetwork.isConnectedOrConnecting();
          if (isConnected) {
              try {
                  Toast.makeText(context, "Network is connected", Toast.LENGTH_LONG).show();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          } else {
              Toast.makeText(context, "Network is changed or reconnected", Toast.LENGTH_LONG).show();
          }
      }
  }

}

在上面的代码中,我们检查意图触发触发onReceive()方法的意图动作,并基于该意图显示吐司。

注意:要使广播接收器不可用于外部应用程序,请在列表中添加属性" android:exported = false"。
当我们发送广播时,外部应用程序也有可能接收它们。
通过指定此限制可以防止这种情况。