Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> android開發之路02(淺談BroadcastReceiver),broadcastreceiver

android開發之路02(淺談BroadcastReceiver),broadcastreceiver

編輯:關於android開發

android開發之路02(淺談BroadcastReceiver),broadcastreceiver


一.BroadcastReceiver (廣播接收者)的作用是用來接收來自系統和應用中的廣播。應用如下:

1.開機完成後系統會產生一條廣播----->接收到這條廣播就能實現開機啟動服務的功能;

2.網絡狀態改變時系統會產生一條廣播,接收到這條廣播就能及時地做出提示和保存數據等操作;

當電池電量改變時,系統會產生一條廣播,接收到這條廣播就能在電量低時告知用戶及時保存進度;

Android中的廣播機制設計的非常出色,大大減少了開發的工作量和開發周期。

二.靜態注冊廣播接收者和動態注冊廣播接收者

①創建BroadcastReceiver對象,讓其繼承android.content.BroadcastReceiver這個類,並實現其onReceive方法。

例如:public class MyReceiver extends BroadcastReceiver{

 

@Override

public void onReceive(Context context, Intent intent) {

//獲取隨廣播而來的Intent中的數據

String msg=intent.getStringExtra("msg");

//在界面輸出提示信息

Toast.makeText(context, msg, Toast.LENGTH_LONG).show();

}

 

}

在創建完我們的BroadcastReceiver之後,還不能夠使它進入工作狀態,我們需要為它注冊一個指定的廣播地址。

②為BroadcastReceiver注冊廣播地址之靜態注冊:靜態注冊是在AndroidManifest.xml文件中配置的,如:

<receiver android:name=".MyReceiver">

            <intent-filter>

                <action android:name="android.intent.action.MY_BROADCAST"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

 </receiver>

配置了以上信息之後,只要是android.intent.action.MY_BROADCAST這個地址的廣播,MyReceiver都能夠接收的到。注意,這種方式的注冊是常駐型的,也就是說當應用關閉後,如果有廣播信息傳來,MyReceiver也會被系統調用而自動運行。

③為BroadcastReceiver注冊廣播地址之動態注冊: 動態注冊需要在代碼中動態的指定廣播地址並注冊,通常我們是在Activity或Service注冊一個廣播,例如:

public class MainActivity extends Activity {

private MyReceiver myReceiver;

IntentFilter intentFilter;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        myReceiver=new MyReceiver();

        intentFilter=new IntentFilter();

        intentFilter.addAction("android.intent.action.MY_BROADCAST");

        //registerReceiver是android.content.ContextWrapper類中的方法,

        //Activity和Service都繼承了ContextWrapper,所以可以直接調用

        registerReceiver(myReceiver, intentFilter);

    }

}

在實際應用中,我們在Activity或Service中注冊了一個BroadcastReceiver,當這個Activity或Service被銷毀時如果沒有解除注冊,系統會報一個異常,提示我們是否忘記解除注冊了。所以,記得在加上:

 @Override

    protected void onDestroy() {

     super.onDestroy();

     unregisterReceiver(myReceiver);

    }

 

就可以解決問題了。注意,這種注冊方式與靜態注冊相反,不是常駐型的,也就是說廣播會跟隨程序的生命周期。

④發送廣播,代碼如下:

public void send(View v){

     Intent intent=new Intent();

     intent.putExtra("msg", "你好,接收者");

     //sendBroadcast也是android.content.ContextWrapper類中的方法,

     //它可以將一個指定地址和參數信息的Intent對象以廣播的形式發送出去

     sendBroadcast(intent);

}

⑤在布局文件中聲明一個button控件:

<Button 

    android:id="@+id/button1"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:text="點我發送廣播"/>

MainActivity中獲取button控件的對象並注冊監聽器,代碼如下:

 private Button button1;

 protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        button1=(Button) findViewById(R.id.button1);

        button1.setOnClickListener(new OnClickListener() {

 

@Override

public void onClick(View v) {

send(v);

}

});

    }

三.普通廣播(Normal Broadcast)和有序廣播(Ordered Broadcast)

普通廣播對於多個接收者來說是完全異步的,通常每個接收者都無需等待即可以接收到廣播,接收者相互之間不會有影響。對於這種廣播,接收者無法終止廣播,即無法阻止其他接收者的接收動作。我們只需要通過創建幾個不同的廣播接收者並聲明即可,這裡不做演示。

有序廣播比較特殊,它每次只發送到優先級較高的接收者那裡,然後由優先級高的接受者再傳播到優先級低的接收者那裡,優先級高的接收者有能力終止這個廣播。

實例如下:

FirstReceiver.java

public class FirstReceiver extends BroadcastReceiver{

@Override

public void onReceive(Context context, Intent intent) {

String msg=intent.getStringExtra("msg");

Toast.makeText(context, msg, Toast.LENGTH_LONG).show();

Bundle bundle=new Bundle();

/**

 * 使用setResultExtras方法將一個Bundle對象設置為結果集對象,傳遞到下一個接收者那裡,

 * 這樣一來,優先級低的接收者可以用getResultExtras獲取到最新的經過處理的信息集合

 */

bundle.putString("msg", "FirstReceiver:"+msg);

setResultExtras(bundle);

}

 

}

SecondReceiver

public class SecondReceiver extends BroadcastReceiver{

 

@Override

public void onReceive(Context context, Intent intent) {

String msg=getResultExtras(true).getString("msg");

Toast.makeText(context, msg, Toast.LENGTH_LONG).show();

Bundle bundle=new Bundle();

bundle.putString("msg", msg);

setResultExtras(bundle);

}

 

}

ThirdReceiver.java

public class ThirdReceiver extends BroadcastReceiver{

 

@Override

public void onReceive(Context context, Intent intent) {

String msg=getResultExtras(true).getString("msg");

Toast.makeText(context, msg, Toast.LENGTH_LONG).show();

}

 

}

現在,我們需要為三個接收者注冊廣播地址,我們修改一下AndroidMainfest.xml文件:

<receiver android:name=".FirstReceiver">

            <intent-filter android:priority="999">

                <action android:name="android.intent.action.MY_BROADCAST"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

        </receiver>

        <receiver android:name=".SecondReceiver">

            <intent-filter android:priority="888">

                <action android:name="android.intent.action.MY_BROADCAST"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

        </receiver>

        <receiver android:name=".ThirdReceiver">

            <intent-filter android:priority="777">

                <action android:name="android.intent.action.MY_BROADCAST"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

        </receiver>

我們看到,現在這三個接收者的<intent-filter>多了一個android:priority屬性,並且依次減小。這個屬性的范圍在-1000到1000,數值越大,優先級越高。

現在,我們需要修改一下發送廣播的代碼,如下:

 public void send(View v){

     Intent intent=new Intent();

     intent.putExtra("msg", "你好,接收者");

     //sendBroadcast也是android.content.ContextWrapper類中的方法,

     //它可以將一個指定地址和參數信息的Intent對象以廣播的形式發送出去

     //sendBroadcast(intent);

     sendOrderedBroadcast(intent, "rookie.permission.MY_BROADCAST_PERMISSION");

    } 

注意:使用sendOrderedBroadcast方法發送有序廣播時,需要一個權限參數,如果為null則表示不要求接收者聲明指定的權限,如果不為null,則表示接收者若要接收此廣播,需聲明指定權限。這樣做是從安全角度考慮的,例如系統的短信就是有序廣播的形式,一個應用可能是具有攔截垃圾短信的功能,當短信到來時它可以先接受到短信廣播,必要時終止廣播傳遞,這樣的軟件就必須聲明接收短信的權限。

所以我們在AndroidMainfest.xml中定義一個權限:

<permission android:protectionLevel="normal"     android:name="rookie.permission.MY_BROADCAST_PERMISSION"/>

然後聲明使用了此權限:

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

在有序廣播中,我們可以通過abortBroadcast()方法終止廣播的傳遞;

四.廣播接收者的應用實例

1.開機啟動服務

我們經常會有這樣的應用場合,比如消息推送服務,需要實現開機啟動的功能。要實現這個功能,我們就可以訂閱系統“啟動完成”這條廣播,接收到這條廣播後我們就可以啟動自己的服務了。

代碼如下:

public class MyReceiver extends BroadcastReceiver{

 

@Override

public void onReceive(Context context, Intent intent) {

Intent service=new Intent(context, MsgPushService.class);

context.startService(service);

}

 

}

 

public class MsgPushService extends Service{

 

@Override

public void onCreate() {

super.onCreate();

}

@Override

public int onStartCommand(Intent intent, int flags, int startId) {

return super.onStartCommand(intent, flags, startId);

 

}

@Override

public IBinder onBind(Intent intent) {

return null;

}

 

}

然後我們需要在AndroidManifest.xml中配置相關信息:

<!-- 開機的廣播接收者 -->

        <receiver android:name=".MyReceiver">

            <intent-filter>

                <!--注冊開機廣播地址  -->

                <action android:name="android.intent.action.BOOT_COMPLETED"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

        </receiver>

        <service android:name=".MsgPushService"/>

從安全角度考慮,系統要求必須聲明接收開機啟動廣播的權限,於是我們再聲明使用下面的權限:

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

2.網絡狀態變化

在某些場合,比如用戶浏覽網絡信息時,網絡突然斷開,我們要及時地提醒用戶網絡已斷開。要實現這個功能,我們可以接收網絡狀態改變這樣一條廣播,當由連接狀態變為斷開狀態時,系統就會發送一條廣播,我們接收到之後,再通過網絡的狀態做出相應的操作。下面就來實現一下這個功能:

public class MyReceiver extends BroadcastReceiver{

 

@Override

public void onReceive(Context context, Intent intent) {

if(!isNetworkAvailable(context)){

Toast.makeText(context, "不能鏈接網絡", 0).show();

}

}

 

private boolean isNetworkAvailable(Context context) {

ConnectivityManager cm=(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo [] info=cm.getAllNetworkInfo();

if(info!=null){

for (int i = 0; i < info.length; i++) {

if(info[i].getState()==NetworkInfo.State.CONNECTED){

return true;

}

}

}

return false;

}

 

}

 

再注冊一下這個接收者的信息:

 <receiver android:name=".MyReceiver">

            <intent-filter>

                <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

        </receiver>

因為在isNetworkAvailable方法中我們使用到了網絡狀態相關的API,所以需要聲明相關的權限才行,下面就是對應的權限聲明:

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

3.電量變化

如果我們閱讀軟件,可能是全屏閱讀,這個時候用戶就看不到剩余的電量,我們就可以為他們提供電量的信息。要想做到這一點,我們需要接收一條電量變化的廣播,然後獲取百分比信息,這聽上去挺簡單的,我們就來實現以下:

public class MyReceiver extends BroadcastReceiver{

 

@Override

public void onReceive(Context context, Intent intent) {

//當前電量

int currLevel=intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);

//總電量

int total=intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);

int percent=currLevel*100/total;

}

 

}

然後再注冊一下廣播接地址信息就可以了:

 <receiver android:name=".MyReceiver">

            <intent-filter>

                <action android:name="android.intent.action.BATTERY_CHANGED"/>

                <category android:name="android.intent.category.DEFAULT"/>

            </intent-filter>

        </receiver>

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved