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

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



2016年7月25日 星期一

Android原件:巢狀類別Dialog 和 Button的互動

Android原件:巢狀類別Dialog Button的互動


實作影片:




前言
請先下載我的github來參考。會比較清楚,一言之就是一個螢幕和Button之間的互動。
要怎麼作應用還是要靠您自己了。





實作

在使用彈跳對話視窗時,必須 IMPLEMENTS 這個內部方法implements DialogInterface.OnClickListener


public class MainActivity extends AppCompatActivity implements DialogInterface.OnClickListener {

   //螢幕
    private TextView m_tv_message;
    private int mChoice;

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

 init();
    }


   


  //螢幕
    private void init() {
        m_tv_message = (TextView) findViewById(R.id.message);
    }


    //Button1
    public void clickAlertDialog(View view) {
        new AlertDialog.Builder(this)
                .setMessage("你好帥喔")
                .setPositiveButton("I Know!", this)
                .setNegativeButton("hewe", this)
                .show();
    }

    //Button1 implments DialogInterface.OnClickListener 必須要override的方法
    @Override
    public void onClick(DialogInterface dialog, int which) {
        m_tv_message.setText("我知道");
    }


    //Button2 clickAlertDialogYesNo
    //因為MainActivity介面的DialogInterface.OnClickListenerButton1已經使用過了
    //所以在Button2我們在下面自己寫了一個方法
    //並寫入clcikAlertDialogYesNo
    public void clickAlertDialogYesNo(View view) {
//呼叫方法
        AlertDialogYesNoListener listener = new AlertDialogYesNoListener();
        new AlertDialog.Builder(this)
                .setMessage("你好帥喔")
                .setPositiveButton("謝謝", listener)
                .setNegativeButton("sfdsfa", listener)
                .show();
    }
    //Button2
    private class AlertDialogYesNoListener implements DialogInterface.OnClickListener {

        @Override
        public void onClick(DialogInterface dialog, int which) {
            switch (which) {
                case DialogInterface.BUTTON_POSITIVE:
                    m_tv_message.setText("Thnks");
                    break;
                case DialogInterface.BUTTON_NEGATIVE:
                    m_tv_message.setText("狗腿");
                    break;
            }

        }
    }



    //Button3使用內部類別,直接把DialogInterface.OnClickListener這方法寫在內部
    //new DialogInterface.OnClickListener就是我們在Button2的時候寫在外面的方法
    public void Button3(View view) {
        new AlertDialog.Builder(this)
                .setMessage("選擇一二三")
                .setPositiveButton("hloOne", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                m_tv_message.setText("one");
                            }
                        }
                )
                .setNegativeButton("22222", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        m_tv_message.setText("two");
                    }
                })
                .setNeutralButton("threee", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        m_tv_message.setText("three");
                    }
                })
                .show();

    }



    //按下button4
    public void Button4(View view) {
        //建造陣列=strings.xml內的responsestring-array內的東西丟入
        final String[] response = getResources().getStringArray(R.array.response);
        new AlertDialog.Builder(this, android.R.style.Theme_Holo_Light_Dialog_NoActionBar)
                //這邊必須用setTitle,不能像上面三個Button一樣使用setMessage
                .setTitle("你好帥喔")
                //setItems的用法
                .setItems(response, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        m_tv_message.setText(response[which]);
                    }
                })
                .show();
   


    //Button5
    public void Button5(View view){
        final String[] response=getResources().getStringArray(R.array.response);
        final boolean[] selected=new boolean[response.length];//記錄每個選項的勾選狀態
        new AlertDialog.Builder(this)
                .setTitle("你好")
                 //MultiChoice是多選的用法
                .setMultiChoiceItems(response,selected,new DialogInterface.OnMultiChoiceClickListener(){

                    @Override
                    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
selected[which]=isChecked;
                    }
                })
                .setPositiveButton("OK",new DialogInterface.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        StringBuilder result=new StringBuilder();
                        for(int i=0;i<selected.length;i++){

                            if(selected[i]){
                                result.append(response[i]).append("\n");

                            }

                        }
                        m_tv_message.setText(result);
                    }
                })
                .setNegativeButton("CANCEL",new DialogInterface.OnClickListener(){

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        m_tv_message.setText("無言");
                    }
                })
                .show();


    }

       //Button6
    public void Button6(View view){
final String[] response=getResources().getStringArray(R.array.response);
        new AlertDialog.Builder(this)
                .setTitle("你好帥")
                //Multi不同,這只能單選
                .setSingleChoiceItems(response,0,new DialogInterface.OnClickListener(){

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                       mChoice=which;
                    }
                })
                .setPositiveButton("OK",new DialogInterface.OnClickListener(){
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        m_tv_message.setText(response[mChoice]);
                    }
                })
                .setNegativeButton("Cancel",new DialogInterface.OnClickListener(){

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
m_tv_message.setText("hellono world" );
                    }
    })
                .show();

    }

}




values>strings.xml下加入字串,這是Button3-6會使用到的字串。
<string-array name="response">
    <item>
我知道</item>
    <item>
少狗腿</item>
    <item>
大家都那麼說</item>

</string-array>


GITHUB:

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

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