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.csdn.net/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等!