​​​​​​ 一、什么是BroadcastReceiver

BroadcastReceiver译为广播接受者。Android系统在发生某个事件(如开机、电量改变、收发短信、拨打电话或者屏幕解锁等)时会发送广播,应用程序使用BroadcastReceiver接收这个广播,就知道系统发生了什么,进而采取相应事件响应。

Android的广播可分为以下两类:

普通广播:通过Context.sendBroadcast()方法来发送。它是完全异步的。所有的receivers接收器的执行顺序不确定。故所有的receivers接收器接收broadcast的顺序不确定。该方式效率更高。

有序广播:是通过Context.sendOrderedBroadcast来发送。所有的receiver依次执行。BroadcastReceiver可以使用setResult系列函数将结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以使用abort系列函数让系统丢弃该广播,使该广播不再传送到其他BroadcastReceiver。

当广播消息到达时, BroadcastReceiver会调用onReceiver()方法, BroadcastReceiver生命周期从对象调用它开始,到onReceiver()方法方法执行结束后完成。若onReceiver()方法不能在10s内完成,则Android会出现ANR异常。故不要在BroadcastReceiver的onReceiver()方法中执行耗时操作。

二、BroadcastReceiver的基本用法

利用BroadcastReceiver接收广播的基本步骤如下。

①创建BroadcastReceiver的子类。

由于BroadcastReceiver本质上是一种监听器,所以为了使用BroadcastReceiver的方法,只需要创建一个BroadcastReceiver的子类,然后重写其onReceive()方法即可。

②注册BroadcastReceiver。

为了能够执行 BroadcastReceiver的方法,还需要为该 BroadcastReceiver指定匹配的 Intent,即注册该BroadcastReceiver。注册方式可分为以下两种。

方式1:静态注册:静态注册方式是在AndroidManifest.xml配置文件中注册 BroadcastReceiver,通过这种方式注册的广播为常驻型广播,尽管应用程序关闭了,如果有相应的事件触发了该程序,其广播接收功能还是会被系统自动调用。静态注册 BroadcastReceiver的基本XML 代码如下:

receiver android:name="com.example.test.MyBroadcastReceiver">
    <intent-filter android:priority="100">
        <action android:name="android.intent.action.MyBroadcastReceiver">
			</action>
     </intent-filter>
</receiver>

方式2:动态注册:利用Java代码在程序中注册BroadcastReceiver,并且在Activity销毁时调用unregisterReceiver(receiver)方法注销该注册,否则 Activity销毁时会出现异常。通过这种方式注册的广播为非常驻型广播,它会与当前Activity保持同样的生命周期, 即只有在程序运行时才会收到广播消息,程序停止运行后就收不到了。基本Java代码如下:

MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MY_BROADCAST");
registerReceiver(receiver, filter);
//Activity销毁时
@Override
protected void onDestroy() {
    super.onDestroy();
	//解除注册BroadcastReceive
    unregisterReceiver(receiver); 
}

(3)申请权限

Android权限的申请有两种方式静态申请和动态申请

静态申请:是在应用安装的时候一次性申请所有权限。静态申请通过在AndroidManifest.xml 中添加相应的权限标记实现(详见以下相关示例)。

动态申请:Google从 Android 6.0( API Level 23 )开始引入了动态权限申请机制,将所有权限分成了正常权限和危险权限。应用的相关功能每次在使用危险权限时,需要动态申请并得到用户的授权才能使用。动态申请权限通过程序代码实现(详见以下相关示例)。

系统权限分为两类:正常权限和危险权限。

正常权限:不会直接给用户隐私权带来风险。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。

危险权限:会授予应用访问用户机密数据的权限。如果您的应用在其清单中列出了正常权限,系统将自动授予该权限。如果您列出了危险权限,则用户必须明确批准您的应用使用这些权限。危险权限都属于权限组,具体权限见下表。

权限组

权限

CALENDAR

READ_CALENDAR

WRITE_CALENDAR

CAMERA

CAMERA

CONTACTS

READ_CONTACTS

WRITE_CONTACTS

GET_ACCOUNTS

LOCATION

ACCESS_FINE_LOCATION

ACCESS_COARSE_LOCATION

MICROPHONE

RECORD_AUDIO

PHONE

READ_PHONE_STATE

CALL_PHONE

READ_CALL_LOG

WRITE_CALL_LOG

ADD_VOICEMAIL

USE_SIP

PROCESS_OUTGOING_CALLS

SENSORS

BODY_SENSORS

SMS

SEND_SMS

RECEIVE_SMS

READ_SMS

RECEIVE_WAP_PUSH

RECEIVE_MMS

STORAGE

READ_EXTERNAL_STORAGE

WRITE_EXTERNAL_STORAGE

三.简单Demo的实现

本Demo摘自《第一行代码》

1.首先,创建一个BroadcastReceiver,只需子类去继承自BroadcastReceiver,并重写父类的onReceiver方法即可。

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

public class MyReceiver extends BroadcastReceiver {

    
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.

            Toast.makeText(context,"这是什么鬼", Toast.LENGTH_SHORT).show();
        Log.i("tag","fashong;lle");

    }
}

import androidx.appcompat.app.AppCompatActivity;

import android.content.IntentFilter;

import android.os.Bundle;


public class MainActivity extends AppCompatActivity {
  private  MyReceiver myReceiver;

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


        //为过滤器设置动作
        filter.addAction("android.intent.action.TIME_TICK");
       //实例化MyReceiver
         myReceiver=new MyReceiver();

        //动态注册过滤器
        registerReceiver(myReceiver,filter);

    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
   // 注销动态注册(方式2)的BroadcastReceiver
        unregisterReceiver(myReceiver);
    }
}

动态注册时,首先创建 IntentFilter的实例,并添加android.intent.action.TIME_TICK的action,添加这个值,是为了实现广播监听,当时间发生变化时,系统发出的正是一条值为android.intent.action.TIME_TICK的广播。BroadcastReceiver想要监听什么样的广播,就添加相应的action。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐