全局大喇叭--广播机制
全局大喇叭--广播机制
- 一、 广播机制简介
- (1) 标准广播(Normal broadcasts)
- (2) 有序广播(Ordered broadcasts)
- 二、 接收系统广播
- 1. 动态注册监听网络变化
- 2. 静态注册实现开机启动
- 三、 发送自定义广播
- 1. 发送标准广播
- 2. 发送有序广播
- 四、 使用本地广播
- 五、 实践--实现强制下线功能
- 1. 新建一个BroadcastBestPractice项目,创建ActivityCollector类,用于管理所有活动,代码下所示
- 2. 创建BaseActivity类作为所有活动的父类
- 3. 然后创建一个登陆界面的活动,新建LoginActivity,并生成相应的布局文件,编辑login.xml文件,有登陆账号和密码进行登陆。
- 4. 修改LoginActivity中的代码是简单的登陆功能,如果登陆成功则进入MainActivity中。
- 5. 在main.xml中增加一个按钮,点击按钮则显示强制退出
- 6. 修改MainActivity代码,用于通知广播,强制下线
- 7. 这些活动都继承BaseActivity
- 8. 在AndroidMainfest.xml文件进行修改,启动手机时进入登陆页面
为了便于进行系统级别的消息通知,Android也引入了一套类似的广播消息机制。
一、 广播机制简介
广播的类型:标准广播和有序广播
(1) 标准广播(Normal broadcasts)
是一种完全异步执行的广播,在广播发出后,所有的广播接收器几乎会在同一时刻接收到这条广播信息,因此他们之间没有先后顺序。这种广播的效率比较高,但同时意味着无法被截断的。
(2) 有序广播(Ordered broadcasts)
是一种同步执行的广播,在广播发出后,同一时刻会有一个广播能够接收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。
且广播有先后顺序的,优先级高的可以先接收,可以截断正在传递的广播。
二、 接收系统广播
Android内置了很多系统级别的广播,在应用程序中通过监听这些广播来得到各种系统的状态信息。(手机开机完成后、电池的电量变化、会发出一条广播)。如果想要接收这些广播,就需要使用广播接收器。
1. 动态注册监听网络变化
广播接收器可以自由地对自己感兴趣的广播进行注册,一般有两种::在代码中注册(动态注册)和在AndroidMainfest.xml中注册(静态注册)。
如何创建一个广播接收器呢?
首先需要新建一个类,让他继承自BroadcastReceiver,并重写父类的onReceive()的方法就行了。
(1) 新建一个BroadcastTest项目,修改MainActivity中的代码。
public class MainActivity extends AppCompatActivity {private IntentFilter intentFilter;private NetworkChangeReceiver networkChangeReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);intentFilter =new IntentFilter();//创建IntentFilter的实例intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//广播想要监听的内容,添加相应的actionnetworkChangeReceiver =new NetworkChangeReceiver();//创建 NetworkChangeReceiver实例registerReceiver(networkChangeReceiver,intentFilter);//这样就会接收到广播,实现了监听网络变化功能}@Overrideprotected void onDestroy() { //动态注册的广播接收器一定都要取消注册才行super.onDestroy();unregisterReceiver(networkChangeReceiver);}//每当网络状态发生变化时,onReceive()得到执行,只是简单地使用Toast提示一段文本信息class NetworkChangeReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "network changes", Toast.LENGTH_SHORT).show();}}
}
(2) 运行程序,会出现一条广播。接着按下home键(不能按back键,否则onDestroy()方法会执行),然后打开setting程序 ->Data usage进入到数据使用详情界面,然后开关Cellular data 按钮来开启和禁用网络,你会看到Toast提醒网络发生变化。
2. 静态注册实现开机启动
让程序在未启动的情况下就能接收到广播—静态注册
可以使用AS提供的快捷方式来创建一个广播接收器,点击com.example.broadcaasttest 包新建…,会弹出一个窗口。
将广播接收器命名为如图所示,Exported属性表示是否允许这个广播接收器接收本程序以外的广播;Enabled属性表示是否启用这个广播接收器。
(3) 修改其中代码,如图所示,用onReceive()方法中使用Toast弹出一段提示信息
(4) 静态广播接收器一定要在AndroidManifest.xml文件中注册才可以使用,不过AS已经自动完成了,给他添加标签加入action,并添加权限
(5) 重新运行程序后,就可以接收开机广播了。
三、 发送自定义广播
1. 发送标准广播
(1) 首先新建一个MyBroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "recevied in MyBraodcastReceiver ", Toast.LENGTH_SHORT).show();}
}
(2) 然后在AndroidMainfest.xml中对这个广播接收器进行修改,让接收器接收到com.example.broadcasttest.MY_BROADCAST的广播
<receiverandroid:name=".MyBroadcastReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.example.broadcasttest.MY_BROADCAST"/></intent-filter></receiver>
(3) 在布局中定义一个按钮,用于发送广播的触发点。
Button button =(Button)findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent =new Intent("com.example.broadcasttest.MY_BROADCAST");sendBroadcast(intent);}});
2. 发送有序广播
(1) 新建一个项目,创建AntherBroadcastReceiver,代码如下:
@Override
public void onReceive(Context context, Intent intent) {Toast.makeText(context, "received anothorReceiver~~~~~", Toast.LENGTH_SHORT).show();
}
(2) 对AndroidMainifest.xml对这个广播接收器进行修改,到这里,程序发出的还是标准广播,让我们尝试一下发送有序广播。
<receiverandroid:name=".AnthorReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="com.example.broadcasttest.MY_BROADCAST"/></intent-filter></receiver>
(1) 回到BroadcastTest项目,修改MainActivity中代码
Button button =(Button)findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent =new Intent("com.example.broadcasttest.MY_BROADCAST");// sendBroadcast(intent);sendOrderedBroadcast(intent,null); //第一个参数是intent,第二个则是与权限相关的字符串}});
(2) 修改AndroidMainifest.xml中的代码,用priority设置优先级
(3) 修改MyBroadcastReceiver中的代码
abortBroadcast();
能看到自由一条消息传播,经过abortBroadcast()方法,就表示将这条广播截断
四、 使用本地广播
为了解决广播的安全性问题,使用这个机制只能在应用程序的内部进行传递。修改MainActivity中的代码
public class MainActivity extends AppCompatActivity {private IntentFilter intentFilter;private LocalReceiver localReceiver;private LocalBroadcastManager localBroadcastManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);localBroadcastManager =LocalBroadcastManager.getInstance(this);Button button =(Button)findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent =new Intent("com.example.broadcasttest.MY_BROADCAST");// sendBroadcast(intent);// sendOrderedBroadcast(intent,null);localBroadcastManager.sendBroadcast(intent);}});intentFilter =new IntentFilter();//创建IntentFilter的实例intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");//广播想要监听的内容,添加相应的actionlocalReceiver =new LocalReceiver();localBroadcastManager.registerReceiver(localReceiver,intentFilter);//注册本地广播监听器}@Overrideprotected void onDestroy() {super.onDestroy();localBroadcastManager.unregisterReceiver(localReceiver);}class LocalReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "received++++++++++++++", Toast.LENGTH_SHORT).show();}}
}
五、 实践–实现强制下线功能
1. 新建一个BroadcastBestPractice项目,创建ActivityCollector类,用于管理所有活动,代码下所示
public class ActivityCollector {public static List<Activity> activities =new ArrayList<>();public static void addActivity(Activity activity){activities.add(activity);}public static void removeActivity(Activity activity){activities.remove(activity);}public static void finishAll(){for (Activity activity :activities){if (!activity.isFinishing()){activity.finish();}}}
}
2. 创建BaseActivity类作为所有活动的父类
public class BaseActivity extends AppCompatActivity {@Overrideprotected void onDestroy() {super.onDestroy();ActivityCollector.removeActivity(this);}@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityCollector.addActivity(this);}
}
3. 然后创建一个登陆界面的活动,新建LoginActivity,并生成相应的布局文件,编辑login.xml文件,有登陆账号和密码进行登陆。
<?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:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".LoginActivity"><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="60dp"><TextViewandroid:layout_width="90dp"android:layout_height="wrap_content"android:gravity="center_vertical"android:textSize="18sp"android:text="Account:"/><EditTextandroid:id="@+id/account"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:layout_gravity="center_vertical"/></LinearLayout><LinearLayoutandroid:orientation="horizontal"android:layout_width="match_parent"android:layout_height="60dp"><TextViewandroid:layout_width="90dp"android:layout_height="wrap_content"android:gravity="center_vertical"android:textSize="18sp"android:text="Password:"/><EditTextandroid:id="@+id/password"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:layout_gravity="center_vertical"android:inputType="textPassword"/></LinearLayout><Buttonandroid:id="@+id/login"android:layout_width="match_parent"android:layout_height="60dp"android:text="Login"/>
</LinearLayout>
4. 修改LoginActivity中的代码是简单的登陆功能,如果登陆成功则进入MainActivity中。
public class LoginActivity extends BaseActivity {private EditText accountEdit;private EditText passwordEdit;private Button login;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);accountEdit =(EditText) findViewById(R.id.account);passwordEdit =(EditText) findViewById(R.id.password);login=(Button) findViewById(R.id.login);login.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String account =accountEdit.getText().toString();String password =passwordEdit.getText().toString();if (account.equals("admin")&&password.equals("123")){Intent intent =new Intent(LoginActivity.this,MainActivity.class);startActivity(intent);finish();}else {Toast.makeText(LoginActivity.this, "try again ", Toast.LENGTH_SHORT).show();}}});}
}
5. 在main.xml中增加一个按钮,点击按钮则显示强制退出
<Buttonandroid:id="@+id/force_offline"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Send force _______________"/>
6. 修改MainActivity代码,用于通知广播,强制下线
public class MainActivity extends BaseActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button forceOffline=(Button) findViewById(R.id.force_offline);forceOffline.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent("com.example.broadcastbestpractice.FORCE_OFFLINE");sendBroadcast(intent);}});}
}
7. 这些活动都继承BaseActivity
public class BaseActivity extends AppCompatActivity {private ForceofflineReceiver receiver;@Overrideprotected void onDestroy() {super.onDestroy();ActivityCollector.removeActivity(this);}@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityCollector.addActivity(this);}@Overrideprotected void onPause() {super.onPause();if (receiver!=null){unregisterReceiver(receiver);receiver=null;}}@Overrideprotected void onResume() {super.onResume();IntentFilter intentFilter =new IntentFilter();intentFilter.addAction("com.example.broadcastbestpractice.FORCE_OFFLINE");receiver =new ForceofflineReceiver();registerReceiver(receiver,intentFilter);}class ForceofflineReceiver extends BroadcastReceiver{@Overridepublic void onReceive(final Context context, Intent intent) {AlertDialog.Builder builder =new AlertDialog.Builder(context);builder.setTitle("Warning!!!!!!!");builder.setMessage("TRY AGAIN!!!!!!!!!!!");builder.setCancelable(false);builder.setPositiveButton("ok==", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {ActivityCollector.finishAll(); //销毁所有活动Intent intent =new Intent(context,LoginActivity.class);context.startActivity(intent);}});builder.show();}}
}
8. 在AndroidMainfest.xml文件进行修改,启动手机时进入登陆页面
<activityandroid:name=".LoginActivity"android:exported="true" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>
点击按钮,强制下线
全局大喇叭--广播机制相关推荐
- Android 第十九课 大喇叭--广播机制----动态注册监听网络变化与静态注册实现开机启动
为了便于进行 系统级别的消息通知,Android引入了一套广播消息机制. 1.广播机制简介: 因为Android中的每个应用程序都可以对自己感兴趣的广播尽心注册,这样程序只会接收自己所关心的广播内容, ...
- Android 全局大喇叭——详解广播机制
Android 全局大喇叭--详解广播机制 一.广播机制简介 1. 标准广播(Normal broadcasts) 2. 有序广播(Ordered broadcasts) 二.接收系统广播 1. 动态 ...
- 广播机制-BroadCastReceiver
广播机制 1.广播机制概述 1.1生活中的广播机制 1.显示生活中的广播就比如说村里的大喇叭,车上的收音机接收的广播FM广播,学校里的校园广播都是常见的广播,安卓中的广播和生活中的广播是十分类似的. ...
- Android - 广播机制和Service
花了几天,想实现定位功能,使用的是百度的服务,有时真的很无奈,就是一小小个问题,就能折腾好几天. 首先,我是在主线程(Fragment)中单独进行定位,发现不起作用. 然后我想使用Service和广播 ...
- 第一行代码学习笔记第五章——详解广播机制
知识点目录 5.1 广播机制 5.2 接收系统广播 * 5.2.1 动态注册监听网络变化 * 5.2.2 静态注册实现开机广播 5.3 发送自定义广播 * 5.3.1 发送标准广播 * 5.3.2 发 ...
- Android广播机制:Broadcast
转载:Android总结篇系列:Android广播机制 1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广 ...
- 【Android】四大组件介绍 *广播机制*
一.广播机制 1.概念 广播机制是用来互相传递信息的一种组件 2.组成部分 发送者(sendBroadcast()) 通过设置Action,标识该广播可被哪些接收器收到. 可通过putExtra,传递 ...
- Android四大组件系列7 Broadcast广播机制(上)
一 概述 广播 (Broadcast) 机制用于进程或线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者 BroadcastReceiver 是 Android 四大组件之一.Broadc ...
- Android 广播机制详解
一.广播的简介 首先,当我们一听到广播这个词时.就可以想到小学是教室的广播.不错Android中的广播机制与我们生活中的广播是有异曲同工之妙的.Android中的发送广播也就像广播室播广播,可以让很多 ...
最新文章
- 区块链系列4-智能合约
- 非常好用的一些软件和网站
- 一台比亚迪秦EV充电时自燃 相关人员:无人员伤亡、起火未爆炸
- Neo4j从mysql读取数据_[bigdata-086] python3+neo4j 从mysql数据库读取记录然后创建节点和关系写入到neo4j...
- Lynis – 用于Linux服务器的自动安全审计工具
- java -D參数简化增加多个jar【简化设置classpath】
- swagger注释API详细说明
- 【渝粤教育】国家开放大学2018年春季 0092-22T民法 参考试题
- 元素内容必须由格式正确的字符数据或标记组成_字符编码是什么?html5如何设置字符编码?...
- linux安装软件常用命令
- 如何用计算机截部分屏,电脑截图只截一部分怎么办
- SQLSERVER 查询分析器快捷键
- 添加打印机,错误为0x0000011b
- MVC进阶学习--View和Controller之间的数据传递(一)
- 计算机操作系统试题 地址变换,计算机操作系统试题及答案汇编
- 计蒜客 联想专卖店大促销
- html前端的几种加密/解密方式
- linux内核panic
- php中文加密解密,php加密解密详解
- Transporter 上传iPA上架