1. 程式人生 > >Android 藍芽通訊開發(一) 搜尋藍芽裝置

Android 藍芽通訊開發(一) 搜尋藍芽裝置

藍芽通訊是我們日常生活中比較方便的一種通訊技術,Android從2.0版本的SDK就開始支援藍芽。對開發人員來說,應用程式中藍芽還是一種用來建立點對點連線通訊的簡單而高效的方式。

藍芽通訊功能的實現的基本流程大致分為藍芽裝置搜尋藍芽裝置連線藍芽通訊三個階段,這裡我們就先來討論藍芽裝置搜尋功能的實現。

Android模擬器還不支援藍芽,因此要測試使用藍芽功能,必須使用至少兩臺Android裝置。

(1)加入許可權

要操作藍芽,需要在AndroidManifest.xml中宣告許可權:

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

另外,要改變藍芽的可見性以及啟用/禁用藍芽功能,還要宣告:

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

(2)獲取藍芽介面卡BluetoothAdapter

首先來介紹關於藍芽開發要用到的幾個重要的類:

  • BluetoothAdapter

    藍芽介面卡,整個藍芽通訊過程都要用到這個類,BluetoothAdapter裡的方法很多,常用的有以下幾個:

    disable() 關閉藍芽
    enable() 開啟藍芽
    getAddress() 獲取本地藍芽地址
    getName()

    獲取本地藍芽名稱
    getDefaultAdapter()獲取預設BluetoothAdapter例項,這是靜態方法
    isEnabled() 判斷藍芽是否開啟
    startDiscovery()啟動搜尋藍芽裝置
    cancelDiscovery()取消搜尋藍芽裝置

  • BluetoothDevice

    這是一個描述一個具體藍芽裝置的類。常用方法有:

    createRfcommSocketToServiceRecord(UUIDuuid)根據UUID建立並返回一個BluetoothSocket
    getState() 獲取藍芽狀態
    getAddress() 獲取藍芽裝置地址
    getName()

    獲取藍芽裝置名稱

  • BluetoothServerSocket

    藍芽通訊伺服器端類,藍芽通訊過程類似於Socket,當兩臺藍芽裝置連線配對之後,伺服器端通過accept()方法來建立BluetoothSocket,需要注意的是,accept()方法會阻塞執行緒,應該放在新的執行緒中執行。

  • BluetoothSocket

    這是伺服器和客戶端通訊的通道,常用的方法有:
    close() 關閉
    connect() 連線
    getInptuStream() 獲取輸入流
    getOutputStream() 獲取輸出流
    getRemoteDevice() 獲取遠端裝置,這裡指的是獲取bluetoothSocket指定連線的那個遠端藍芽裝置

實現藍芽裝置搜尋,我們暫時只要用到前面兩個類。

與一般的裝置介面卡相當,我們要獲取BluetoothAdapter時只需使用BluetoothAdapter類提供的getDefaultAdapter()方法。

BluetoothAdapter bAdapter = BluetoothAdapter.getDefaultAdapter();
if(bAdapter == null) {
    Toast.makeText(this, "Bluetooth is not supported.", Toast.LENGTH_LONG).show();
    finish();
    return;
}

除了檢測系統藍芽介面卡狀態外,我們通常還需要獲取藍芽啟用情況,並在當藍芽功能關閉時詢問是否開啟藍芽功能。

if(!bAdapter.isEnabled()) {     //藍芽未開啟
    //彈出對話方塊提示使用者是否開啟藍芽
    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableIntent, REQUEST_ENABLE);

    //bAdapter.enable();    不做提示,強行開啟
    }
    else {
    Toast.makeText(MainActivity.this, "Bluetooth has been turned on.", Toast.LENGTH_SHORT).show();
}

(3)搜尋藍芽裝置

獲取了BluetoothAdapter之後,要發起搜尋藍芽裝置是使用BluetoothAdapter的startDiscovery()方法。這個方法會觸發兩條系統廣播,具體來說是搜尋過程中觸發的,分別是

BluetoothDevice.ACTION_FOUND                //搜尋到裝置廣播
BluetoothAdapter.ACTION_DISCOVERY_FINISHED  //搜尋完成廣播

首先寫好廣播接收器。

List<BluetoothDevice> devices = new ArrayList<>();

private BroadcastReceiver searchReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        //搜尋到裝置
        if(BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);  //獲取藍芽裝置資訊
            devices.add(dev);
        }
        //搜尋完成
        else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            //搜尋結果列表,對話方塊呈現
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
            builder.setTitle("搜尋到的藍芽裝置列表");
            final String[] item = new String[devices.size()];
            int n = item.length;
            //遍歷搜尋結果
            for(int i = 0; i < n; i ++) {
                item[i] = devices.get(i).getName()+"\t:\t"+devices.get(i).getAddress();
            }
            builder.setItems(item, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(MainActivity.this, item[which], Toast.LENGTH_SHORT).show();
                }
            });
            builder.create().show();
        }
    }
};

所以在啟動搜尋藍芽裝置之前,應該先註冊這兩條廣播。

@Override
protected void onCreate(Bundle savedInstanceState) {

    // ...
    registerSearchReceiver();

}

//註冊廣播
private void registerSearchReceiver() {
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);   //搜尋到裝置廣播
    registerReceiver(searchReceiver, filter);
    filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);  //搜尋完成廣播
    registerReceiver(searchReceiver, filter);
}

之後就可以啟動藍芽裝置的搜尋了。最後別忘記解除安裝掉廣播。

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterSearchReceiver();
}

//解除安裝廣播
private void unregisterSearchReceiver() {
    unregisterReceiver(searchReceiver);
}


至此,藍芽通訊的第一步裝置搜尋功能已完成。