Android 自定义广播

发送和接收定向广播

实现点击发送按钮,收到广播弹出Toast提示

  • 1.新建一个广播MyBroadcastReceiver(直接用新建广播即可,自己创建java类的话不要忘记在manifest文件中进行注册)

    1
    2
    3
    4
    5
    6
    7
    public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    Log.d("test", "收到消息");
    Toast.makeText(context, "自定义广播接收器已经接收到消息", Toast.LENGTH_SHORT).show();
    }
    }

    自己创建的话,不要忘记注册

    1
    2
    3
    4
    5
     <receiver
    android:name=".MyBroadcastReceiver"
    android:enabled="true"
    android:exported="true">
    </receiver>
  • 2.主活动 实现点击事件

    Android对广播的要求越来越严,现在构造了intent后必须调用setComponet()方法,并且现在建立intent时不需要添加action参数,在manifest中注册时,也可以不指定action

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class MainActivity extends AppCompatActivity {
    private Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Log.d("test", "已发送");
    Intent intent = new Intent();
    //调用setComponent()方法
    intent.setComponent(new ComponentName(getPackageName(), "com.ccc.day09_mybroadcastreceiver.MyBroadcastReceiver"));
    sendBroadcast(intent);
    }
    });
    }
    }
  • 效果:

动态注册发送和接收不定向广播
  • 1.新建一个项目程序,创建广播接收器

    1
    2
    3
    4
    5
    6
    7
    public class AnotherBroadCastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "收到不定向广播消息", Toast.LENGTH_LONG).show();
    }
    }
  • 主活动动态注册广播

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class MainActivity extends AppCompatActivity {
    //设置为静态可以解决重复注册的问题
    static AnotherBroadCastReceiver anotherBroadCastReceiver;

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

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("MyBroadcast");
    if (anotherBroadCastReceiver == null) {
    anotherBroadCastReceiver = new AnotherBroadCastReceiver();
    registerReceiver(anotherBroadCastReceiver, intentFilter); //动态注册
    }
    }
    }
  • 再去修改上面那个项目的主活动,让其发送不定向广播

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class MainActivity extends AppCompatActivity {

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

    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Intent intent = new Intent("MyBroadcast"); //发送不定向广播
    sendBroadcast(intent);
    }
    });
    }
    }
  • 将上面两个项目程序安装在同一个模拟器上,然后依次启动项目2,项目1,项目1点击发送,项目2可以接收

  • 关闭项目2.会发现无法接收项目1发送的广播了,由此可见,动态注册的广播接收器只能在活动启动时接收广播

发送有序广播
  • 发送有序广播用sendOrderedBroadcast()方法,两个参数,第一个是intent,第二个是和权限相关的字符串,填写null就行了

    1
    2
    Intent intent = new Intent("MyBroadcast");
    sendOrderedBroadcast(intent,null);
  • 设置优先级大小 动态用intentFilter.setPriority(1000); 静态使用android:priority="1000",优先级高的可以先收到广播

    1
    2
    3
    4
    5
    6
    7
    //动态
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("MyBroadcast");
    // setPriority()设置权限大小
    intentFilter.setPriority(1000);
    anotherBroadCastReceiver = new AnotherBroadCastReceiver();
    registerReceiver(anotherBroadCastReceiver, intentFilter);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!--静态-->
    <receiver
    android:name=".util.BootCompleteReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter android:priority="1000"> <!--在这里设置-->
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
    </receiver>
  • 如果在onReceive()方法中调用了abortBroadcast()方法,那么广播有序广播传递到这里时会被截断,不再往下传

本地广播
  • 前面我们发送和接收的广播都属于系统全局广播,容易引起安全性问题,因此Android引入了一套本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收本应用程序发出的广播,这样来保证安全性

  • 引入依赖库

    1
    implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
  • 主活动修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     public class MainActivity extends AppCompatActivity {
    private IntentFilter intentFilter;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManger;

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

    // 获取实例
    localBroadcastManger = localBroadcastManger.getInstance(this);
    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Intent intent = new Intent("LocalBroadcast");
    // 发送广播
    localBroadcastManger.sendBroadcast(intent);
    }
    });

    // 注册广播
    intentFilter = new IntentFilter();
    intentFilter.addAction("LocalBroadcast");
    localReceiver = new LocalReceiver();
    localBroadcastManger.registerReceiver(localReceiver, intentFilter);
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();
    localBroadcastManger.unregisterReceiver(localReceiver);
    }

    private class LocalReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    Toast.makeText(context, "已接收到本地广播!",Toast.LENGTH_LONG).show();
    }
    }
    }

0%