2013年5月20日 星期一

關於 Android 的 BroadcaseReceiver (1)

最近想寫個偵測 Wifi 狀態的服務,不過首先必須先讓服務能夠偵測到系統打開、關閉 Wifi
而要偵測到系統的通知,就必須先對系統註冊 BroadcastReceiver 事件。

首先,因為要讓程式有機會觸發註冊 BroadcastReceiver 的時機,因此程式還是必須要有個主介面(MainActivity.java)
主介面對應的 XML(activity_main.xml)什麼也沒有,只放了一個按鈕
按鈕按下後會觸發註冊 BroadcaseReceiver 的動作。
而當系統的 Wifi 狀態改變時,程式預期要偵測到,並且在 Log 中顯示偵測到的是 Wifi 已連接還是已關閉。

程式碼如下:

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent" >

  <TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:text="@string/hello_world"
    tools:context=".MainActivity" />

  <Button
    android:id="@+id/enable"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@+id/textView1"
    android:layout_below="@+id/textView1"
    android:text="Enable" />
</RelativeLayout>

MainActivity.java
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.IntentFilter;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    Button enabledButton = (Button) this.findViewById(R.id.enable);
    
    enabledButton.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    IntentFilter wifiFilter = new IntentFilter();
    wifiFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
    registerReceiver(new WifiConnectedListener(), wifiFilter);
   }
  });
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
  }
}

WifiConnectedListener.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.util.Log;

public class WifiConnectedListener extends BroadcastReceiver {

 @Override
 public void onReceive(Context context, Intent intent) {
  final String action = intent.getAction();
  if (action.equals(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION)) {
   if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
    Log.e("Wifi", "Wifi is connected");
   } else {
    Log.e("Wifi", "Wifi is lost");
   }
  }
 }
}

這個測試目前的結果發現,註冊 BroadcaseReceiver 之後,的確可以偵測到 Wifi 的狀態
但是存在一個問題是,必須手動啟動程式、按下按鈕後,監聽 BroadcastReceiver 的動作才會開始有作用。
如果是把手機重新啟動時,之前註冊過的 BroadcaseReceiver 會失去作用,必須重新按一次按鈕才行。

預計下一篇要來研究要如何讓程式註冊的事件,永遠都能夠偵測到想偵測的事件。目前猜想也許需要看看 [4] 的討論?

參考資料:
1、Android學習筆記 - 背景執行服務(Service)
2、如何使用BroadcastReceiver
3、Android WIFI How To Detect When WIFI Connection has been established
4、How to Start an Application on Startup?

沒有留言: