赞
踩
用途:
Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器)。广播作为Android组件间的通信方式,可以使用的场景如下:
从实现原理看上,Android中的广播使用了观察者模式,基于消息的发布/订阅事件模型。因此,从实现的角度来看,Android中的广播将广播的发送者和接受者极大程度上解耦,使得系统能够方便集成,更易扩展。具体实现流程要点粗略概括如下:
<!--添加状态改变的权限-->
<uses-permission android:name="android.permission.BATTERY_STATS"
tools:ignore="ProtectedPermissions" />
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //第二步:我们要收听的频道是:电量变化 IntentFilter intentFilter = new IntentFilter(); //第三步:然后设置频道,这里设置的频道就是电量的变化 intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //第四部:实例化对象 BatterLevelRecever batterLevelRecever = new BatterLevelRecever(); //第五步:注册广播 this.registerReceiver(batterLevelRecever, intentFilter); } //第一步,首先创建一个广播接收器,继承自BroadcastReceiver,然后覆写onReceive方法 private class BatterLevelRecever extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "收到了状态改变的广播" + action); } } }
个人理解就是,首先创建一个类,让其继承自BroadcastReceiver,并重写父类的onReceive()方法。当广播来临时,onReceive()就会得到调用,具体的逻辑就可以在这个方法里面处理。
D/MainActivity: 收到了状态改变的广播android.intent.action.BATTERY_CHANGED
至此,一个监听电量变化的广播就创建好了
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private TextView batterLevelText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定控件 initView(); RegisterBatterReveiver(); } //找到控件 public void initView(){ batterLevelText = this.findViewById(R.id.battery_level); } //注册广播的方法 private void RegisterBatterReveiver() { //我们要收听的频道是:电量变化 IntentFilter intentFilter = new IntentFilter(); //然后设置频道,这里设置的频道就是电量的变化 intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //实例化对象 BatterLevelRecever batterLevelRecever = new BatterLevelRecever(); //注册广播 this.registerReceiver(batterLevelRecever, intentFilter); } //第一步,首先创建一个广播接收器,继承自BroadcastReceiver,然后覆写onReceive方法 private class BatterLevelRecever extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.d(TAG, "收到了状态改变的广播" + action); //显示电池当前电量 Log.d(TAG, "当前电量:"+intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0)); //首先必须进行判空,因为如果注册广播的代码在准备控件的代码之前,就会出现异常 if (batterLevelText != null) { batterLevelText.setText("当前电量:"+intent.getIntExtra(BatteryManager.EXTRA_LEVEL,0)); } } } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/battery_level" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_marginLeft="30dp" android:id="@+id/battery_percent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/battery_level" /> </RelativeLayout>
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private TextView batterLevelText; private TextView batterPercentText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定控件 initView(); RegisterBatterReveiver(); } //找到控件 public void initView() { batterLevelText = this.findViewById(R.id.battery_level); batterPercentText = findViewById(R.id.battery_percent); } //注册广播的方法 private void RegisterBatterReveiver() { //我们要收听的频道是:电量变化 IntentFilter intentFilter = new IntentFilter(); //然后设置频道,这里设置的频道就是电量的变化 intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //实例化对象 BatterLevelRecever batterLevelRecever = new BatterLevelRecever(); //注册广播 this.registerReceiver(batterLevelRecever, intentFilter); } //第一步,首先创建一个广播接收器,继承自BroadcastReceiver,然后覆写onReceive方法 private class BatterLevelRecever extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { Log.d(TAG, "收到了状态改变的广播" + action); //显示电池当前电量 Log.d(TAG, "当前电量:" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)); int currentlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); //首先必须进行判空,因为如果注册广播的代码在准备控件的代码之前,就会出现异常 if (batterLevelText != null) { batterLevelText.setText("当前电量:" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)); } int maxlevel = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); //拿到当前电量后再除以最大值 float percent = currentlevel * 1.0f / maxlevel * 100; Log.d(TAG, "当前电量百分比是:" + percent + "%"); if (batterPercentText != null) { batterPercentText.setText("百分比:" + percent + "%"); } } } } }
//这个频道为连接USB
intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
//这个频道为顿开USB
intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
else if(Intent.ACTION_POWER_CONNECTED.equals(action)){
Log.d(TAG, "usb连接成功");
}else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)){
Log.d(TAG, "usb断开");
}
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private TextView batterLevelText; private TextView batterPercentText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定控件 initView(); RegisterBatterReveiver(); } //找到控件 public void initView() { batterLevelText = this.findViewById(R.id.battery_level); batterPercentText = findViewById(R.id.battery_percent); } //注册广播的方法 private void RegisterBatterReveiver() { //我们要收听的频道是:电量变化 IntentFilter intentFilter = new IntentFilter(); //然后设置频道,这里设置的频道就是电量的变化 intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); //这个频道为连接USB intentFilter.addAction(Intent.ACTION_POWER_CONNECTED); //这个频道为顿开USB intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED); //实例化对象 BatterLevelRecever batterLevelRecever = new BatterLevelRecever(); //注册广播 this.registerReceiver(batterLevelRecever, intentFilter); } //第一步,首先创建一个广播接收器,继承自BroadcastReceiver,然后覆写onReceive方法 private class BatterLevelRecever extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { Log.d(TAG, "收到了状态改变的广播" + action); //显示电池当前电量 Log.d(TAG, "当前电量:" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)); int currentlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); //首先必须进行判空,因为如果注册广播的代码在准备控件的代码之前,就会出现异常 if (batterLevelText != null) { batterLevelText.setText("当前电量:" + intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)); } int maxlevel = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0); //拿到当前电量后再除以最大值 float percent = currentlevel * 1.0f / maxlevel * 100; Log.d(TAG, "当前电量百分比是:" + percent + "%"); if (batterPercentText != null) { batterPercentText.setText("百分比:" + percent + "%"); } }else if(Intent.ACTION_POWER_CONNECTED.equals(action)){ Log.d(TAG, "usb连接成功"); }else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)){ Log.d(TAG, "usb断开"); } } } }
1.首先创建一个广播接收器类,继承自BroadcastReceiver,然后重写父类中onReceive()方法
2.实例化IntentFilter类;
3.设置频道,使用intentFilter.addAction()方法;
4.实例化广播接收器类;
5.注册广播,使用this.registerReceiver();
6.必须要销毁该广播接收器
//取消广播注册
@Override
protected void onDestroy() {
super.onDestroy();
//取消广播注册,否则会导致内存泄露
if (batterLevelRecever != null) {
this.unregisterReceiver(batterLevelRecever);
}
}
public class BootCompleteReceiver extends BroadcastReceiver {
private static final String TAG = "BootCompleteReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "action is == " + action);
Log.d(TAG, "开机完成");
Toast.makeText(context, "收到开机完成的广播", Toast.LENGTH_LONG).show();
}
}
<!--第二步,跟动态设置action是一样的-->
<receiver android:name=".BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
</application>
在标签下面要添加一个i标签,在标签里面在添加一个标签。
相当于动态注册时的这两部分
IntentFilter intentFilter = new IntentFilter(); //然后设置频道,这里设置的频道就是电量的变化 intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
- 1
- 2
- 3
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
静态和动态最大的区别就是,静态注册一旦完成不可终止,会一直保持监听状态。但是动态可以随时注册,随时销毁,可以和activity保持相同的生命周期
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SendBroadcastActivity" android:orientation="vertical"> <EditText android:id="@+id/be_sent_message" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入发送内容"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送一条广播通知" android:onClick="SendBroadCast" tools:ignore="OnClick" /> </LinearLayout>
一个输入框用来输入发送的广播内容,一个按钮用来发送广播
package com.example.broadcast_learning; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.EditText; public class SendBroadcastActivity extends AppCompatActivity { private EditText inputBox; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_send_broadcast); inputBox = findViewById(R.id.be_sent_message); } //点击按钮,此方法会被调用 public void SendBroadCast(View view){ //被调用之后发送广播 String content = inputBox.getText().toString(); Intent intent = new Intent(); //设置频道 intent.setAction(Constants.ACTION_SEND_MSG); //设置数据 intent.putExtra(Constants.ACTION_CONTENT,content); //发送广播 sendBroadcast(intent); } }
用来封装自定义广播的频道和数据内容
package com.example.broadcast_learning;
public class Constants {
public static final String ACTION_SEND_MSG = "com.example.broadcast_learning.SEND_MSG";
public static final String ACTION_CONTENT = "content";
}
特别注意!!!
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H247wg7M-1620915208308)(C:\Users\23737\Desktop\QQ图片20210513210555.png)]
public class MessageReceiver extends BroadcastReceiver {
private static final String TAG = "MessageReceiver";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "action is == "+action);
String stringExtra = intent.getStringExtra(Constants.ACTION_CONTENT);
Log.d(TAG, "自定义广播内容是:"+stringExtra);
Toast.makeText(context,"自定义广播内容是:"+stringExtra,Toast.LENGTH_LONG).show();
}
}
<!--自定义广播-->
<receiver android:name=".MessageReceiver">
<intent-filter >
<action android:name="android.intent.action.PACKAGE_ADDED"></action>
</intent-filter>
</receiver>
有序广播类似于单位的通知,由上级到下级一级一级的传达。特点是:
- 有序;
- 可以终止向下传达;
- 可以修改广播的内容;
无序广播就像是上学时的学校广播,谁都能听到。有序广播就像是校长的通知,一级一级向下传达
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".SendOrderBroadcastActivity" android:orientation="vertical"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="发送一个有序广播" android:onClick="sendOrderBroadcast" tools:ignore="OnClick" /> </LinearLayout>
public class SendOrderBroadcastActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_order_broadcast);
}
public void sendOrderBroadcast(View view){
Intent intent = new Intent();
intent.setAction(Constants.ACTION_ORDER_BROADVAST_TEST);
sendOrderedBroadcast(intent,null);
}
}
public class HighLevelReceiver extends BroadcastReceiver {
private static final String TAG = "HighLevelReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "high action is "+intent.getAction());
}
}
把高等级的广播接受到的信息打印出来
<!--有序广播高等级-->
<receiver android:name=".HighLevelReceiver">
<!--priority表示等级,值是-1000到1000,默认为0-->
<intent-filter android:priority="1000">
<action android:name="com.example.broadcast_learning.ORDER_BROADCAST" />
</intent-filter>
</receiver>
public class HighLevelReceiver extends BroadcastReceiver {
private static final String TAG = "HighLevelReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "high action is "+intent.getAction());
}
}
<!--有序广播低等级-->
<receiver android:name=".LowLevelReceiver">
<!--priority表示等级,值是-1000到1000,默认为0-->
<intent-filter android:priority="0">
<action android:name="com.example.broadcast_learning.ORDER_BROADCAST" />
</intent-filter>
</receiver>
public class HighLevelReceiver extends BroadcastReceiver {
private static final String TAG = "HighLevelReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "high action is "+intent.getAction());
//终止向下传达
abortBroadcast();
}
}
public class SendOrderBroadcastActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_send_order_broadcast); } public void sendOrderBroadcast(View view){ Intent intent = new Intent(); intent.setAction(Constants.ACTION_ORDER_BROADVAST_TEST); //准备广播数据 Bundle bundle = new Bundle(); bundle.putCharSequence("content","我是要被发送的广播内容"); sendOrderedBroadcast(intent,null,null,null, Activity.RESULT_OK,null,bundle); } }
public class HighLevelReceiver extends BroadcastReceiver {
private static final String TAG = "HighLevelReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "high action is "+intent.getAction());
//终止向下传达
abortBroadcast();
//修改广播内容
Bundle resultExtras = getResultExtras(true);
String content = resultExtras.getCharSequence("content").toString();
Log.d(TAG, "content-->"+content);
}
}
<!--首先定义权限-->
<permission android:name="com.example.broadcast_learning.ORDER_PERMISSION"/>
public void sendOrderBroadcast(View view){
Intent intent = new Intent();
intent.setAction(Constants.ACTION_ORDER_BROADVAST_TEST);
//准备广播数据
Bundle bundle = new Bundle();
bundle.putCharSequence("content","我是要被发送的广播内容");
sendOrderedBroadcast(intent,Manifest.permission.ORDER_PERMISSION,null,null, Activity.RESULT_OK,null,bundle);
}
<!--首先定义权限-->
<permission android:name="com.example.broadcast_learning.ORDER_PERMISSION"/>
这一步很重要,不然接收不到
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。