Android入門(7)| 四大組件之廣播接收器

廣播接收器(Broadcast Receiver),是我們接觸到的第二個組件。Broadcast(廣播)是一種廣泛應(yīng)用在應(yīng)用程序之間傳輸信息的機制,而BroadcastReceiver(廣播接收器)則是用于接收來自系統(tǒng)和應(yīng)用的廣播對并對其進行響應(yīng)的組件。Android提供了一套完整的API,允許應(yīng)用程序自由地發(fā)送和接收廣播。其中發(fā)送廣播的方法就是使用Intent,而接收廣播就需要使用廣播接收器了。


本節(jié)目錄

廣播的類型

在介紹廣播接收器之前,我們先來具體介紹一下廣播。Android里面廣播就類似于現(xiàn)實生活里面的廣播。當我們需要傳達一些信息給很多人聽的時候,我們就會使用廣播,而在程序里面也是同樣的道理,除此以外,它不僅能夠給自己的程序發(fā)送廣播,還能夠給其他的程序發(fā)送廣播。

Android中的廣播主要可以分為兩種類型:標準廣播和有序廣播。

  • 標準廣播
    標準廣播是一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,幾乎所有的廣播接收器都會接受到這個廣播,因此標準廣播的效率是很高的。
標準廣播
  • 有序廣播
    有序廣播是一種同步執(zhí)行的廣播,在廣播發(fā)出之后,同一時刻只會有一個廣播接收器能夠收到這條廣播,當這個廣播接收器中的邏輯執(zhí)行完畢之后,這條廣播才能夠被繼續(xù)傳遞。所以此時的廣播接收器是有先后順序的。
有序廣播

接收廣播的方法

廣播接收器就是用來接收廣播,它可以對它需要的廣播進行注冊,這樣當有相應(yīng)的廣播發(fā)出時,它就能夠接收到該廣播。注冊廣播的方式一般有2種:動態(tài)注冊和靜態(tài)注冊。下面分別來看一看吧。

1.動態(tài)注冊

動態(tài)注冊簡單來說其實就是在代碼中進行使用registerReceiver()方法來為廣播接收器進行注冊。先創(chuàng)建一個空項目,然后修改主代碼:

package com.example.yzbkaka.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    IntentFilter intentFilter;  //放置廣播的“容器”
    NetworkChangeReceiver networkChangeReceiver;  //廣播接收器
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intentFilter = new IntentFilter();
        networkChangeReceiver = new NetworkChangeReceiver();
        intentFilter.addAction("android.net.com.CONNECTIVITY.CHANGE");
        registerReceiver(networkChangeReceiver,intentFilter);  //注冊廣播
    }
    
    @Override
    protected void onDestroy(){
        super.onDestroy();
        unregisterReceiver(networkChangeReceiver);
    }
    
    class NetworkChangeReceiver extends BroadcastReceiver{  //廣播接收器繼承自BroadcastReceiver
        @Override
        public void onReceive(Context context, Intent intent) {  //添加邏輯
            Toast.makeText(MainActivity.this, "get a broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}

這里我們首先是要創(chuàng)建一個內(nèi)部類NetworkChangeReceiver并讓它繼承BroadcastReceiver 然后我們就在它的onReceive()的方法中來添加邏輯。接著看到上面的主代碼,我們先是新建一個IntentFilter的實例,這個實例是用來存放廣播的,然后我們對它使用addAction()的方法來添加廣播,這里添加的廣播是系統(tǒng)自帶的廣播,主要是用來判斷網(wǎng)絡(luò)變化的。然后我們就使用registerReceiver()的方法來對廣播進行注冊,這里需要的兩個參數(shù)就是我們的廣播接收器和intentFilter了。

需要注意的是使用動態(tài)的方法注冊的廣播必須要手動取消注冊才行,我們在onDestroy()的方法中使用unregisterReceiver()來進行取消注冊。

2.靜態(tài)注冊

靜態(tài)注冊的主要思路就是在AndroidManifest.xml中來進行注冊。我們先創(chuàng)造一個新的類,修改代碼:

package com.example.yzbkaka.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;


public class BootCompleteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "this is bootcompletereceiver", Toast.LENGTH_SHORT).show();
    }
}

接著我們到AndroidManifest.xml來為接收器進行注冊:

   <receiver
          android:name=".BootCompleteReceiver"
          android:enable="true"
          android:exported="true">
        </receiver>

我們在<application>的標簽類添加<receiver>來進行注冊,這里的android:enable屬性是指是否啟用這個接收器,而android:exported屬性是指是否允許這個廣播接收器接收本程序以外的廣播。

接著我們就需要來為廣播接收器添加廣播了,還是在AndroidManifest.xml中修改:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yzbkaka.myapplication">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <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">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".BootCompleteReceiver"
            android:enable="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

因為在Android系統(tǒng)中使用某些比較隱秘的廣播時需要我們來聲明權(quán)限,所以我們先在開頭中聲明一下權(quán)限,使用的是<uses-permission>的標簽來進行添加。之后我們在<receiver>里面使用<intent-filter>標簽來添加廣播,這一條廣播是當手機開機時系統(tǒng)會自動發(fā)布的廣播,不需要我們來手動發(fā)送。到這里我們就可以使用我們的廣播接收器了。

靜態(tài)注冊的方法看起來是要比動態(tài)注冊的方法操作要復(fù)雜一些,但是它卻能夠在程序啟動之前就能夠接收到廣播,因為動態(tài)注冊的方法實在onCreate()中進行的,所以動態(tài)注冊的廣播接收器必須當活動被創(chuàng)建起來之后才能夠接收到廣播。

發(fā)送廣播

前面我們使用的例子中接收到的廣播都是系統(tǒng)內(nèi)置的廣播,也就是說這些廣播能都在某些情況下由系統(tǒng)自動的發(fā)送。但是我們也可以自定義廣播來進行發(fā)送。

1.發(fā)送標準廣播

前面說過,標準廣播就是可以被所有的廣播接收器接收。下面我們就來發(fā)送標準廣播吧。

還是先創(chuàng)建一個空項目,然后新建一個廣播接收器:

package com.example.yzbkaka.sendbroadcastpractice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;


public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "get a broadcast", Toast.LENGTH_SHORT).show();
    }
}

還是比較容易理解的代碼,這里就不多說了。接著是注冊廣播接收器:

    <receiver 
            android:name=".MyBroadcastReceiver"
            android:enabled="true"
            android:exported="true" >
            <intent-filter>
                <action android:name="com.example.broadcast.MY_BROADCAST"/>
            </intent-filter>
      </receiver>

在注冊的時候我們是自定義了一條叫做com.example.broadcast.MY_BROADCAST的廣播,到時候我們的廣播接收器就會接收這樣一條廣播。然后我們?yōu)槲覀兊闹骰顒犹砑右粋€按鈕,最后修改主代碼:

package com.example.yzbkaka.sendbroadcastpractice;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button send = (Button)findViewById(R.id.button1);
        final Intent intent = new Intent("com.example.broadcast.MY_BROADCAST");
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendBroadcast(intent);  //發(fā)送廣播
            }
        });
    }
}

我們這里先是將廣播存放在intent當中,然后就是將intent使用sendBroadcast()方法來進行發(fā)送。

運行程序,然我們點擊按鈕的時候就會發(fā)送廣播,而在程序的下方就會出現(xiàn)一跳短消息提示語句,說明我們的接收器成功接收到了廣播。

2.發(fā)送有序廣播

知道了如何發(fā)送標準廣播,下面就來看一看如何發(fā)送有序廣播吧。

我們直接使用上面的項目,前面的代碼都不變,我們直接修改主代碼:

package com.example.yzbkaka.sendbroadcastpractice;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button send = (Button)findViewById(R.id.button1);
        final Intent intent = new Intent("com.example.broadcast.MY_BROADCAST");
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendOrderedBroadcast(intent,null);  //有序發(fā)送廣播的方法
            }
        });
    }
}

這里我們是直接修改發(fā)送廣播的方法,改成使用sendOrderedBroadcast()方法來進行發(fā)送,這個方法需要2個參數(shù):第一個就是存儲了廣播的intent;第二個就是直接使用默認的null即可。

有序廣播的特點是必須要按照廣播接收器的優(yōu)先級來被捕獲,即優(yōu)先級越高的廣播接收器,就能夠越在前面接收廣播。所以我們接下來就來修改廣播接收器的優(yōu)先級,打開AndroidManifest.xml,修改代碼:

 <intent-filter android:priority="100">
                <action android:name="com.example.broadcast.MY_BROADCAST"/>
            </intent-filter>

使用priority的屬性來設(shè)置廣播接收器的優(yōu)先級,這里我們設(shè)置為100。之后如果有多個廣播接收器,我們就可以手動的設(shè)置它們的優(yōu)先級來為它們進行排序。

當然,優(yōu)先級高的廣播接收器也可以執(zhí)行不讓廣播繼續(xù)傳送的操作,即廣播傳到它這里以后就不會再傳書下去了,我們直接在onCreate()里面添加abortBroadcase()方法就能夠阻斷廣播的傳輸了。

使用本地廣播

我們之前發(fā)送的廣播(包括系統(tǒng)廣播和自定義廣播)都是在系統(tǒng)內(nèi)全局發(fā)送的,即所有的程序都能夠接收這些廣播。但是有些情況下我們不想讓其他的程序收到我們的廣播時,我們就可以選擇發(fā)送本地廣播。

新建項目,添加一個按鈕,然后直接修改主代碼:

package com.example.yzbkaka.localbroadcasttest;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    IntentFilter intentFilter;
    LocalReceiver localReceiver;
    LocalBroadcastManager localBroadcastManager;  //創(chuàng)建管理器

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button send = (Button)findViewById(R.id.button1);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent("com.example.broadcast.LOCAL_BROADCAST");
                localBroadcastManager.sendBroadcast(intent);  //發(fā)送廣播
            }
        });
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.example.broadcast.LOCAL_BROADCAST");
        localReceiver = new LocalReceiver();
        localBroadcastManager.registerReceiver(localReceiver,intentFilter);  //注冊廣播接收器
        
    }

    class LocalReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "get local broadcast", Toast.LENGTH_SHORT).show();
        }
    }
}

這里我們是采用動態(tài)注冊的方法來實現(xiàn)的,因為我們想要的是發(fā)送不讓其他程序接收到的廣播,如果采用靜態(tài)的注冊方法,則在我們活動創(chuàng)建之前就有了廣播,這和我們想要的是不同的。接著我們就是創(chuàng)建一個LocalBroadcastManager的實例,我們發(fā)送本地廣播主要就是依靠它來完成的。然后就是調(diào)用LocalBroadcastManager實例的方法來進行發(fā)送和注冊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容