廣播主要分兩種類型:標準廣播和有序廣播
發送標準廣播
- 首先定義一個廣播接收器來接收此廣播,新建一個MyBroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_LONG).show();
}
}
- 在AndroidManifest.xml中對這個廣播接收器進行修改
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.md.bb">
...
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.md.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
</manifest>
- 這里讓MyBroadcastReceiver接收一條值為com.example.md.MY_BROADCAST的廣播,所以在一會發廣播的時候得發一條這樣的廣播
- 修改Activity_main.xml中的代碼
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=" send Broadcast"/>
</LinearLayout>
- 定義一個按鈕作為發送廣播的觸發點,
- 修改MainActivity中的代碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 我們自定義的廣播
Intent intent = new Intent("com.example.md.MY_BROADCAST");
// 發送出去
sendBroadcast(intent);
}
});
}
}
- 在按鈕點擊事件中,首先構造出Intent對象,把要發送的廣播的值傳入,然后調用sendBroadcast()方法將廣播發送出去,這個時候所有監聽
com.example.md.MY_BROADCAST
這條廣播的廣播接收器就會收到一條消息,此時發送的就是標準廣播
2018-03-18_21-11-45.png
發送有序廣播
廣播是一種可以跨進程的通信,此前在我們程序內發出的廣播,其他的應用也是可以接收到的,再新建一個項目,用于接收上面的自定義廣播
- 新建AntotherBroadcastReceive
public class AntotherBroadcastReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in AntotherBroadcastReceive",Toast.LENGTH_SHORT).show();
Log.d("aaaaaaaaaa","aaaaaaaaaaaaaa");
}
}
- 仍然是在廣播接收器的onReceive()方法中彈出一段文本
- 在AndroidManifest.xml中對這個廣播進行修改
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.md.b2">
<application
...
<receiver
android:name=".AntotherBroadcastReceive"
android:enabled="true"
android:exported="true">
<intent-filter>
<!--這里是我們自定義的廣播-->
<action android:name="com.example.md.MY_BROADCAST"/>
</intent-filter>
</receiver>
</application>
</manifest>
- 在這個里面接收的仍然是這個廣播,現在運行第二個項目,把這個程序安裝到模擬器上,然后回到第一個項目的頁面,點擊按鈕,這個時候就會彈出兩個提示信息(此時第二項目別關)
第一次.png
第二次.png
2018-03-19_20-04-21.png
足以說明應用發出的廣播是可以被其他程序接收到的
- 發送有序廣播,還是在第一個項目中,在MainActivity中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
Button button_1 = (Button)findViewById(R.id.button_1);
button_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 我們自定義的廣播
Intent intent = new Intent("com.example.md.MY_BROADCAST");
// 添加進來
//sendBroadcast(intent);
sendOrderedBroadcast(intent,null);
}
});
}
- 可以看到,這里只改了一行的代碼將
sendBroadcast(intent)
改成了sendOrderedBroadcast(intent,null)
,這個方法接收兩個參數,第一個參數是Intent,第二個參數是一個與權限相關的字符串,這里傳入null就可以了,現在重啟程序,點擊按鈕,這兩個應用仍然都可以接收到這兩個廣播 - 此時和標準廣播好像沒什么區別,但是,這個時候廣播接收器是有先后順序的,而且前面的廣播接收器還可以將這個廣播進行截斷,阻止傳播
- 該怎么定義廣播接收器的先后順序呢,是在注冊的時候進行設定,還是在第一個項目中修改AndroidManifest.xml中的文件
...
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="com.example.md.MY_BROADCAST"/>
</intent-filter>
</receiver>
- 在這里通過
android:priority="100"
屬性設置了廣播接收器的優先級,優先級越高就可以先接受到廣播,這里設置為100 - 設置完優先級,那么就可以在MyBroadcastReceiver中選擇是否允許攔截這個廣播的傳遞
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received in MyBroadcastReceiver",Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
- 若在onReceive()方法中調用了abortBroadcast()方法,就表示將這個廣播進行攔截,后面的廣播接收器就無法再接收到這條廣播了,運行程序,這個時候就只會彈出一個信息了
本地廣播
前面使用的發送和接收的廣播都是系統的全局廣播,就是發出的和接收的廣播都可以被其他程序接收,這個時候安全性就下降了,這個時候,我們使用本地廣播,就是
發出的廣播只能夠在應用程序的內部使用,并且廣播接收器也只能接收來自本應用內部的廣播
- 在MainActivity中修改代碼,只要就是使用了LocalBroadcastManager來對廣播進行管理
public class MainActivity extends AppCompatActivity {
private IntentFilter intentFilter;
private LocalReceiver localReceiver;
private LocalBroadcastManager localBroadcastManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// 獲取實例
localBroadcastManager = LocalBroadcastManager.getInstance(this);
Button button_1 = (Button)findViewById(R.id.button_1);
button_1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 我們自定義的廣播
Intent intent = new Intent("com.example.md.LOCAL_BROADCAST");
//發送自定義廣播
localBroadcastManager.sendBroadcast(intent);
}
});
// // 創建一個實例
intentFilter = new IntentFilter();
// // 添加一個action,
intentFilter.addAction("com.example.md.LOCAL_BROADCAST");
localReceiver = new LocalReceiver();
//注冊的是本地的廣播接收器
localBroadcastManager.registerReceiver(localReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 動態注冊的廣播需要注冊
localBroadcastManager.unregisterReceiver(localReceiver);
}
class LocalReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"received local broadcast",Toast.LENGTH_SHORT).show();
}
}
}
- 這個和前面所學的動態注冊廣播接收器以及發送廣播的代碼基本相同
- 首先是通過
LocalBroadcastManager.getInstance(this)
獲取到它的實例 - 注冊廣播接收器的時候用的是
localBroadcastManager.registerReceiver()
- 發送廣播的時候調用的是
localBroadcastManager.sendBroadcast()
點擊按鈕的時候就會發出com.example.md.LOCAL_BROADCAST廣播,然后在LocalReceiver里接收這條廣播,點擊程序
本地廣播.png
- 本地廣播是無法通過靜態注冊的方式來接收的,這是因為靜態的注冊主要就是為了讓程序在沒有啟動的情況下也能接收到廣播,而發送本地廣播是在程序啟動的情況下
- 本地廣播的優勢
- 可以明確的知道正在發送的廣播是什么,不用擔心機密數據的泄漏
- 其他程序的廣播也無法將廣播發送到我們的程序內部,不用擔心安全漏洞問題
- 發送本地廣播比發系統廣播效率高