星期一, 10月 10, 2011

Bluetooth (四)

Android應用程式學習筆記

Finding Devices

使用BluetoothAdapter,你可以找到遠端的藍芽裝置,不管是通過裝置探詢或是查詢配對裝置。

裝置探詢(device discovery)是掃描程序,搜尋本地可用的藍芽裝置,然後,一一要求一些資訊。當在本地區的藍芽裝置目前能夠是被發現的,它才會回應探詢的請求。如果裝置是可發現的,它將分享一些資訊回應探尋的請求,比如名稱、類別、位址。使用這些資訊,執行探詢的裝置可以選擇初始化連線的裝置。

一旦與遠端裝置第一次連線,配對要求自動顯示給用戶,當配對成功,裝置的基本資料就會被儲存並且可經由Bluetooth APIs讀取。使用已知的遠端裝置的MAC位址,就能在任何時間執行連線無需在經過探詢。

記住能被配對(paired)與能被連線(connected)是不相同的,能被配對是指兩個裝置知道彼此是存在的,彼此已經分享了link-key用來認證,且彼此之間是有能力建立加密連線。能被連線是指裝置目前分享RFCOMM頻道且可以彼此傳遞數據。目前Android Bluetooth APIs的要求裝置配對之前必須先建立RFCOMM連線。

以下我們就來學習如何找到裝置進行配對或是使用裝置探詢找到新裝置。


Querying paired devices


在執行裝置探詢之前,查詢已配對裝置了解想連線的裝置是否已是我們已配對裝置是值得的,呼叫getBondedDevice()方法,此方法回傳一系列BluetoothDevices顯示配對裝置。例如,你可以查詢所有的已配對裝置,然後顯示出它們的名稱給用戶,使用ArrayAdapter:


Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
    // Loop through paired devices
    for (BluetoothDevice device : pairedDevices) {
        // Add the name and address to an array adapter to show in a ListView
        mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    }
}

所有來自BluetoothDevice物件以啟動連線的訊息就是MAC位址。在此例中,我們將資訊存在ArrayAdapter中顯示給用戶。MAC位址會在之後要連線時取出(see in Connecting Device)。


Discovering devices

啟動裝置探詢,呼叫startDiscovery(),該程序是異步並且會立刻回傳一個布林值表示探詢工作是否已經成功開始。探詢程序通常涉及調查掃描大約12秒鐘,通過已找到的裝置的每頁掃描取得藍芽名稱。

你的應用程式必須註冊廣播接收器接收ACTION_DOUND意圖,為了接收每個被探詢的裝置資訊。對每個裝置,系統會廣播ACTION_FOUND意圖,意圖夾帶EXTRA_DEVICE和EXTRA_CLASS額外檔案,分別包括一個BluetoothDevice和一個BluetoothClass。舉例,當裝置被探詢時,你可以如何註冊處理廣播。


// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // When discovery finds a device
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Get the BluetoothDevice object from the Intent
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a ListView
            mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
        }
    }
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy



Enabling discoverablilty

如果你想要使本地裝置能被其他裝置找到,呼叫startActivityForResult(intent , int)方法,ACTION_REQUEST_DISCOVERABLE動作意圖,這將發出一個請求,以便通過系統設定啟用可發現模式,預設情況下,裝置變成可發現的長達120秒,你可以藉著EXTRA_DISCOVERABLE_DURATION意圖定義不同的持續時間,最大可以設定為3600秒,數值0表示裝置永遠是可發現的,任何低於0及高於3600的值都會被設成120秒。以下舉例設定為300秒。


Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);

對話框會顯示,請求用戶權限使裝置為可發現的,如下圖,如果用戶回應"Yes",裝置將變成可發現的時間長達指定的時間,你的Activity接著呼叫onActivityResult()回調方法,如果用戶回應"No"或發生錯誤,結果代碼將是Activity.RESULT_CANCELED。


裝置在配發的時間內靜靜地保持可發現的模式,如果你想要當可發現模式改變時的告知,你可以為ACTION_SCAN_MODE_CHANGE意圖註冊廣播接收器,意圖會包括兩個額外的字段,EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE,它們分別為新的和舊的掃瞄模式,每個字段的值有可能為SCAN_MODE_CONNECTABLE_DISCOVERABLE、SCAN_MODE_CONNECTABLE、SCAN_MODE_NONE,它們分別表示裝置在可發現的模式,不在可發現模式但是可以接受連線,或是不在可發現模式且無法接受連線。

如果你將啟動與遠端裝置的連線,你無需啟用裝置為可發現。啟用可發現模式只在當你想要你的應用程式是主機伺服器接收傳入的連線才需要,因為遠端裝置必須在連線之前能夠發現裝置。

沒有留言:

張貼留言