show code block

2016年12月18日 星期日

廣播BroadcastReceiver - 靜態廣播static broadcastReceiver

廣播BroadcastReceiver



前言:

前一陣子我也不太清楚為什麼Intent就可以實現的東西,還需要廣播這種東西的存在?

解釋如下。


Android系統中,為什麼需要廣播機制呢?廣播機制,本質上它就是一種組件間的通信方式,如果是兩個組件位於不同的進程當中,那麼可以用Binder機制來實現,如果兩個組件是在同一個進程中,那麼它們之間可以用來通信的方式就更多了,這樣看來,廣播機制似乎是多余的。然而,廣播機制卻是不可替代的,它和Binder機制不一樣的地方在於,廣播的發送者和接收者事先是不需要知道對方的存在的,這樣帶來的好處便是,系統的各個組件可以松耦合地組織在一起,這樣系統就具有高度的可擴展性,容易與其它系統進行集成。



       在軟件工程中,是非常強調模塊之間的高內聚低耦合性的,不然的話,隨著系統越來越龐大,就會面臨著越來越難維護的風險,最後導致整個項目的失敗。Android應用程序的組織方式,可以說是把這種高內聚低耦合性的思想貫徹得非常透徹,在任何一個Activity中,都可以使用一個簡單的Intent,通過startActivity或者startService,就可以把另外一個Activity或者Service啟動起來為它服務,而且它根本上不依賴這個Activity或者Service的實現,只需要知道它的字符串形式的名字即可,而廣播機制更絕,它連接收者的名字都不需要知道。




使用時機:

個人覺得,動態廣播帶資料的部分可以用Intent代替,此篇只講靜態廣播的形式,他能在關掉App的情況下在後台運轉
可以實現鬧鐘效果,或是指定時間做Notification式的推播。
動態廣播就不再本偏多做贅述。




實作:


1、當有人發送廣播給 MyBroadcastReceiver r時,就觸發onReceive


public class MyBroadcastReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {

                 if(intent.getAction().equals("MESSAGE")){
                           Log.d("我是MyBroadcastReceiver1"  , "我聽到了喔");
                          //接收到廣播後要做的事情
              }
           }
}
額外創建一個Java檔案,並且繼承extends BroadcastReceiver。



2、在程式裡面註冊廣播 靜態註冊(靜態註冊的好處是它會長時間在背景做監聽,就算你App關掉了也會一直在背景運行。)

Bundle bundle = new Bundle();
Intent intent = new Intent();
bundle.putString("CONTENT", CONTENT);
bundle.putString("PHONENUMBER", PHONENUMBER);
intent.putExtras(bundle);
intent.setAction("MESSAGE");   //重要連接manifest
sendBroadcast(intent);
這一段我設置在一個Button內,按下後執行上面這些程式碼。




3、在manifest.xml中,創立receiver
(Java(setAction)  manifest.xml(receiver))

<application
...前後省略...
       <receiver android:name=".MyBroadcastReceiver">
            <intent-filter>
                <action android:name="MESSAGE" />
            </intent-filter>
        </receiver>
...前後省略...

</application>


簡單三步驟END
設定在manifest.xml內,放置在application裡面就行了。

ntent.setAction("MESSAGE");  setAction為註冊廣播時的轉接頭。

receiver(Java(setAction)  ⇔ manifest.xml(receiver)


靜態註冊的receiver  <action android:name="MESSAGE" />
注意:name裡面的文字最好是獨一無二的字串,如果有其他App使用的字串和你App設定的一樣,當接收到Message這個字串時,只要對方的靜態註冊的字串也是MESSAGE,就會一起執行動作。 此網誌在這邊用MESSAGE只是做個簡易示範,可以改成com.message.want.to.send.message,減少程式之間呼叫的衝突。





Total程式碼:

MainActivity.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@+id/activity_main"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.example.a015865.broadcastreceiver.MainActivity">
   
   <Button
       android:text="Hello"
       android:onClick="Hello"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />
</RelativeLayout>





MyBroadcastReceiver.java
public class MyBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        if(intent.getAction().equals("MESSAGEE")){
            Log.d("我是MyBroadcastReceiver1"  , "我聽到了喔");
            Toast.makeText(context,"我收到了唷!",Toast.LENGTH_LONG).show();
            //接收到廣播後要做的事情
    }

    }
}


MainActivity.java
public class MainActivity extends AppCompatActivity {

    private PendingIntent pendingIntent;
    private Context context;
    private String CONTENT = "HELLO MY MESSAGE",PHONENUMBER="0978550131";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

    }

    public void Hello(View view) {
        Bundle bundle = new Bundle();
        Intent intent = new Intent();
        bundle.putString("CONTENT", CONTENT);
        bundle.putString("PHONENUMBER", PHONENUMBER);
        intent.putExtras(bundle);
        intent.setAction("MESSAGEE");   //重要連接manifest
        sendBroadcast(intent);
   }
}





如有接收到廣播,情況如下。




Demo下載:
https://drive.google.com/open?id=0Byk75IYx-dKXRVRhcGhJUkJlazQ



文獻:

http://blog.csdn.net/luoshengyang/article/details/6730748

http://www.codedata.com.tw/mobile/android-tutorial-the-5th-class-1-broadcastreceiver-alarmmanager/

http://gityuan.com/2016/06/04/broadcast-receiver/


作品:https://play.google.com/store/apps/details?id=com.army.a015865.armyonline

「國軍定時自動回報」內使用到的功能。



沒有留言:

張貼留言

協程(coroutine) - 協程為什麼要學它?

 Coroutine 協程 再強調一次 協程就是由kotlin官方所提供的線程api //Thread Thread { }.start() //Executor val execu...