藍牙應該是如今每一部智能手機的標配了。想當年在山寨機橫行的年代裏,藍牙均可以作爲一個賣點~~~android
廢話很少說了,進入正題:編程
使用藍牙功能是須要權限的,關於藍牙的權限也就兩個:異步
<uses-permission android:name=」android.permission.BLUETOOTH」 /> <uses-permission android:name=」android.permission.BLUETOOTH_ADMIN」 />
第一個是最基本的,打開藍牙,請求鏈接,接受鏈接都須要這個。ide
每二個從字面上看都以爲高級一點,它主要用於像創建搜索、對藍牙進行設置這些操做。spa
添加好權限以後就能夠開始使用了code
Android系統爲咱們提供了一個功能極其強大的類用於進行藍牙操做,這個類就是BluetoothAdapter。經過這個類的方法能夠知足咱們的大多數操做了。對象
要得到這個類的對象咱們能夠直接調用它的一個靜態方法getDefaultAdapter()。順便看看它的源碼是怎樣的吧:blog
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()這個方法來肯定,和以前是同樣的。再也不細說了。
(未定待續)