BroadCast 广播
广播作用以及机制
其实BroadcastReceiver就是应用程序间的全局大喇叭,即通信的一个手段,
系统自己在很多时候都会发送广播,比如电量低或者充足,刚启动完,插入耳机,输入法改变等,
发生这些时间,系统都会发送广播,这个叫系统广播,每个APP都会收到,如果你想让你的应用在接收到
这个广播的时候做一些操作,比如:系统开机后,偷偷后台跑服务哈哈,这个时候你只需要为你的应用
注册一个用于监视开机的BroadcastReceiver,当接收到开机广播就做写偷偷摸摸的勾当~
当然我们也可以自己发广播,比如:接到服务端推送信息,用户在别处登录,然后应该强制用户下线回到
登陆界面,并提示在别处登录当然,这些等下都会写一个简单的示例帮大家了解广播给我们带来的好处.
项目中广播使用
BroadCastReceiver广播接受者,安卓四大组件之一
广播三要素: (1)广播发送者 : 发送广播 (2)广播接收者(调频): 用于接收广播 (3)要处理的事情 :处理广播的相关信息,
Intent有图对象 广播的使用场景:
(1)同一APP下多个组件之间传递数据(Activity/Fragment/Service之间传递数据) (2)2个APP之间传递数据
技能get点: (1)自定义广播接受者 (2)使用广播接受者进行电话拦截和短信拦截和系统电量的变化
广播生命周期
静态注册和动态注册的区别:假如说Activity是接受者: 动态注册: (1)广播会跟Activity的生命周期的结束而结束;
(2)自由的控制注册和取消,有很大的灵活性 静态注册:
(1)广播不会跟随Activity的生命周期的结束而结束,一直存在,即使应用程序关闭,也会被唤醒接受广播 (2)全局的广播
广播的分类
无序广播发送 (也叫标准广播)
有序广播发送
如何实现广播
1,先创建一个广播,写一个类继承BroadcastReceiver即可
package com.example.day12;
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
2,注册一个广播
静态广播注册
在清单文件中注册广播就是静态的
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--我是一个广播-->
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.feng.broad"></action>
</intent-filter>
</receiver>
<!--广播结束-->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
动态广播注册
package com.example.day12;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.day12.util.BroadcastConst;
import java.io.BufferedReader;
import java.io.FileFilter;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button sendId;
private MyReceiver myReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendId = findViewById(R.id.send_id);
sendId.setOnClickListener(this);
//1,创建一个广播
myReceiver = new MyReceiver();
//添加广播过滤器
IntentFilter intentFilter = new IntentFilter();
//添加action
intentFilter.addAction(BroadcastConst.ACTION);
//注册
registerReceiver(myReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
//注销广播
unregisterReceiver(myReceiver);
}
}
发送一个无序广播
Intent intent = new Intent();
intent.setAction("com.feng.broad");
Bundle bundle = new Bundle();
bundle.putInt("msg",123);
intent.putExtras(bundle);
sendBroadcast(intent);
发送一个有序广播
Intent intent1 = new Intent();
intent1.setAction("com.feng.broad");
//第一个参数是intent 二是权限名.
sendOrderedBroadcast(intent1,null);
完整的代码如下
1,清单文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.day12">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<receiver
android:name=".MyReceiver2"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="com.feng.broad"></action>
</intent-filter>
</receiver>
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="900">
<action android:name="com.feng.broad" />
</intent-filter>
</receiver>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
java代码
package com.example.day12;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.day12.util.BroadcastConst;
import java.io.BufferedReader;
import java.io.FileFilter;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button sendId;
private MyReceiver myReceiver;
private Button sendOrderId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendOrderId = findViewById(R.id.send_order_id);
sendOrderId.setOnClickListener(this);
sendId = findViewById(R.id.send_id);
sendId.setOnClickListener(this);
//1,创建一个广播
// myReceiver = new MyReceiver();
// //添加广播过滤器
// IntentFilter intentFilter = new IntentFilter();
// //添加action
// intentFilter.addAction(BroadcastConst.ACTION);
// //注册
// registerReceiver(myReceiver,intentFilter);
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.send_id:
Intent intent = new Intent();
intent.setAction("com.feng.broad");
Bundle bundle = new Bundle();
bundle.putInt("msg",123);
intent.putExtras(bundle);
sendBroadcast(intent);
break;
case R.id.send_order_id:
Intent intent1 = new Intent();
intent1.setAction("com.feng.broad");
sendOrderedBroadcast(intent1,null);
break;
default:
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//注销广播
unregisterReceiver(myReceiver);
}
}
3,第一个广播
package com.example.day12;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.example.day12.util.BroadcastConst;
public class MyReceiver extends BroadcastReceiver {
private static final String TAG = "MyReceiver";
@Override
public void onReceive(Context context, Intent intent) {
//TODO 1:获取action
String action = intent.getAction();
if(BroadcastConst.ACTION.equals(action)){
// Bundle extras = intent.getExtras();
// int msg = extras.getInt("msg");
Log.i(TAG, "onReceive: ");
}
}
}
第二个广播
package com.example.day12;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class MyReceiver2 extends BroadcastReceiver {
private static final String TAG = "MyReceiver2";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("com.feng.broad")){
Log.i(TAG, "onReceive: +++");
//判断是不是有序广播
if(isOrderedBroadcast()){
//中断一个广播
abortBroadcast();
}
}
}
}
系统广播
安卓常用系统广播 https://blog.youkuaiyun.com/cc_want/article/details/82344899
接收系统广播
系统在某些时候会发送相应的系统广播,下面我们就来让我们的APP接收系统广播,
接收之前,还需要为我们的APP注册广播接收器哦!而注册的方法又分为以下两种:动态与静态!
静态接收系统锁屏广播
package com.example.day12;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class ScreenReceiver extends BroadcastReceiver {
private static final String TAG = "ScreenReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive: ------");
String action = intent.getAction();
if(Intent.ACTION_SCREEN_ON.equals(action)){ //不能用
Log.i(TAG, "onReceive: 亮了");
}else if(Intent.ACTION_SCREEN_OFF.equals(action)){//不能用
Log.i(TAG, "onReceive: 暗了");
}else if (Intent.ACTION_USER_PRESENT.equals(action)){
Log.i(TAG, "onReceive: 唤醒了");
}else if(Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)){
Log.i(TAG, "onReceive: 飞行了");
}
}
}
清单文件中注册
<receiver
android:name=".ScreenReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.SCREEN_ON"></action>
<action android:name="android.intent.action.SCREEN_OFF"></action>
<action android:name="android.intent.action.USER_PRESENT"></action>
<action android:name="android.intent.action.AIRPLANE_MODE"></action>
</intent-filter>
</receiver>
使用注意事项
不要在广播里添加过多逻辑或者进行任何耗时操作,因为在广播中是不允许开辟线程的, 当onReceiver()方法运行较长时间(超过10秒)还没有结束的话,那么程序会报错(ANR), 广播更多的时候扮演的是一个打开其他组件的角色,比如启动Service,Notification提示, Activity等!