Android Bluetooth藍(lán)牙技術(shù)使用流程詳解
在上篇文章給大家介紹了Android Bluetooth藍(lán)牙技術(shù)初體驗相關(guān)內(nèi)容,感興趣的朋友可以點擊了解詳情。
一:藍(lán)牙設(shè)備之間的通信主要包括了四個步驟
設(shè)置藍(lán)牙設(shè)備
尋找局域網(wǎng)內(nèi)可能或者匹配的設(shè)備
連接設(shè)備
設(shè)備之間的數(shù)據(jù)傳輸
二:具體編程實現(xiàn)
1. 啟動藍(lán)牙功能
首先通過調(diào)用靜態(tài)方法getDefaultAdapter()獲取藍(lán)牙適配器BluetoothAdapter,如果返回為空,則無法繼續(xù)執(zhí)行了。例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
其次,調(diào)用isEnabled()來查詢當(dāng)前藍(lán)牙設(shè)備的狀態(tài),如果返回為false,則表示藍(lán)牙設(shè)備沒有開啟,接下來你需要封裝一個ACTION_REQUEST_ENABLE請求到intent里面,調(diào)用startActivityForResult()方法使能藍(lán)牙設(shè)備,例如:
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
2. 查找設(shè)備
使用BluetoothAdapter類里的方法,你可以查找遠(yuǎn)端設(shè)備(大概十米以內(nèi))或者查詢在你手機上已經(jīng)匹配(或者說綁定)的其他設(shè)備了。當(dāng)然需要確定對方藍(lán)牙設(shè)備已經(jīng)開啟或者已經(jīng)開啟了“被發(fā)現(xiàn)使能”功能(對方設(shè)備是可以被發(fā)現(xiàn)的是你能夠發(fā)起連接的前提條件)。如果該設(shè)備是可以被發(fā)現(xiàn)的,會反饋回來一些對方的設(shè)備信息,比如名字、MAC地址等,利用這些信息,你的設(shè)備就可以選擇去向?qū)Ψ匠跏蓟粋€連接。
如果你是第一次與該設(shè)備連接,那么一個配對的請求就會自動的顯示給用戶。當(dāng)設(shè)備配對好之后,他的一些基本信息(主要是名字和MAC)被保存下來并可以使用藍(lán)牙的API來讀取。使用已知的MAC地址就可以對遠(yuǎn)端的藍(lán)牙設(shè)備發(fā)起連接請求。
匹配好的設(shè)備和連接上的設(shè)備的不同點:匹配好只是說明對方設(shè)備發(fā)現(xiàn)了你的存在,并擁有一個共同的識別碼,并且可以連接。連接上:表示當(dāng)前設(shè)備共享一個RFCOMM信道并且兩者之間可以交換數(shù)據(jù)。也就是是說藍(lán)牙設(shè)備在建立RFCOMM信道之前,必須是已經(jīng)配對好了的。
3. 查詢匹配好的設(shè)備
在建立連接之前你必須先查詢配對好了的藍(lán)牙設(shè)備集以便選取一個設(shè)備進(jìn)行通信,例如你可以你可以查詢所有配對的藍(lán)牙設(shè)備,并使用一個數(shù)組適配器將其打印顯示出來:
Set<BluetoothDevice> pairedDevices =mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
//Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
建立一個藍(lán)牙連接只需要MAC地址就已經(jīng)足夠。
4. 掃描設(shè)備
掃描設(shè)備,只需要調(diào)用startDiscovery()方法,這個掃描的過程大概持續(xù)是12秒,應(yīng)用程序為了ACTION_FOUND動作需要注冊一個BroadcastReceiver來接受設(shè)備掃描到的信息。對于每一個設(shè)備,系統(tǒng)都會廣播ACTION_FOUND動作。
// 用ACTION_FOUND為action注冊廣播接收器
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// 發(fā)現(xiàn)設(shè)備
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// 從Intent中獲取藍(lán)牙設(shè)備
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 添加名字和地址到設(shè)備適配器中
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
//注冊廣播接收器
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); //在onDestroy時記得注銷廣播接收器
5. 使能被發(fā)現(xiàn)
如果你想使你的設(shè)備能夠被其他設(shè)備發(fā)現(xiàn),將ACTION_REQUEST_DISCOVERABLE動作封裝在intent中并調(diào)用startActivityForResult(Intent, int)方法就可以了。它將在不使你應(yīng)用程序退出的情況下使你的設(shè)備能夠被發(fā)現(xiàn)。缺省情況下的使能時間是120秒,當(dāng)然你可以可以通過添加EXTRA_DISCOVERABLE_DURATION字段來改變使能時間(最大不超過300秒)例如:
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent);
運行該段代碼之后,系統(tǒng)會彈出一個對話框來提示你啟動設(shè)備使能被發(fā)現(xiàn)(此過程中如果你的藍(lán)牙功能沒有開啟,系統(tǒng)會幫你開啟),并且如果你準(zhǔn)備對該遠(yuǎn)端設(shè)備發(fā)現(xiàn)一個連接,你不需要開啟設(shè)備被發(fā)現(xiàn)功能,因為該功能只是在你的應(yīng)用程序作為服務(wù)器端的時候才需要。
6. 連接設(shè)備
在應(yīng)用程序中,想建立兩個藍(lán)牙設(shè)備之間的連接,必須實現(xiàn)客戶端和服務(wù)器端的代碼(因為任何一個設(shè)備都必須可以作為服務(wù)端或者客戶端)。一個開啟服務(wù)來監(jiān)聽,一個發(fā)起連接請求(使用服務(wù)器端設(shè)備的MAC地址)。當(dāng)他們都擁有一個藍(lán)牙套接字在同一RFECOMM信道上的時候,可以認(rèn)為他們之間已經(jīng)連接上了。服務(wù)端和客戶端通過不同的方式或其他們的藍(lán)牙套接字。當(dāng)一個連接監(jiān)聽到的時候,服務(wù)端獲取到藍(lán)牙套接字。當(dāng)客戶可打開一個FRCOMM信道給服務(wù)器端的時候,客戶端獲取到藍(lán)牙套接字。
注意:在此過程中,如果兩個藍(lán)牙設(shè)備還沒有配對好的,android系統(tǒng)會通過一個通知或者對話框的形式來通知用戶。RFCOMM連接請求會在用戶選擇之前阻塞。
7. 服務(wù)端的連接
當(dāng)你想要連接兩臺設(shè)備時,一個必須作為服務(wù)端(通過持有一個打開的BluetoothServerSocket),目的是監(jiān)聽外來連接請求,當(dāng)監(jiān)聽到以后提供一個連接上的BluetoothSocket給客戶端,當(dāng)客戶端從BluetoothServerSocket得到BluetoothSocket以后就可以銷毀BluetoothServerSocket,除非你還想監(jiān)聽更多的連接請求。
建立服務(wù)套接字和監(jiān)聽連接的基本步驟:
首先通過調(diào)用listenUsingRfcommWithServiceRecord(String, UUID)方法來獲取BluetoothServerSocket對象,參數(shù)String代表了該服務(wù)的名稱,UUID代表了和客戶端連接的一個標(biāo)識(128位格式的字符串ID,相當(dāng)于PIN碼),UUID必須雙方匹配才可以建立連接。
其次調(diào)用accept()方法來監(jiān)聽可能到來的連接請求,當(dāng)監(jiān)聽到以后,返回一個連接上的藍(lán)牙套接字BluetoothSocket。
最后,在監(jiān)聽到一個連接以后,需要調(diào)用close()方法來關(guān)閉監(jiān)聽程序。(一般藍(lán)牙設(shè)備之間是點對點的傳輸)
注意:accept()方法不應(yīng)該放在主Acitvity里面,因為它是一種阻塞調(diào)用(在沒有監(jiān)聽到連接請求之前程序就一直停在那里)。解決方法是新建一個線程來管理。例如:
8. 客戶端的連接
為了初始化一個與遠(yuǎn)端設(shè)備的連接,需要先獲取代表該設(shè)備的一個BluetoothDevice對象。通過BluetoothDevice對象來獲取BluetoothSocket并初始化連接,具體步驟:
使用BluetoothDevice對象里的方法createRfcommSocketToServiceRecord(UUID)來獲取BluetoothSocket。UUID就是匹配碼。然后,調(diào)用connect()方法來。如果遠(yuǎn)端設(shè)備接收了該連接,他們將在通信過程中共享RFFCOMM信道,并且connect返回。
注意:conncet()方法也是阻塞調(diào)用,一般建立一個獨立的線程中來調(diào)用該方法。在設(shè)備discover過程中不應(yīng)該發(fā)起連接connect(),這樣會明顯減慢速度以至于連接失敗。且數(shù)據(jù)傳輸完成只有調(diào)用close()方法來關(guān)閉連接,這樣可以節(jié)省系統(tǒng)內(nèi)部資源。
9. 管理連接
當(dāng)設(shè)備連接上以后,每個設(shè)備都擁有各自的BluetoothSocket。就可以實現(xiàn)設(shè)備之間數(shù)據(jù)的共享了。
首先通過調(diào)用getInputStream()和getOutputStream()方法來獲取輸入輸出流。
然后通過調(diào)用read(byte[]) 和write(byte[]).方法來讀取或者寫數(shù)據(jù)。
實現(xiàn)細(xì)節(jié):以為讀取和寫操作都是阻塞調(diào)用,需要建立一個專用線程來管理。
10. 權(quán)限設(shè)置
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permissionandroid:name="android.permission.BLUETOOTH" />
以上所述是小編給大家分享的Android Bluetooth藍(lán)牙技術(shù)使用流程詳解,希望對大家有所幫助。
- Android藍(lán)牙開發(fā)深入解析
- 詳解Android——藍(lán)牙技術(shù) 帶你實現(xiàn)終端間數(shù)據(jù)傳輸
- Android單片機與藍(lán)牙模塊通信實例代碼
- 分享Android 藍(lán)牙4.0(ble)開發(fā)的解決方案
- Android 獲取藍(lán)牙Mac地址的正確方法
- Android手機通過藍(lán)牙連接佳博打印機的實例代碼
- android實現(xiàn)藍(lán)牙文件發(fā)送的實例代碼,支持多種機型
- Android實現(xiàn)藍(lán)牙(BlueTooth)設(shè)備檢測連接
- 詳解Android 藍(lán)牙通信方式總結(jié)
- Android學(xué)習(xí)筆記之藍(lán)牙功能
相關(guān)文章
flutter傳遞值到任意widget(當(dāng)需要widget嵌套使用需要傳遞值的時候)
這篇文章主要介紹了flutter傳遞值到任意widget(當(dāng)需要widget嵌套使用需要傳遞值的時候),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-07-07
Android?studio?利用共享存儲進(jìn)行用戶的注冊和登錄驗證功能
這篇文章主要介紹了Android?studio?利用共享存儲進(jìn)行用戶的注冊和登錄驗證功能,包括注冊頁面布局及登錄頁面功能,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12
Android開發(fā)之BottomSheetDialog組件的使用
BottomSheetDialog是底部操作控件,可在屏幕底部創(chuàng)建一個支持滑動關(guān)閉視圖。本文將通過示例詳細(xì)講解它的使用,感興趣的小伙伴可以了解一下2023-01-01
android實現(xiàn)用戶體驗超棒的微信WebView進(jìn)度條
本篇文章主要介紹了android實現(xiàn)用戶體驗超棒的微信WebView進(jìn)度條,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
Android 自定義驗證碼輸入框的實例代碼(支持粘貼連續(xù)性)
這篇文章主要介紹了Android 自定義驗證碼輸入框的實例代碼(支持粘貼連續(xù)性),代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-10-10
Android中使用DownloadManager類來管理數(shù)據(jù)下載的教程
這篇文章主要介紹了Android中使用DownloadManager類來管理數(shù)據(jù)下載的教程,針對HTTP下文件的下載與保存地址指定等基礎(chǔ)操作作出了詳細(xì)講解,需要的朋友可以參考下2016-04-04
PopupWindow?RecyclerView實現(xiàn)下拉選擇Spinner示例解析
這篇文章主要介紹了PopupWindow?RecyclerView實現(xiàn)下拉選擇Spinner示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
Android Fragment與Activity之間的相互通信實例代碼
這篇文章主要介紹了Android Fragment與Activity之間的相互通信的相關(guān)資料,并附簡單實例代碼,需要的朋友可以參考下2016-11-11
Android?Camera實現(xiàn)旋轉(zhuǎn)角度
這篇文章主要為大家詳細(xì)介紹了Android?Camera實現(xiàn)旋轉(zhuǎn)角度,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-07-07

