Android开发笔记(一百六十二)蓝牙设备的连接与配对
生活随笔
收集整理的這篇文章主要介紹了
Android开发笔记(一百六十二)蓝牙设备的连接与配对
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
藍牙是一種短距離無線通信技術,它由愛立信公司于1994年創制,原本想替代連接電信設備的數據線,但是后來發現它也能用于移動設備之間的數據傳輸,所以藍牙技術在手機上獲得了長足發展。
因為手機內部的通訊芯片一般同時集成了2G/3G/4G、WIFI和藍牙,所以藍牙功能已經是智能手機的標配了。若想進行藍牙方面的開發,需要在App工程的AndroidManifest.xml中補充下面的權限配置:
? ? <!-- 藍牙 --><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH" /><!-- 如果Android6.0 藍牙搜索不到設備,需要補充下面兩個權限 --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />與NFC類似,Android也提供了藍牙模塊的管理工具,名叫BluetoothAdapter,雖然通常把BluetoothAdapter翻譯為“藍牙適配器”,其實它干的是管理器的活。下面是BluetoothAdapter類常用的方法說明:
getDefaultAdapter : 獲取默認的藍牙適配器。該方法為靜態方法。
getState : 獲取藍牙的開關狀態。STATE_ON表示已開啟,STATE_TURNING_ON表示正在開啟,STATE_OFF表示已關閉,STATE_TURNING_OFF表示正在關閉。
enable : 啟用藍牙功能。
disable : 禁用藍牙功能。
isEnabled : 判斷藍牙功能是否啟用。返回true表示已啟用,返回false表示未啟用。
getBondedDevices : 獲取已配對的設備集合。
getRemoteDevice : 根據設備地址獲取遠程的設備對象。
startDiscovery : 開始搜索周圍的藍牙設備。
cancelDiscovery : 取消搜索周圍的藍牙設備。
isDiscovering : 判斷是否正在搜索周圍的藍牙設備。
接下來通過一個檢測藍牙設備并配對的例子,介紹如何在App開發中運用藍牙技術。不要小看這個例子,簡簡單單的功能可得分成四個步驟:初始化、啟用藍牙、搜索藍牙設備、與指定設備配對,下面分別進行詳細說明:
一、初始化藍牙適配器
如果僅僅是普通的藍牙連接,則調用getDefaultAdapter獲取藍牙適配器就行了。初始化藍牙適配器的代碼示例如下:
private BluetoothAdapter mBluetooth;private void initBluetooth() {mBluetooth = BluetoothAdapter.getDefaultAdapter();if (mBluetooth == null) {Toast.makeText(this, "本機未找到藍牙功能", Toast.LENGTH_SHORT).show();finish();}}
二、啟用藍牙功能
雖然BluetoothAdapter提供了enable方法用于啟用藍牙功能,但是該方法并不允許外部發現本設備,所以等于沒用。實際開發中要彈窗提示用戶,是否允許其他設備檢測到自身,彈窗代碼如下所示:
? ? // 彈出是否允許掃描藍牙設備的選擇對話框Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);startActivityForResult(intent, mOpenCode);藍牙權限的選擇對話框如下圖所示:
由于選擇彈窗上面可選擇“允許”還是“拒絕”,因此代碼中要重寫onActivityResult函數,在該函數中判斷藍牙權限的選擇結果。下面是判斷權限選擇的例子代碼:
private int mOpenCode = 1;@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent) {super.onActivityResult(requestCode, resultCode, intent);if (requestCode == mOpenCode) {mHandler.postDelayed(mRefresh, 50); // 刷新藍牙設備列表if (resultCode == RESULT_OK) {Toast.makeText(this, "允許本地藍牙被附近的其它藍牙設備發現", Toast.LENGTH_SHORT).show();} else if (resultCode == RESULT_CANCELED) {Toast.makeText(this, "不允許藍牙被附近的其它藍牙設備發現", Toast.LENGTH_SHORT).show();}}}
三、搜索周圍的藍牙設備
藍牙功能打開之后,就能調用startDiscovery方法去搜索周圍的藍牙設備了。不過因為搜索動作是個異步的過程,startDiscovery方法并不直接返回搜索發現的設備結果,而是通過廣播BluetoothDevice.ACTION_FOUND返回新發現的藍牙設備。所以頁面代碼需要注冊一個藍牙搜索結果的廣播接收器,在接收器中解析藍牙設備信息,再把新設備添加到藍牙設備列表。
下面是藍牙搜索接收器的注冊、注銷,以及內部邏輯處理的代碼例子:
? ? private void beginDiscovery() {// 如果當前不是正在搜索,則開始新的搜索任務if (!mBluetooth.isDiscovering()) {mBluetooth.startDiscovery();}}@Overrideprotected void onStart() {super.onStart();//需要過濾多個動作,則調用IntentFilter對象的addAction添加新動作IntentFilter discoveryFilter = new IntentFilter();discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);//注冊搜索結果的接收器registerReceiver(discoveryReceiver, discoveryFilter);}@Overrideprotected void onStop() {super.onStop();// 注銷廣播接收器unregisterReceiver(discoveryReceiver);}// 藍牙設備的搜索結果通過廣播返回private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, "onReceive action=" + action);// 獲得已經搜索到的藍牙設備if (action.equals(BluetoothDevice.ACTION_FOUND)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);refreshDevice(device); // 將發現的藍牙設備加入到設備列表}}};搜索到的藍牙設備可能會有多個,每發現一個新設備都會收到一次發現廣播,這樣設備列表是動態刷新的。搜索完成的藍牙設備列表界面如下圖所示,其中左圖為A手機的設備列表,右圖為B手機的設備列表:
四、與指定的藍牙設備配對
注意到新發現的設備狀態是“未綁定”,這意味著當前手機并不能跟對方設備進行數據交互。只有新設備是“已綁定”狀態,才能與當前手機傳輸數據。藍牙設備的“未綁定”與“已綁定”,區別在于這兩部設備之間是否成功配對了,而配對操作由BluetoothDevice類管理。下面是BluetoothDevice類的常用方法說明:
getName : 獲取設備的名稱。
getAddress : 獲取設備的MAC地址。
getBondState : 獲取設備的綁定狀態。BOND_NONE表示未綁定,BOND_BONDING表示正在綁定,BOND_BONDED表示已綁定。
createBond : 建立該設備的配對信息。該方法為隱藏方法,需要通過反射調用。
removeBond : 移除該設備的配對信息。該方法為隱藏方法,需要通過反射調用。
從上面的方法說明可以看出,搜索獲得新設備后,即可調用設備對象的createBond方法建立配對。但配對成功與否的結果同樣不是立即返回的,因為系統會彈出配對確認框供用戶選擇,就像下面的兩個界面截圖那樣,左圖是A手機上的配對彈窗,右圖是B手機上的配對彈窗。
只有用戶在兩部手機都選擇了“配對”按鈕,才算是雙方正式搭配好了。由于配對請求需要在界面上手工確認,因此配對結果只能通過異步機制返回,此處的結果返回仍然采取廣播形式,即系統會發出廣播BluetoothDevice.ACTION_BOND_STATE_CHANGED通知App。故而前面第三步的廣播接收器得增加過濾綁定狀態的變更動作,接收器內部也要補充更新藍牙設備的綁定狀態了。修改后的廣播接收器相關代碼片段如下所示:
@Overrideprotected void onStart() {super.onStart();//需要過濾多個動作,則調用IntentFilter對象的addAction添加新動作IntentFilter discoveryFilter = new IntentFilter();discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);// 增加綁定狀態的變更動作discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//注冊搜索結果的接收器registerReceiver(discoveryReceiver, discoveryFilter);}// 藍牙設備的搜索結果通過廣播返回private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, "onReceive action=" + action);// 獲得已經搜索到的藍牙設備if (action.equals(BluetoothDevice.ACTION_FOUND)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);refreshDevice(device); // 將發現的藍牙設備加入到設備列表} else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);// 更新藍牙設備的綁定狀態if (device.getBondState() == BluetoothDevice.BOND_BONDING) {tv_discovery.setText("正在配對" + device.getName());} else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {tv_discovery.setText("完成配對" + device.getName());} else if (device.getBondState() == BluetoothDevice.BOND_NONE) {tv_discovery.setText("取消配對" + device.getName());}}}};兩部手機配對完畢,分別刷新自己的設備列表頁面,將對方設備的綁定狀態改為“已綁定”,然后它倆就可以眉目傳情,傳遞小紙條什么的了。下面是更新狀態后的設備列表界面,其中左圖為A手機的設備列表,右圖為B手機的設備列表:
點此查看Android開發筆記的完整目錄
__________________________________________________________________________
本文現已同步發布到微信公眾號“老歐說安卓”,打開微信掃一掃下面的二維碼,或者直接搜索公眾號“老歐說安卓”添加關注,更快更方便地閱讀技術干貨。
因為手機內部的通訊芯片一般同時集成了2G/3G/4G、WIFI和藍牙,所以藍牙功能已經是智能手機的標配了。若想進行藍牙方面的開發,需要在App工程的AndroidManifest.xml中補充下面的權限配置:
? ? <!-- 藍牙 --><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><uses-permission android:name="android.permission.BLUETOOTH" /><!-- 如果Android6.0 藍牙搜索不到設備,需要補充下面兩個權限 --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />與NFC類似,Android也提供了藍牙模塊的管理工具,名叫BluetoothAdapter,雖然通常把BluetoothAdapter翻譯為“藍牙適配器”,其實它干的是管理器的活。下面是BluetoothAdapter類常用的方法說明:
getDefaultAdapter : 獲取默認的藍牙適配器。該方法為靜態方法。
getState : 獲取藍牙的開關狀態。STATE_ON表示已開啟,STATE_TURNING_ON表示正在開啟,STATE_OFF表示已關閉,STATE_TURNING_OFF表示正在關閉。
enable : 啟用藍牙功能。
disable : 禁用藍牙功能。
isEnabled : 判斷藍牙功能是否啟用。返回true表示已啟用,返回false表示未啟用。
getBondedDevices : 獲取已配對的設備集合。
getRemoteDevice : 根據設備地址獲取遠程的設備對象。
startDiscovery : 開始搜索周圍的藍牙設備。
cancelDiscovery : 取消搜索周圍的藍牙設備。
isDiscovering : 判斷是否正在搜索周圍的藍牙設備。
接下來通過一個檢測藍牙設備并配對的例子,介紹如何在App開發中運用藍牙技術。不要小看這個例子,簡簡單單的功能可得分成四個步驟:初始化、啟用藍牙、搜索藍牙設備、與指定設備配對,下面分別進行詳細說明:
一、初始化藍牙適配器
如果僅僅是普通的藍牙連接,則調用getDefaultAdapter獲取藍牙適配器就行了。初始化藍牙適配器的代碼示例如下:
private BluetoothAdapter mBluetooth;private void initBluetooth() {mBluetooth = BluetoothAdapter.getDefaultAdapter();if (mBluetooth == null) {Toast.makeText(this, "本機未找到藍牙功能", Toast.LENGTH_SHORT).show();finish();}}
二、啟用藍牙功能
雖然BluetoothAdapter提供了enable方法用于啟用藍牙功能,但是該方法并不允許外部發現本設備,所以等于沒用。實際開發中要彈窗提示用戶,是否允許其他設備檢測到自身,彈窗代碼如下所示:
? ? // 彈出是否允許掃描藍牙設備的選擇對話框Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);startActivityForResult(intent, mOpenCode);藍牙權限的選擇對話框如下圖所示:
由于選擇彈窗上面可選擇“允許”還是“拒絕”,因此代碼中要重寫onActivityResult函數,在該函數中判斷藍牙權限的選擇結果。下面是判斷權限選擇的例子代碼:
private int mOpenCode = 1;@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent intent) {super.onActivityResult(requestCode, resultCode, intent);if (requestCode == mOpenCode) {mHandler.postDelayed(mRefresh, 50); // 刷新藍牙設備列表if (resultCode == RESULT_OK) {Toast.makeText(this, "允許本地藍牙被附近的其它藍牙設備發現", Toast.LENGTH_SHORT).show();} else if (resultCode == RESULT_CANCELED) {Toast.makeText(this, "不允許藍牙被附近的其它藍牙設備發現", Toast.LENGTH_SHORT).show();}}}
三、搜索周圍的藍牙設備
藍牙功能打開之后,就能調用startDiscovery方法去搜索周圍的藍牙設備了。不過因為搜索動作是個異步的過程,startDiscovery方法并不直接返回搜索發現的設備結果,而是通過廣播BluetoothDevice.ACTION_FOUND返回新發現的藍牙設備。所以頁面代碼需要注冊一個藍牙搜索結果的廣播接收器,在接收器中解析藍牙設備信息,再把新設備添加到藍牙設備列表。
下面是藍牙搜索接收器的注冊、注銷,以及內部邏輯處理的代碼例子:
? ? private void beginDiscovery() {// 如果當前不是正在搜索,則開始新的搜索任務if (!mBluetooth.isDiscovering()) {mBluetooth.startDiscovery();}}@Overrideprotected void onStart() {super.onStart();//需要過濾多個動作,則調用IntentFilter對象的addAction添加新動作IntentFilter discoveryFilter = new IntentFilter();discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);//注冊搜索結果的接收器registerReceiver(discoveryReceiver, discoveryFilter);}@Overrideprotected void onStop() {super.onStop();// 注銷廣播接收器unregisterReceiver(discoveryReceiver);}// 藍牙設備的搜索結果通過廣播返回private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, "onReceive action=" + action);// 獲得已經搜索到的藍牙設備if (action.equals(BluetoothDevice.ACTION_FOUND)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);refreshDevice(device); // 將發現的藍牙設備加入到設備列表}}};搜索到的藍牙設備可能會有多個,每發現一個新設備都會收到一次發現廣播,這樣設備列表是動態刷新的。搜索完成的藍牙設備列表界面如下圖所示,其中左圖為A手機的設備列表,右圖為B手機的設備列表:
四、與指定的藍牙設備配對
注意到新發現的設備狀態是“未綁定”,這意味著當前手機并不能跟對方設備進行數據交互。只有新設備是“已綁定”狀態,才能與當前手機傳輸數據。藍牙設備的“未綁定”與“已綁定”,區別在于這兩部設備之間是否成功配對了,而配對操作由BluetoothDevice類管理。下面是BluetoothDevice類的常用方法說明:
getName : 獲取設備的名稱。
getAddress : 獲取設備的MAC地址。
getBondState : 獲取設備的綁定狀態。BOND_NONE表示未綁定,BOND_BONDING表示正在綁定,BOND_BONDED表示已綁定。
createBond : 建立該設備的配對信息。該方法為隱藏方法,需要通過反射調用。
removeBond : 移除該設備的配對信息。該方法為隱藏方法,需要通過反射調用。
從上面的方法說明可以看出,搜索獲得新設備后,即可調用設備對象的createBond方法建立配對。但配對成功與否的結果同樣不是立即返回的,因為系統會彈出配對確認框供用戶選擇,就像下面的兩個界面截圖那樣,左圖是A手機上的配對彈窗,右圖是B手機上的配對彈窗。
只有用戶在兩部手機都選擇了“配對”按鈕,才算是雙方正式搭配好了。由于配對請求需要在界面上手工確認,因此配對結果只能通過異步機制返回,此處的結果返回仍然采取廣播形式,即系統會發出廣播BluetoothDevice.ACTION_BOND_STATE_CHANGED通知App。故而前面第三步的廣播接收器得增加過濾綁定狀態的變更動作,接收器內部也要補充更新藍牙設備的綁定狀態了。修改后的廣播接收器相關代碼片段如下所示:
@Overrideprotected void onStart() {super.onStart();//需要過濾多個動作,則調用IntentFilter對象的addAction添加新動作IntentFilter discoveryFilter = new IntentFilter();discoveryFilter.addAction(BluetoothDevice.ACTION_FOUND);// 增加綁定狀態的變更動作discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//注冊搜索結果的接收器registerReceiver(discoveryReceiver, discoveryFilter);}// 藍牙設備的搜索結果通過廣播返回private BroadcastReceiver discoveryReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();Log.d(TAG, "onReceive action=" + action);// 獲得已經搜索到的藍牙設備if (action.equals(BluetoothDevice.ACTION_FOUND)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);refreshDevice(device); // 將發現的藍牙設備加入到設備列表} else if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);// 更新藍牙設備的綁定狀態if (device.getBondState() == BluetoothDevice.BOND_BONDING) {tv_discovery.setText("正在配對" + device.getName());} else if (device.getBondState() == BluetoothDevice.BOND_BONDED) {tv_discovery.setText("完成配對" + device.getName());} else if (device.getBondState() == BluetoothDevice.BOND_NONE) {tv_discovery.setText("取消配對" + device.getName());}}}};兩部手機配對完畢,分別刷新自己的設備列表頁面,將對方設備的綁定狀態改為“已綁定”,然后它倆就可以眉目傳情,傳遞小紙條什么的了。下面是更新狀態后的設備列表界面,其中左圖為A手機的設備列表,右圖為B手機的設備列表:
點此查看Android開發筆記的完整目錄
__________________________________________________________________________
本文現已同步發布到微信公眾號“老歐說安卓”,打開微信掃一掃下面的二維碼,或者直接搜索公眾號“老歐說安卓”添加關注,更快更方便地閱讀技術干貨。
總結
以上是生活随笔為你收集整理的Android开发笔记(一百六十二)蓝牙设备的连接与配对的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机科学论文生成器,高考满分作文生成器
- 下一篇: Android 属性动画使用(二)