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