Android學習筆記——Bluetooth的使用


藍牙應該是現在每一部智能手機的標配了。想當年在山寨機橫行的年代里,藍牙都可以做為一個賣點~~~

 

廢話不多說了,進入正題:

 

使用藍牙功能是需要權限的,關於藍牙的權限也就兩個:

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

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

第一個是最基本的,打開藍牙,請求連接,接受連接都需要這個。

每二個從字面上看都覺得高級一點,它主要用於像建立搜索、對藍牙進行設置這些操作。

 

添加好權限之后就可以開始使用了

Android系統為我們提供了一個功能極其強大的類用於進行藍牙操作,這個類就是BluetoothAdapter。通過這個類的方法可以滿足我們的大多數操作了。

要獲得這個類的對象我們可以直接調用它的一個靜態方法getDefaultAdapter()。順便看看它的源碼是怎樣的吧:

 

public static synchronized BluetoothAdapter getDefaultAdapter() {
    if (sAdapter == null) {
        IBinder b = ServiceManager.getService(BLUETOOTH_MANAGER_SERVICE);
        if (b != null) {
            IBluetoothManager managerService = IBluetoothManager.Stub.asInterface(b);
            sAdapter = new BluetoothAdapter(managerService);
        } else {
            Log.e(TAG, "Bluetooth binder is null");
        }
    }
    return sAdapter;
}

 

典型的單例模式:

 

打開藍牙

首先要先確實您的設備是否有藍牙,這個驗證還是很有必要的,因為我們要考慮到我們的應用不一定就是給手機用的,也可能是平板之類的。

 

private boolean isBluetoothAvaliable() {
    return BluetoothAdapter.getDefaultAdapter() != null;
}

 

我們一般打開藍牙會使用到系統提供的一個Activity。這個Activity的action為:BluetoothAdapter.ACTION_REQUEST_ENABLE。

然后我們要使用startActivityForResult()這個方法來啟動它。

這個Activity是有返回值的,如果用戶選擇的是打開,我們應該可以收到一個RESULT_OK

如果用戶選擇的是取消,我們應該可以收到一個RESULT_CANCELED。

比如像下面的這一段代碼:

 

public void openBluetooth() {
    Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBT, 1);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 1) {
        if (resultCode == RESULT_OK) {
            System.out.println("藍牙已打開");
        } else if (resultCode == RESULT_CANCELED) {
            System.out.println("取消打開");
        }
    }
}

 

監聽藍牙狀態的變化

當藍牙的狀態發生改變時,系統是會發出一個為BluetoothAdapter.ACTION_STATE_CHANGED的廣播。

該廣播攜帶兩個參數,一個是BluetoothAdapter.EXTRA_PREVIOUS_STATE,表示之前的藍牙狀態。

另一個是BluetoothAdapter.EXTRA_STATE,表示當前的藍牙狀態。而它們的值為以下四個:

BluetoothAdapter.STATE_TURNING_ON;

BluetoothAdapter.STATE_ON;

BluetoothAdapter.STATE_TURNING_OFF;

BluetoothAdapter.STATE_OFF;

分別代表,打開中,已打開,關閉中,已關閉。

 

private class BluetoothStateListener extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
        String msg = null;
        switch (state) {
        case BluetoothAdapter.STATE_TURNING_ON:
            msg = "turning on";
            break;
        case BluetoothAdapter.STATE_ON:
            msg = "on";
            break;
        case BluetoothAdapter.STATE_TURNING_OFF:
            msg = "turning off";
            break;
        case BluetoothAdapter.STATE_OFF:
            msg = "off";
            break;
        }
        System.out.println(msg);
    }
}

protected void onResume() {
    super.onResume();
    // 藍牙開閉狀態接收器
    listener = new BluetoothStateListener();
    IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(listener, filter);
}

 

當然在程序中的某刻,我們可以調用BludetoothAdapter的getState()這個方法,該方法的返回值為上面的四個中的一個,不再贅述。

 

查找藍牙設備

這個關於查找設備要分為兩個部分,一個是已綁定的設備,另一個是搜索新的設備。

對於已綁定的設備,我們可以直接通過BluetoothAdapter的getBondedDevices()這個方法來獲得。

該方法返回的是一個Set<BluetoothDevice>我們可以直接從人獲得我們需要的信息:

 

public void getBoundedDevices() {
    System.out.println("getPairedDevices");
    // 這個要在打開藍牙的情況下才可以,不然為空集
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    Set<BluetoothDevice> devices = adapter.getBondedDevices();
    for (BluetoothDevice device : devices) {
        System.out.println(device.getName() + " : " + device.getAddress());
    }
}

 

另外就是查找新的設備了,這時我們要調用startDiscovery()方法,這個方法並不會在我們的程序中執行,它是系統進程來的,然后通過異步發送廣播的方式來通知。

所以我們還要注冊一個廣播接收器來接收系統的廣播,這個廣播的action為BluetoothDevice.ACTION_FOUND。

它攜帶兩個值,一個是BluetoothDevice.EXTRA_DEVICE另一個是BluetoothDevice.EXTRA_CLASS分別表示哪一個具體的設備和這個設備的類型。

 

private class BluetoothDeviceScanListener extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        // 這里可以把我們的將我們的設備添加到一個列表中
        System.out.println(device.getName() + " : " + device.getAddress());
    }
}

 

在官方的文檔中一直強調,查找設備這個動作是會消耗大量的系統資源的,而且它會大大減少藍牙的可用帶寬,所以當我們找到了目標設備后,應該由我們主動調用cancelDiscovery()這個方法來取消搜索,而不應該期待默認的搜索時間到了,由系統來取消搜索。

 

設置可被搜索

藍牙的默認設置是不允許被搜索到的,這一點有時候挺蛋疼的。

所以我們自己通過編程來實現打開可被搜索的選擇,使用是很裝簡單的,也是調用系統的一個Activity。這個activity的action是BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE它同樣是有返回值的。並且,這個我們可以通過BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION這個參數來指定可被搜索的時間。

 

public void discoverable() {
    BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    // 這個可以用來設置時間
    intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);
    startActivityForResult(intent, 2);
}

 

這個Activity還同時具有打開藍牙的功能,所以我們並不需要先打開藍牙,再設置可被發現的時間,一次就可以搞定。

最后,這個狀態的改變系統也是會發出廣播的,我們可以注冊一個廣播接收器來捕捉這個狀態的變化,或是通過調用BluetoothAdapter的getScanMod()這個方法來確定,和之前是一樣的。不再細說了。

(未定待續)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM