一、收发标准广播
Android的广播机制正式借鉴了Wifi的通信原理,不必搭建专门的通路,就能在发送方与接收方之间建立连接,同时广播也是Android的四大组件之一,它用于Android各组件之间的灵活通信,与活动的区别在于以下几点
1:活动只能一对一通信,而广播可以一对多,一人发送广播,多人接收处理
2:对于发送方来说 广播不需要考虑接收放有没有在工作
3:对于接收方来说,因为可能会收到各式各样的广播,所以接收方要过滤符合条件的广播
与广播有关的方法主要有以下三个
1:sendBoradcast 发送广播
2:registerReceiver 注册广播的接收器
3:unregisterReceiver 注销广播的接收器
广播收发过程可以分为以下三个步骤
1:发送标准广播
2:定义广播接收器
3:开关广播接收器
实战效果如下
点击发送标准广播按钮后即显示收到了广播
代码如下
Java类代码
package com.example.chapter09; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter09.util.DateUtil; public class BroadStandardActivity extends AppCompatActivity implements View.OnClickListener { private final static String TAG = "BroadStandardActivity"; // 这是广播的动作名称,发送广播和接收广播都以它作为接头暗号 private final static String STANDARD_ACTION = "com.example.chapter09.standard"; private TextView tv_standard; // 声明一个文本视图对象 private String mDesc = "这里查看标准广播的收听信息"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_broad_standard); tv_standard = findViewById(R.id.tv_standard); tv_standard.setText(mDesc); findViewById(R.id.btn_send_standard).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_send_standard) { Intent intent = new Intent(STANDARD_ACTION); // 创建指定动作的意图 sendBroadcast(intent); // 发送标准广播 } } private StandardReceiver standardReceiver; // 声明一个标准广播的接收器实例 @Override protected void onStart() { super.onStart(); standardReceiver = new StandardReceiver(); // 创建一个标准广播的接收器 // 创建一个意图过滤器,只处理STANDARD_ACTION的广播 IntentFilter filter = new IntentFilter(STANDARD_ACTION); registerReceiver(standardReceiver, filter); // 注册接收器,注册之后才能正常接收广播 } @Override protected void onStop() { super.onStop(); unregisterReceiver(standardReceiver); // 注销接收器,注销之后就不再接收广播 } // 定义一个标准广播的接收器 private class StandardReceiver extends BroadcastReceiver { // 一旦接收到标准广播,马上触发接收器的onReceive方法 @Override public void onReceive(Context context, Intent intent) { // 广播意图非空,且接头暗号正确 if (intent != null && intent.getAction().equals(STANDARD_ACTION)) { mDesc = String.format("%s\n%s 收到一个标准广播", mDesc, DateUtil.getNowTime()); tv_standard.setText(mDesc); } } } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <Button android:id="@+id/btn_send_standard" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="发送标准广播" android:textColor="@color/black" android:textSize="17sp" /> <TextView android:id="@+id/tv_standard" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="left" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
二、收发有序广播
一个广播存在多个接收器,这些接收器需要排队收听广播,这意味着该广播是条有序广播,
先收到广播的接收器A,既可以让其他接收器继续收听广播,也可以中断广播不让其他接收器收听
实现有序广播的收发,需要完成以下三个步骤
1:发送广播时要注明这是一个有序广播
2:定义有序广播的接收器
3:注册有序广播的多个接收器
效果如下
点击接收后中断广播那么只有B接收到了广播,A没有
代码如下
Java类
package com.example.chapter09; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View; import android.widget.CheckBox; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter09.util.DateUtil; public class BroadOrderActivity extends AppCompatActivity implements View.OnClickListener { private final static String TAG = "BroadOrderActivity"; private final static String ORDER_ACTION = "com.example.chapter09.order"; private CheckBox ck_abort; private TextView tv_order; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_broad_order); ck_abort = findViewById(R.id.ck_abort); tv_order = findViewById(R.id.tv_order); findViewById(R.id.btn_send_order).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_send_order) { tv_order.setText(""); Intent intent = new Intent(ORDER_ACTION); // 创建一个指定动作的意图 sendOrderedBroadcast(intent, null); // 发送有序广播 } } @Override protected void onStart() { super.onStart(); // 多个接收器处理有序广播的顺序规则为: // 1、优先级越大的接收器,越早收到有序广播; // 2、优先级相同的时候,越早注册的接收器越早收到有序广播 orderAReceiver = new OrderAReceiver(); // 创建一个有序广播的接收器A // 创建一个意图过滤器A,只处理ORDER_ACTION的广播 IntentFilter filterA = new IntentFilter(ORDER_ACTION); filterA.setPriority(8); // 设置过滤器A的优先级,数值越大优先级越高 registerReceiver(orderAReceiver, filterA); // 注册接收器A,注册之后才能正常接收广播 orderBReceiver = new OrderBReceiver(); // 创建一个有序广播的接收器B // 创建一个意图过滤器A,只处理ORDER_ACTION的广播 IntentFilter filterB = new IntentFilter(ORDER_ACTION); filterB.setPriority(10); // 设置过滤器B的优先级,数值越大优先级越高 registerReceiver(orderBReceiver, filterB); // 注册接收器B,注册之后才能正常接收广播 } @Override protected void onStop() { super.onStop(); unregisterReceiver(orderAReceiver); // 注销接收器A,注销之后就不再接收广播 unregisterReceiver(orderBReceiver); // 注销接收器B,注销之后就不再接收广播 } private OrderAReceiver orderAReceiver; // 声明有序广播接收器A的实例 // 定义一个有序广播的接收器A private class OrderAReceiver extends BroadcastReceiver { // 一旦接收到有序广播,马上触发接收器的onReceive方法 @Override public void onReceive(Context context, Intent intent) { if (intent != null && intent.getAction().equals(ORDER_ACTION)) { String desc = String.format("%s%s 接收器A收到一个有序广播\n", tv_order.getText().toString(), DateUtil.getNowTime()); tv_order.setText(desc); if (ck_abort.isChecked()) { abortBroadcast(); // 中断广播,此时后面的接收器无法收到该广播 } } } } private OrderBReceiver orderBReceiver; // 声明有序广播接收器B的实例 // 定义一个有序广播的接收器B private class OrderBReceiver extends BroadcastReceiver { // 一旦接收到有序广播B,马上触发接收器的onReceive方法 @Override public void onReceive(Context context, Intent intent) { if (intent != null && intent.getAction().equals(ORDER_ACTION)) { String desc = String.format("%s%s 接收器B收到一个有序广播\n", tv_order.getText().toString(), DateUtil.getNowTime()); tv_order.setText(desc); if (ck_abort.isChecked()) { abortBroadcast(); // 中断广播,此时后面的接收器无法收到该广播 } } } } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <CheckBox android:id="@+id/ck_abort" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="left|center" android:checked="false" android:text="接收之后是否中断广播" android:textColor="@color/black" android:textSize="17sp" /> <Button android:id="@+id/btn_send_order" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="发送有序广播" android:textColor="@color/black" android:textSize="17sp" /> <TextView android:id="@+id/tv_order" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="left" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
三、收发静态广播
静态广播在现在的Android中比较少用,因为不太安全 下面看看效果即可 实现了手机的震动功能
java类代码如下
package com.example.chapter09; import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter09.receiver.ShockReceiver; public class BroadStaticActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_broad_static); findViewById(R.id.btn_send_shock).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_send_shock) { // Android8.0之后删除了大部分静态注册,防止退出App后仍在接收广播, // 为了让应用能够继续接收静态广播,需要给静态注册的广播指定包名。 String receiverPath = "com.example.chapter09.receiver.ShockReceiver"; Intent intent = new Intent(ShockReceiver.SHOCK_ACTION); // 创建一个指定动作的意图 // 发送静态广播之时,需要通过setComponent方法指定接收器的完整路径 ComponentName componentName = new ComponentName(this, receiverPath); intent.setComponent(componentName); // 设置意图的组件信息 sendBroadcast(intent); // 发送静态广播 Toast.makeText(this, "已发送震动广播", Toast.LENGTH_SHORT).show(); } } }