Android 平臺(tái)包含藍(lán)牙網(wǎng)絡(luò)堆棧支持岖寞,憑借此項(xiàng)支持,設(shè)備能以無(wú)線方式與其他藍(lán)牙設(shè)備交換數(shù)據(jù)。應(yīng)用框架提供了通過(guò) Android Bluetooth API 訪問(wèn)藍(lán)牙功能的途徑霸旗。 這些 API 允許應(yīng)用以無(wú)線方式連接到其他藍(lán)牙設(shè)備签舞,從而實(shí)現(xiàn)點(diǎn)到點(diǎn)和多點(diǎn)無(wú)線功能秕脓。
使用 Bluetooth API,Android 應(yīng)用可執(zhí)行以下操作:
- 掃描其他藍(lán)牙設(shè)備
- 查詢本地藍(lán)牙適配器的配對(duì)藍(lán)牙設(shè)備
- 建立 RFCOMM 通道
- 通過(guò)服務(wù)發(fā)現(xiàn)連接到其他設(shè)備
- 與其他設(shè)備進(jìn)行雙向數(shù)據(jù)傳輸
- 管理多個(gè)連接
本文將介紹如何使用傳統(tǒng)藍(lán)牙儒搭。傳統(tǒng)藍(lán)牙適用于電池使用強(qiáng)度較大的操作吠架,例如 Android 設(shè)備之間的流式傳輸和通信等。 針對(duì)具有低功耗要求的藍(lán)牙設(shè)備搂鲫,Android 4.3(API 級(jí)別 18)中引入了面向低功耗藍(lán)牙的 API 支持傍药。 如需了解更多信息,請(qǐng)參閱低功耗藍(lán)牙魂仍。
基礎(chǔ)知識(shí)
本文將介紹如何使用 Android Bluetooth API 來(lái)完成使用藍(lán)牙進(jìn)行通信的四項(xiàng)主要任務(wù):設(shè)置藍(lán)牙拐辽、查找局部區(qū)域內(nèi)的配對(duì)設(shè)備或可用設(shè)備、連接設(shè)備擦酌,以及在設(shè)備之間傳輸數(shù)據(jù)俱诸。
android.bluetooth 包中提供了所有 Bluetooth API。 下面概要列出了創(chuàng)建藍(lán)牙連接所需的類和接口:
BluetoothAdapter
表示本地藍(lán)牙適配器(藍(lán)牙無(wú)線裝置)赊舶。 BluetoothAdapter 是所有藍(lán)牙交互的入口點(diǎn)睁搭。 利用它可以發(fā)現(xiàn)其他藍(lán)牙設(shè)備,查詢綁定(配對(duì))設(shè)備的列表笼平,使用已知的 MAC 地址實(shí)例化 BluetoothDevice园骆,以及創(chuàng)建 BluetoothServerSocket 以偵聽(tīng)來(lái)自其他設(shè)備的通信。
BluetoothDevice
表示遠(yuǎn)程藍(lán)牙設(shè)備寓调。利用它可以通過(guò) BluetoothSocket 請(qǐng)求與某個(gè)遠(yuǎn)程設(shè)備建立連接锌唾,或查詢有關(guān)該設(shè)備的信息,例如設(shè)備的名稱捶牢、地址鸠珠、類和綁定狀態(tài)等巍耗。
BluetoothSocket
表示藍(lán)牙套接字接口(與 TCP Socket 相似)。這是允許應(yīng)用通過(guò) InputStream 和 OutputStream 與其他藍(lán)牙設(shè)備交換數(shù)據(jù)的連接點(diǎn)渐排。
BluetoothServerSocket
表示用于偵聽(tīng)傳入請(qǐng)求的開(kāi)放服務(wù)器套接字(類似于 TCP ServerSocket)炬太。 要連接兩臺(tái) Android 設(shè)備,其中一臺(tái)設(shè)備必須使用此類開(kāi)放一個(gè)服務(wù)器套接字驯耻。 當(dāng)一臺(tái)遠(yuǎn)程藍(lán)牙設(shè)備向此設(shè)備發(fā)出連接請(qǐng)求時(shí)亲族,BluetoothServerSocket 將會(huì)在接受連接后返回已連接的 BluetoothSocket。
BluetoothClass
描述藍(lán)牙設(shè)備的一般特征和功能可缚。 這是一組只讀屬性霎迫,用于定義設(shè)備的主要和次要設(shè)備類及其服務(wù)。 不過(guò)帘靡,它不能可靠地描述設(shè)備支持的所有藍(lán)牙配置文件和服務(wù)知给,而是適合作為設(shè)備類型提示。
BluetoothProfile
表示藍(lán)牙配置文件的接口描姚。 藍(lán)牙配置文件是適用于設(shè)備間藍(lán)牙通信的無(wú)線接口規(guī)范涩赢。 免提配置文件便是一個(gè)示例。 如需了解有關(guān)配置文件的詳細(xì)討論轩勘,請(qǐng)參閱使用配置文件
BluetoothHeadset
提供藍(lán)牙耳機(jī)支持筒扒,以便與手機(jī)配合使用。 其中包括藍(lán)牙耳機(jī)和免提(1.5 版)配置文件绊寻。
BluetoothA2dp
定義高質(zhì)量音頻如何通過(guò)藍(lán)牙連接和流式傳輸花墩,從一臺(tái)設(shè)備傳輸?shù)搅硪慌_(tái)設(shè)備〕尾剑“A2DP”代表高級(jí)音頻分發(fā)配置文件冰蘑。
BluetoothHealth
表示用于控制藍(lán)牙服務(wù)的健康設(shè)備配置文件代理。
BluetoothHealthCallback
用于實(shí)現(xiàn) BluetoothHealth 回調(diào)的抽象類驮俗。您必須擴(kuò)展此類并實(shí)現(xiàn)回調(diào)方法懂缕,以接收關(guān)于應(yīng)用注冊(cè)狀態(tài)和藍(lán)牙通道狀態(tài)變化的更新內(nèi)容。
BluetoothHealthAppConfiguration
表示第三方藍(lán)牙健康應(yīng)用注冊(cè)的應(yīng)用配置王凑,以便與遠(yuǎn)程藍(lán)牙健康設(shè)備通信搪柑。
BluetoothProfile.ServiceListener
在 BluetoothProfile IPC 客戶端連接到服務(wù)(即,運(yùn)行特定配置文件的內(nèi)部服務(wù))或斷開(kāi)服務(wù)連接時(shí)向其發(fā)送通知的接口索烹。
藍(lán)牙權(quán)限
要在應(yīng)用中使用藍(lán)牙功能工碾,必須聲明藍(lán)牙權(quán)限 BLUETOOTH。您需要此權(quán)限才能執(zhí)行任何藍(lán)牙通信百姓,例如請(qǐng)求連接渊额、接受連接和傳輸數(shù)據(jù)等。
如果您希望您的應(yīng)用啟動(dòng)設(shè)備發(fā)現(xiàn)或操作藍(lán)牙設(shè)置,則還必須聲明 BLUETOOTH_ADMIN 權(quán)限旬迹。 大多數(shù)應(yīng)用需要此權(quán)限僅僅為了能夠發(fā)現(xiàn)本地藍(lán)牙設(shè)備火惊。 除非該應(yīng)用是將要應(yīng)用戶請(qǐng)求修改藍(lán)牙設(shè)置的“超級(jí)管理員”,否則不應(yīng)使用此權(quán)限所授予的其他能力奔垦。 注:如果要使用 BLUETOOTH_ADMIN 權(quán)限屹耐,則還必須擁有 BLUETOOTH 權(quán)限。
在您的應(yīng)用清單文件中聲明藍(lán)牙權(quán)限椿猎。例如:
<manifest ... >
<uses-permission android:name="android.permission.BLUETOOTH" />
...
</manifest>
如需了解有關(guān)聲明應(yīng)用權(quán)限的更多信息惶岭,請(qǐng)參閱 <uses-permission> 參考資料。
設(shè)置藍(lán)牙
您需要驗(yàn)證設(shè)備支持藍(lán)牙犯眠,并且如果支持確保將其啟用按灶,然后您的應(yīng)用才能通過(guò)藍(lán)牙進(jìn)行通信。
如果不支持藍(lán)牙筐咧,則應(yīng)正常停用任何藍(lán)牙功能鸯旁。 如果支持藍(lán)牙但已停用此功能,則可以請(qǐng)求用戶在不離開(kāi)應(yīng)用的同時(shí)啟用藍(lán)牙嗜浮。 可使用 BluetoothAdapter羡亩,分兩步完成此設(shè)置:
-
所有藍(lán)牙 Activity 都需要 BluetoothAdapter。 要獲取 BluetoothAdapter危融,請(qǐng)調(diào)用靜態(tài) getDefaultAdapter() 方法。這將返回一個(gè)表示設(shè)備自身的藍(lán)牙適配器(藍(lán)牙無(wú)線裝置)的 BluetoothAdapter雷袋。 整個(gè)系統(tǒng)有一個(gè)藍(lán)牙適配器吉殃,并且您的應(yīng)用可使用此對(duì)象與之交互。 如果 getDefaultAdapter() 返回 null被济,則該設(shè)備不支持藍(lán)牙廉沮,您的操作到此為止叠艳。 例如:
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
2.啟用藍(lán)牙
下一步,您需要確保已啟用藍(lán)牙抱完。調(diào)用 isEnabled() 以檢查當(dāng)前是否已啟用藍(lán)牙。 如果此方法返回 false刃泡,則表示藍(lán)牙處于停用狀態(tài)巧娱。要請(qǐng)求啟用藍(lán)牙,請(qǐng)使用 ACTION_REQUEST_ENABLE 操作 Intent 調(diào)用 startActivityForResult()烘贴。這將通過(guò)系統(tǒng)設(shè)置發(fā)出啟用藍(lán)牙的請(qǐng)求(無(wú)需停止您的應(yīng)用)禁添。 例如:
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
如圖 1 所示,將顯示對(duì)話框桨踪,請(qǐng)求用戶允許啟用藍(lán)牙老翘。如果用戶響應(yīng)“Yes”,系統(tǒng)將開(kāi)始啟用藍(lán)牙,并在該進(jìn)程完成(或失斊糖汀)后將焦點(diǎn)返回到您的應(yīng)用墓怀。
傳遞給 startActivityForResult() 的 REQUEST_ENABLE_BT 常量是在局部定義的整型(必須大于 0),系統(tǒng)會(huì)將其作為 requestCode 參數(shù)傳遞回您的 onActivityResult() 實(shí)現(xiàn)卫键。
如果成功啟用藍(lán)牙捺疼,您的 Activity 將會(huì)在 onActivityResult() 回調(diào)中收到 RESULT_OK 結(jié)果代碼。 如果由于某個(gè)錯(cuò)誤(或用戶響應(yīng)“No”)而沒(méi)有啟用藍(lán)牙永罚,則結(jié)果代碼為 RESULT_CANCELED啤呼。
您的應(yīng)用還可以選擇偵聽(tīng) ACTION_STATE_CHANGED 廣播 Intent呢袱,每當(dāng)藍(lán)牙狀態(tài)發(fā)生變化時(shí)官扣,系統(tǒng)都會(huì)廣播此 Intent。 此廣播包含額外字段 EXTRA_STATE 和 EXTRA_PREVIOUS_STATE羞福,二者分別包含新的和舊的藍(lán)牙狀態(tài)惕蹄。 這些額外字段可能的值包括 STATE_TURNING_ON、STATE_ON治专、STATE_TURNING_OFF 和 STATE_OFF卖陵。偵聽(tīng)此廣播適用于檢測(cè)在您的應(yīng)用運(yùn)行期間對(duì)藍(lán)牙狀態(tài)所做的更改。
提示:?jiǎn)⒂每蓹z測(cè)性將會(huì)自動(dòng)啟用藍(lán)牙张峰。 如果您計(jì)劃在執(zhí)行藍(lán)牙 Activity 之前一直啟用設(shè)備的可檢測(cè)性泪蔫,則可以跳過(guò)上述步驟 2。 閱讀下面的啟用可檢測(cè)性喘批。
查找設(shè)備
使用 BluetoothAdapter撩荣,您可以通過(guò)設(shè)備發(fā)現(xiàn)或通過(guò)查詢配對(duì)(綁定)設(shè)備的列表來(lái)查找遠(yuǎn)程藍(lán)牙設(shè)備。
設(shè)備發(fā)現(xiàn)是一個(gè)掃描過(guò)程饶深,它會(huì)搜索局部區(qū)域內(nèi)已啟用藍(lán)牙功能的設(shè)備餐曹,然后請(qǐng)求一些關(guān)于各臺(tái)設(shè)備的信息(有時(shí)也被稱為“發(fā)現(xiàn)”、“查詢”或“掃描”)敌厘。但局部區(qū)域內(nèi)的藍(lán)牙設(shè)備僅在其當(dāng)前已啟用可檢測(cè)性時(shí)才會(huì)響應(yīng)發(fā)現(xiàn)請(qǐng)求台猴。 如果設(shè)備可檢測(cè)到,它將通過(guò)共享一些信息(例如設(shè)備名稱俱两、類及其唯一 MAC 地址)來(lái)響應(yīng)發(fā)現(xiàn)請(qǐng)求饱狂。 利用此信息,執(zhí)行發(fā)現(xiàn)的設(shè)備可以選擇發(fā)起到被發(fā)現(xiàn)設(shè)備的連接锋华。
在首次與遠(yuǎn)程設(shè)備建立連接后嗡官,將會(huì)自動(dòng)向用戶顯示配對(duì)請(qǐng)求。 設(shè)備完成配對(duì)后毯焕,將會(huì)保存關(guān)于該設(shè)備的基本信息(例如設(shè)備名稱衍腥、類和 MAC 地址)磺樱,并且可使用 Bluetooth API 讀取這些信息。 利用遠(yuǎn)程設(shè)備的已知 MAC 地址可隨時(shí)向其發(fā)起連接婆咸,而無(wú)需執(zhí)行發(fā)現(xiàn)操作(假定該設(shè)備處于有效范圍內(nèi))竹捉。
請(qǐng)記住,被配對(duì)與被連接之間存在差別尚骄。被配對(duì)意味著兩臺(tái)設(shè)備知曉彼此的存在块差,具有可用于身份驗(yàn)證的共享鏈路密鑰,并且能夠與彼此建立加密連接倔丈。 被連接意味著設(shè)備當(dāng)前共享一個(gè) RFCOMM 通道憨闰,并且能夠向彼此傳輸數(shù)據(jù)。 當(dāng)前的 Android Bluetooth API 要求對(duì)設(shè)備進(jìn)行配對(duì)需五,然后才能建立 RFCOMM 連接鹉动。 (在使用 Bluetooth API 發(fā)起加密連接時(shí),會(huì)自動(dòng)執(zhí)行配對(duì))宏邮。
以下幾節(jié)介紹如何查找已配對(duì)的設(shè)備泽示,或使用設(shè)備發(fā)現(xiàn)來(lái)發(fā)現(xiàn)新設(shè)備。
注:Android 設(shè)備默認(rèn)處于不可檢測(cè)到狀態(tài)蜜氨。 用戶可通過(guò)系統(tǒng)設(shè)置將設(shè)備設(shè)為在有限的時(shí)間內(nèi)處于可檢測(cè)到狀態(tài)械筛,或者,應(yīng)用可請(qǐng)求用戶在不離開(kāi)應(yīng)用的同時(shí)啟用可檢測(cè)性飒炎。 下面討論如何啟用可檢測(cè)性埋哟。
查詢配對(duì)的設(shè)備
在執(zhí)行設(shè)備發(fā)現(xiàn)之前,有必要查詢已配對(duì)的設(shè)備集厌丑,以了解所需的設(shè)備是否處于已知狀態(tài)定欧。 為此,請(qǐng)調(diào)用 getBondedDevices()怒竿。 這將返回表示已配對(duì)設(shè)備的一組 BluetoothDevice。 例如扩氢,您可以查詢所有已配對(duì)設(shè)備耕驰,然后使用 ArrayAdapter 向用戶顯示每臺(tái)設(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());
}
}
要發(fā)起連接,BluetoothDevice 對(duì)象僅僅需要提供 MAC 地址录豺。 在此示例中朦肘,它將保存為顯示給用戶的 ArrayAdapter 的一部分。 之后可提取該 MAC 地址双饥,以便發(fā)起連接媒抠。 您可以在有關(guān)連接設(shè)備的部分詳細(xì)了解如何創(chuàng)建連接。
發(fā)現(xiàn)設(shè)備
要開(kāi)始發(fā)現(xiàn)設(shè)備咏花,只需調(diào)用 startDiscovery()趴生。該進(jìn)程為異步進(jìn)程阀趴,并且該方法會(huì)立即返回一個(gè)布爾值,指示是否已成功啟動(dòng)發(fā)現(xiàn)操作苍匆。 發(fā)現(xiàn)進(jìn)程通常包含約 12 秒鐘的查詢掃描刘急,之后對(duì)每臺(tái)發(fā)現(xiàn)的設(shè)備進(jìn)行頁(yè)面掃描,以檢索其藍(lán)牙名稱浸踩。
您的應(yīng)用必須針對(duì) ACTION_FOUND Intent 注冊(cè)一個(gè) BroadcastReceiver叔汁,以便接收每臺(tái)發(fā)現(xiàn)的設(shè)備的相關(guān)信息。 針對(duì)每臺(tái)設(shè)備检碗,系統(tǒng)將會(huì)廣播 ACTION_FOUND Intent据块。此 Intent 將攜帶額外字段 EXTRA_DEVICE 和 EXTRA_CLASS,二者分別包含BluetoothDevice 和 BluetoothClass折剃。 例如另假,下面說(shuō)明了在發(fā)現(xiàn)設(shè)備時(shí)如何注冊(cè)以處理廣播。
// Create a BroadcastReceiver for ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
要發(fā)起連接微驶,BluetoothDevice 對(duì)象僅僅需要提供 MAC 地址浪谴。 在此示例中,它將保存為顯示給用戶的 ArrayAdapter 的一部分因苹。 之后可提取該 MAC 地址苟耻,以便發(fā)起連接。 您可以在有關(guān)連接設(shè)備的部分詳細(xì)了解如何創(chuàng)建連接扶檐。
注意:執(zhí)行設(shè)備發(fā)現(xiàn)對(duì)于藍(lán)牙適配器而言是一個(gè)非常繁重的操作過(guò)程凶杖,并且會(huì)消耗大量資源。 在找到要連接的設(shè)備后款筑,確保始終使用 cancelDiscovery() 停止發(fā)現(xiàn)智蝠,然后再嘗試連接。 此外奈梳,如果您已經(jīng)保持與某臺(tái)設(shè)備的連接杈湾,那么執(zhí)行發(fā)現(xiàn)操作可能會(huì)大幅減少可用于該連接的帶寬,因此不應(yīng)該在處于連接狀態(tài)時(shí)執(zhí)行發(fā)現(xiàn)操作攘须。
啟用可檢測(cè)性
如果您希望將本地設(shè)備設(shè)為可被其他設(shè)備檢測(cè)到漆撞,請(qǐng)使用 ACTION_REQUEST_DISCOVERABLE 操作 Intent 調(diào)用 startActivityForResult(Intent, int)。 這將通過(guò)系統(tǒng)設(shè)置發(fā)出啟用可檢測(cè)到模式的請(qǐng)求(無(wú)需停止您的應(yīng)用)于宙。 默認(rèn)情況下浮驳,設(shè)備將變?yōu)榭蓹z測(cè)到并持續(xù) 120 秒鐘。 您可以通過(guò)添加 EXTRA_DISCOVERABLE_DURATION Intent Extra 來(lái)定義不同的持續(xù)時(shí)間捞魁。 應(yīng)用可以設(shè)置的最大持續(xù)時(shí)間為 3600 秒至会,值為 0 則表示設(shè)備始終可檢測(cè)到。 任何小于 0 或大于 3600 的值都會(huì)自動(dòng)設(shè)為 120 秒谱俭。 例如奉件,以下片段會(huì)將持續(xù)時(shí)間設(shè)為 300 秒:
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
如圖 2 所示宵蛀,將顯示對(duì)話框,請(qǐng)求用戶允許將設(shè)備設(shè)為可檢測(cè)到瓶蚂。如果用戶響應(yīng)“Yes”糖埋,則設(shè)備將變?yōu)榭蓹z測(cè)到并持續(xù)指定的時(shí)間量。 然后窃这,您的 Activity 將會(huì)收到對(duì) onActivityResult() 回調(diào)的調(diào)用瞳别,其結(jié)果代碼等于設(shè)備可檢測(cè)到的持續(xù)時(shí)間。 如果用戶響應(yīng)“No”或出現(xiàn)錯(cuò)誤杭攻,結(jié)果代碼將為 RESULT_CANCELED祟敛。
注:如果尚未在設(shè)備上啟用藍(lán)牙,則啟用設(shè)備可檢測(cè)性將會(huì)自動(dòng)啟用藍(lán)牙兆解。
設(shè)備將在分配的時(shí)間內(nèi)以靜默方式保持可檢測(cè)到模式。如果您希望在可檢測(cè)到模式發(fā)生變化時(shí)收到通知锅睛,您可以針對(duì) ACTION_SCAN_MODE_CHANGED Intent 注冊(cè) BroadcastReceiver埠巨。 它將包含額外字段 EXTRA_SCAN_MODE 和 EXTRA_PREVIOUS_SCAN_MODE,二者分別告知您新的和舊的掃描模式现拒。 每個(gè)字段可能的值包括SCAN_MODE_CONNECTABLE_DISCOVERABLE辣垒、 SCAN_MODE_CONNECTABLE 或 SCAN_MODE_NONE,這些值分別指示設(shè)備處于可檢測(cè)到模式印蔬、未處于可檢測(cè)到模式但仍能接收連接勋桶,或未處于可檢測(cè)到模式并且無(wú)法接收連接。
如果您將要發(fā)起到遠(yuǎn)程設(shè)備的連接侥猬,則無(wú)需啟用設(shè)備可檢測(cè)性例驹。 僅當(dāng)您希望您的應(yīng)用托管將用于接受傳入連接的服務(wù)器套接字時(shí),才有必要啟用可檢測(cè)性退唠,因?yàn)檫h(yuǎn)程設(shè)備必須能夠發(fā)現(xiàn)該設(shè)備鹃锈,然后才能發(fā)起連接。
連接設(shè)備
要在兩臺(tái)設(shè)備上的應(yīng)用之間創(chuàng)建連接瞧预,必須同時(shí)實(shí)現(xiàn)服務(wù)器端和客戶端機(jī)制仪召,因?yàn)槠渲幸慌_(tái)設(shè)備必須開(kāi)放服務(wù)器套接字,而另一臺(tái)設(shè)備必須發(fā)起連接(使用服務(wù)器設(shè)備的 MAC 地址發(fā)起連接)松蒜。 當(dāng)服務(wù)器和客戶端在同一 RFCOMM 通道上分別擁有已連接的 BluetoothSocket 時(shí),二者將被視為彼此連接已旧。 這種情況下秸苗,每臺(tái)設(shè)備都能獲得輸入和輸出流式傳輸,并且可以開(kāi)始傳輸數(shù)據(jù)运褪,在有關(guān)管理連接的部分將會(huì)討論這一主題惊楼。 本部分介紹如何在兩臺(tái)設(shè)備之間發(fā)起連接玖瘸。
服務(wù)器設(shè)備和客戶端設(shè)備分別以不同的方法獲得需要的 BluetoothSocket。服務(wù)器將在傳入連接被接受時(shí)收到套接字檀咙。 客戶端將在其打開(kāi)到服務(wù)器的 RFCOMM 通道時(shí)收到該套接字雅倒。
一種實(shí)現(xiàn)技術(shù)是自動(dòng)將每臺(tái)設(shè)備準(zhǔn)備為一個(gè)服務(wù)器,從而使每臺(tái)設(shè)備開(kāi)放一個(gè)服務(wù)器套接字并偵聽(tīng)連接弧可。然后任一設(shè)備可以發(fā)起與另一臺(tái)設(shè)備的連接蔑匣,并成為客戶端。 或者棕诵,其中一臺(tái)設(shè)備可顯式“托管”連接并按需開(kāi)放一個(gè)服務(wù)器套接字裁良,而另一臺(tái)設(shè)備則直接發(fā)起連接。
注:如果兩臺(tái)設(shè)備之前尚未配對(duì)校套,則在連接過(guò)程中价脾,Android 框架會(huì)自動(dòng)向用戶顯示配對(duì)請(qǐng)求通知或?qū)υ捒颍ㄈ鐖D 3 所示)。因此笛匙,在嘗試連接設(shè)備時(shí)侨把,您的應(yīng)用無(wú)需擔(dān)心設(shè)備是否已配對(duì)。 您的 RFCOMM 連接嘗試將被阻塞妹孙,直至用戶成功完成配對(duì)或配對(duì)失斍锉(包括用戶拒絕配對(duì)、配對(duì)失敗或超時(shí))涕蜂。
連接為服務(wù)器
當(dāng)您需要連接兩臺(tái)設(shè)備時(shí),其中一臺(tái)設(shè)備必須通過(guò)保持開(kāi)放的 BluetoothServerSocket 來(lái)充當(dāng)服務(wù)器机隙。 服務(wù)器套接字的用途是偵聽(tīng)傳入的連接請(qǐng)求蜘拉,并在接受一個(gè)請(qǐng)求后提供已連接的 BluetoothSocket。 從 BluetoothServerSocket 獲取 BluetoothSocket 后有鹿,可以(并且應(yīng)該)舍棄 BluetoothServerSocket旭旭,除非您需要接受更多連接。
關(guān)于 UUID
通用唯一標(biāo)識(shí)符 (UUID) 是用于唯一標(biāo)識(shí)信息的字符串 ID 的 128 位標(biāo)準(zhǔn)化格式葱跋。 UUID 的特點(diǎn)是其足夠龐大持寄,因此您可以選擇任意隨機(jī)值而不會(huì)發(fā)生沖突。 在此示例中娱俺,它被用于唯一標(biāo)識(shí)應(yīng)用的藍(lán)牙服務(wù)稍味。 要獲取 UUID 以用于您的應(yīng)用,您可以使用網(wǎng)絡(luò)上的眾多隨機(jī) UUID 生成器之一荠卷,然后使用 fromString(String) 初始化一個(gè) UUID模庐。
以下是設(shè)置服務(wù)器套接字并接受連接的基本過(guò)程:
1.通過(guò)調(diào)用 listenUsingRfcommWithServiceRecord(String, UUID) 獲取 BluetoothServerSocket。
該字符串是您的服務(wù)的可識(shí)別名稱油宜,系統(tǒng)會(huì)自動(dòng)將其寫入到設(shè)備上的新服務(wù)發(fā)現(xiàn)協(xié)議 (SDP) 數(shù)據(jù)庫(kù)條目(可使用任意名稱掂碱,也可直接使用您的應(yīng)用名稱)怜姿。 UUID 也包含在 SDP 條目中,并且將作為與客戶端設(shè)備的連接協(xié)議的基礎(chǔ)疼燥。 也就是說(shuō)沧卢,當(dāng)客戶端嘗試連接此設(shè)備時(shí),它會(huì)攜帶能夠唯一標(biāo)識(shí)其想要連接的服務(wù)的 UUID醉者。 兩個(gè) UUID 必須匹配但狭,在下一步中,連接才會(huì)被接受湃交。
2.通過(guò)調(diào)用 accept() 開(kāi)始偵聽(tīng)連接請(qǐng)求熟空。
這是一個(gè)阻塞調(diào)用。它將在連接被接受或發(fā)生異常時(shí)返回搞莺。 僅當(dāng)遠(yuǎn)程設(shè)備發(fā)送的連接請(qǐng)求中所包含的 UUID 與向此偵聽(tīng)服務(wù)器套接字注冊(cè)的 UUID 相匹配時(shí)息罗,連接才會(huì)被接受。 操作成功后才沧,accept() 將會(huì)返回已連接的 BluetoothSocket迈喉。
3.除非您想要接受更多連接,否則請(qǐng)調(diào)用 close()温圆。
這將釋放服務(wù)器套接字及其所有資源挨摸,但不會(huì)關(guān)閉 accept() 所返回的已連接的 BluetoothSocket泻拦。 與 TCP/IP 不同草则,RFCOMM 一次只允許每個(gè)通道有一個(gè)已連接的客戶端甘桑,因此大多數(shù)情況下唤蔗,在接受已連接的套接字后立即在 BluetoothServerSocket 上調(diào)用 close() 是行得通的。
accept() 調(diào)用不應(yīng)在主 Activity UI 線程中執(zhí)行嘶是,因?yàn)樗亲枞{(diào)用释移,并會(huì)阻止與應(yīng)用的任何其他交互旭愧。 在您的應(yīng)用所管理的新線程中使用 BluetoothServerSocket 或 BluetoothSocket 完成所有工作非剃,這通常是一種行之有效的做法置逻。 要終止 accept() 等被阻塞的調(diào)用,請(qǐng)通過(guò)另一個(gè)線程在 BluetoothServerSocket(或 BluetoothSocket)上調(diào)用 close()备绽,被阻塞的調(diào)用將會(huì)立即返回券坞。 請(qǐng)注意,BluetoothServerSocket 或 BluetoothSocket
示例
以下是一個(gè)用于接受傳入連接的服務(wù)器組件的簡(jiǎn)化線程:
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);
mmServerSocket.close();
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
在此示例中肺素,只需要一個(gè)傳入連接恨锚,因此在接受連接并獲取 BluetoothSocket 之后,應(yīng)用會(huì)立即將獲取的 BluetoothSocket 發(fā)送到單獨(dú)的線程倍靡,關(guān)閉 BluetoothServerSocket 并中斷循環(huán)眠冈。
請(qǐng)注意,當(dāng) accept() 返回 BluetoothSocket 時(shí),表示套接字已連接好蜗顽,因此您不應(yīng)該像在客戶端那樣調(diào)用 connect()。
manageConnectedSocket()
是應(yīng)用中的虛構(gòu)方法雨让,它將啟動(dòng)用于傳輸數(shù)據(jù)的線程雇盖,在有關(guān)管理連接的部分將會(huì)討論這一主題。
在完成傳入連接的偵聽(tīng)后栖忠,通常應(yīng)立即關(guān)閉您的 BluetoothServerSocket崔挖。 在此示例中,獲取 BluetoothSocket 后立即調(diào)用 close()庵寞。 您也可能希望在您的線程中提供一個(gè)公共方法狸相,以便在需要停止偵聽(tīng)服務(wù)器套接字時(shí)關(guān)閉私有 BluetoothSocket。
連接為客戶端
要發(fā)起與遠(yuǎn)程設(shè)備(保持開(kāi)放的服務(wù)器套接字的設(shè)備)的連接捐川,必須首先獲取表示該遠(yuǎn)程設(shè)備的 BluetoothDevice 對(duì)象脓鹃。(在前面有關(guān)查找設(shè)備的部分介紹了如何獲取 BluetoothDevice)。 然后必須使用 BluetoothDevice 來(lái)獲取 BluetoothSocket 并發(fā)起連接古沥。
以下是基本過(guò)程:
-
使用 BluetoothDevice瘸右,通過(guò)調(diào)用 createRfcommSocketToServiceRecord(UUID) 獲取 BluetoothSocket。
這將初始化將要連接到 BluetoothDevice 的 BluetoothSocket岩齿。 此處傳遞的 UUID 必須與服務(wù)器設(shè)備在使用 listenUsingRfcommWithServiceRecord(String, UUID) 開(kāi)放其 BluetoothServerSocket 時(shí)所用的 UUID 相匹配太颤。 要使用相同的 UUID,只需將該 UUID 字符串以硬編碼方式編入應(yīng)用盹沈,然后通過(guò)服務(wù)器代碼和客戶端代碼引用該字符串龄章。
-
通過(guò)調(diào)用 connect() 發(fā)起連接。
執(zhí)行此調(diào)用時(shí)乞封,系統(tǒng)將會(huì)在遠(yuǎn)程設(shè)備上執(zhí)行 SDP 查找做裙,以便匹配 UUID。 如果查找成功并且遠(yuǎn)程設(shè)備接受了該連接歌亲,它將共享 RFCOMM 通道以便在連接期間使用菇用,并且 connect() 將會(huì)返回。 此方法為阻塞調(diào)用陷揪。 如果由于任何原因連接失敗或 connect() 方法超時(shí)(大約 12 秒之后)惋鸥,它將會(huì)引發(fā)異常。
由于 connect() 為阻塞調(diào)用悍缠,因此該連接過(guò)程應(yīng)始終在主 Activity 線程以外的線程中執(zhí)行卦绣。
注:在調(diào)用 connect() 時(shí),應(yīng)始終確保設(shè)備未在執(zhí)行設(shè)備發(fā)現(xiàn)飞蚓。 如果正在進(jìn)行發(fā)現(xiàn)操作滤港,則會(huì)大幅降低連接嘗試的速度,并增加連接失敗的可能性。
示例
以下是發(fā)起藍(lán)牙連接的線程的基本示例:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
請(qǐng)注意溅漾,在建立連接之前會(huì)調(diào)用 cancelDiscovery()山叮。 在進(jìn)行連接之前應(yīng)始終執(zhí)行此調(diào)用,而且調(diào)用時(shí)無(wú)需實(shí)際檢查其是否正在運(yùn)行(但如果您確實(shí)想要執(zhí)行檢查添履,請(qǐng)調(diào)用 isDiscovering())屁倔。
manageConnectedSocket() 是應(yīng)用中的虛構(gòu)方法,它將啟動(dòng)用于傳輸數(shù)據(jù)的線程暮胧,在有關(guān)管理連接的部分將會(huì)討論這一主題锐借。
在完成 BluetoothSocket 后,應(yīng)始終調(diào)用 close() 以執(zhí)行清理操作往衷。這樣做會(huì)立即關(guān)閉已連接的套接字并清理所有內(nèi)部資源钞翔。
管理連接
在成功連接兩臺(tái)(或更多臺(tái))設(shè)備后,每臺(tái)設(shè)備都會(huì)有一個(gè)已連接的 BluetoothSocket席舍。 這一點(diǎn)非常有趣布轿,因?yàn)檫@表示您可以在設(shè)備之間共享數(shù)據(jù)。 利用 BluetoothSocket俺亮,傳輸任意數(shù)據(jù)的一般過(guò)程非常簡(jiǎn)單:
在成功連接兩臺(tái)(或更多臺(tái))設(shè)備后驮捍,每臺(tái)設(shè)備都會(huì)有一個(gè)已連接的 BluetoothSocket。 這一點(diǎn)非常有趣脚曾,因?yàn)檫@表示您可以在設(shè)備之間共享數(shù)據(jù)东且。 利用 BluetoothSocket,傳輸任意數(shù)據(jù)的一般過(guò)程非常簡(jiǎn)單:
- 獲取 InputStream 和 OutputStream本讥,二者分別通過(guò)套接字以及 getInputStream() 和 getOutputStream() 來(lái)處理數(shù)據(jù)傳輸珊泳。
- 使用 read(byte[]) 和 write(byte[]) 讀取數(shù)據(jù)并寫入到流式傳輸。
就這么簡(jiǎn)單拷沸。
當(dāng)然色查,還需要考慮實(shí)現(xiàn)細(xì)節(jié)。首要的是撞芍,應(yīng)該為所有流式傳輸讀取和寫入操作使用專門的線程秧了。 這一點(diǎn)很重要,因?yàn)?read(byte[]) 和 write(byte[]) 方法都是阻塞調(diào)用序无。read(byte[]) 將會(huì)阻塞验毡,直至從流式傳輸中讀取內(nèi)容。write(byte[]) 通常不會(huì)阻塞帝嗡,但如果遠(yuǎn)程設(shè)備沒(méi)有足夠快地調(diào)用 read(byte[])晶通,并且中間緩沖區(qū)已滿,則其可能會(huì)保持阻塞狀態(tài)以實(shí)現(xiàn)流量控制哟玷。因此狮辽,線程中的主循環(huán)應(yīng)專門用于讀取 InputStream。 可使用線程中單獨(dú)的公共方法來(lái)發(fā)起對(duì) OutputStream 的寫入操作。
示例
以下是可能的顯示內(nèi)容示例:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
構(gòu)造函數(shù)獲取必要的流式傳輸喉脖,并且一旦執(zhí)行椰苟,線程將會(huì)等待通過(guò) InputStream 傳入的數(shù)據(jù)。 當(dāng) read(byte[]) 返回流式傳輸中的字節(jié)時(shí)动看,將使用來(lái)自父類的成員處理程序?qū)?shù)據(jù)發(fā)送到主 Activity尊剔。
發(fā)送傳出數(shù)據(jù)不外乎從主 Activity 調(diào)用線程的 write() 方法,并傳入要發(fā)送的字節(jié)菱皆。 然后,此方法直接調(diào)用 write(byte[])挨稿,將數(shù)據(jù)發(fā)送到遠(yuǎn)程設(shè)備仇轻。
線程的 cancel() 方法很重要,它能通過(guò)關(guān)閉 BluetoothSocket 隨時(shí)終止連接奶甘。當(dāng)您結(jié)束藍(lán)牙連接的使用時(shí)篷店,應(yīng)始終調(diào)用此方法。
有關(guān)使用 Bluetooth API 的演示臭家,請(qǐng)參閱藍(lán)牙聊天示例應(yīng)用疲陕。
使用配置文件
從 Android 3.0 開(kāi)始,Bluetooth API 便支持使用藍(lán)牙配置文件钉赁。 藍(lán)牙配置文件是適用于設(shè)備間藍(lán)牙通信的無(wú)線接口規(guī)范蹄殃。 免提配置文件便是一個(gè)示例。 對(duì)于連接到無(wú)線耳機(jī)的手機(jī)你踩,兩臺(tái)設(shè)備都必須支持免提配置文件诅岩。
您可以實(shí)現(xiàn)接口 BluetoothProfile,通過(guò)寫入自己的類來(lái)支持特定的藍(lán)牙配置文件带膜。 Android Bluetooth API 提供了以下藍(lán)牙配置文件的實(shí)現(xiàn):
耳機(jī)吩谦。耳機(jī)配置文件提供了藍(lán)牙耳機(jī)支持,以便與手機(jī)配合使用膝藕。 Android 提供了 BluetoothHeadset 類式廷,它是用于通過(guò)進(jìn)程間通信 (IPC) 來(lái)控制藍(lán)牙耳機(jī)服務(wù)的代理。 這包括藍(lán)牙耳機(jī)和免提(1.5 版)配置文件芭挽。BluetoothHeadset 類包含 AT 命令支持滑废。 有關(guān)此主題的詳細(xì)討論,請(qǐng)參閱供應(yīng)商特定的 AT 命令
A2DP览绿。高級(jí)音頻分發(fā)配置文件 (A2DP) 定義了高質(zhì)量音頻如何通過(guò)藍(lán)牙連接和流式傳輸策严,從一個(gè)設(shè)備傳輸?shù)搅硪粋€(gè)設(shè)備。 Android 提供了 BluetoothA2dp 類饿敲,它是用于通過(guò) IPC 來(lái)控制藍(lán)牙 A2DP 服務(wù)的代理妻导。
健康設(shè)備。Android 4.0(API 級(jí)別 14)引入了對(duì)藍(lán)牙健康設(shè)備配置文件 (HDP) 的支持。 這允許您創(chuàng)建應(yīng)用倔韭,使用藍(lán)牙與支持藍(lán)牙功能的健康設(shè)備進(jìn)行通信术浪,例如心率監(jiān)測(cè)儀、血糖儀寿酌、溫度計(jì)胰苏、臺(tái)秤等等。 有關(guān)支持的設(shè)備列表及其相應(yīng)的設(shè)備數(shù)據(jù)專業(yè)化代碼醇疼,請(qǐng)參閱 www.bluetooth.org 上的藍(lán)牙分配編號(hào)硕并。 請(qǐng)注意,這些值在 ISO/IEEE 11073-20601 [7] 規(guī)范的“命名法規(guī)附錄”中也被稱為 MDC_DEV_SPEC_PROFILE_*秧荆。 有關(guān) HDP 的詳細(xì)討論倔毙,請(qǐng)參閱健康設(shè)備配置文件。
以下是使用配置文件的基本步驟:
- 獲取默認(rèn)適配器(請(qǐng)參閱設(shè)置藍(lán)牙)乙濒。
- 使用 getProfileProxy() 建立到配置文件所關(guān)聯(lián)的配置文件代理對(duì)象的連接陕赃。在以下示例中,配置文件代理對(duì)象是一個(gè) BluetoothHeadset 的實(shí)例颁股。
- 設(shè)置 BluetoothProfile.ServiceListener么库。此偵聽(tīng)程序會(huì)在 BluetoothProfile IPC 客戶端連接到服務(wù)或斷開(kāi)服務(wù)連接時(shí)向其發(fā)送通知。
- 在 onServiceConnected() 中甘有,獲取配置文件代理對(duì)象的句柄诉儒。
- 獲得配置文件代理對(duì)象后,可以立即將其用于監(jiān)視連接狀態(tài)和執(zhí)行其他與該配置文件相關(guān)的操作梧疲。
例如允睹,以下代碼片段顯示了如何連接到 BluetoothHeadset 代理對(duì)象,以便能夠控制耳機(jī)配置文件:
BluetoothHeadset mBluetoothHeadset;
// Get the default adapter
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Establish connection to the proxy.
mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
}
}
public void onServiceDisconnected(int profile) {
if (profile == BluetoothProfile.HEADSET) {
mBluetoothHeadset = null;
}
}
};
// ... call functions on mBluetoothHeadset
// Close proxy connection after use.
mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);
供應(yīng)商特定的 AT 命令
從 Android 3.0 開(kāi)始幌氮,應(yīng)用可以注冊(cè)接收耳機(jī)所發(fā)送的預(yù)定義的供應(yīng)商特定 AT 命令的系統(tǒng)廣播(例如 Plantronics +XEVENT 命令)缭受。 例如,應(yīng)用可以接收指示所連接設(shè)備的電池電量的廣播该互,并根據(jù)需要通知用戶或采取其他操作米者。 為 ACTION_VENDOR_SPECIFIC_HEADSET_EVENT intent 創(chuàng)建廣播接收器,以處理耳機(jī)的供應(yīng)商特定 AT 命令宇智。
健康設(shè)備配置文件
Android 4.0(API 級(jí)別 14)引入了對(duì)藍(lán)牙健康設(shè)備配置文件 (HDP) 的支持蔓搞。 這允許您創(chuàng)建應(yīng)用,使用藍(lán)牙與支持藍(lán)牙功能的健康設(shè)備進(jìn)行通信随橘,例如心率監(jiān)測(cè)儀喂分、血糖儀、溫度計(jì)机蔗、臺(tái)秤等等蒲祈。 Bluetooth Health API 包括類 BluetoothHealth甘萧、BluetoothHealthCallback 和 BluetoothHealthAppConfiguration,在基礎(chǔ)知識(shí)部分介紹了這些類梆掸。
在使用 Bluetooth Health API 時(shí)扬卷,了解以下關(guān)鍵 HDP 概念很有幫助:
概念 | 說(shuō)明 |
---|---|
源設(shè)備 | 在 HDP 中定義的角色。源設(shè)備是將醫(yī)療數(shù)據(jù)傳輸?shù)?Android 手機(jī)或平板電腦等智能設(shè)備的健康設(shè)備(體重秤酸钦、血糖儀怪得、溫度計(jì)等)。 |
匯集設(shè)備 | 在 HDP 中定義的角色卑硫。在 HDP 中徒恋,匯集設(shè)備是接收醫(yī)療數(shù)據(jù)的智能設(shè)備。 在 Android HDP 應(yīng)用中欢伏,匯集設(shè)備表示為 BluetoothHealthAppConfiguration 對(duì)象因谎。 |
注冊(cè) | 指的是注冊(cè)特定健康設(shè)備的匯集設(shè)備。 |
連接 | 指的是開(kāi)放健康設(shè)備與 Android 手機(jī)或平板電腦等智能設(shè)備之間的通道颜懊。 |
創(chuàng)建 HDP 應(yīng)用
以下是創(chuàng)建 Android HDP 應(yīng)用所涉及的基本步驟:
-
獲取 BluetoothHealth 代理對(duì)象的引用。
與常規(guī)耳機(jī)和 A2DP 配置文件設(shè)備相似风皿,您必須使用 BluetoothProfile.ServiceListener 和 HEALTH 配置文件類型來(lái)調(diào)用 getProfileProxy()河爹,以便與配置文件代理對(duì)象建立連接。
創(chuàng)建 BluetoothHealthCallback 并注冊(cè)充當(dāng)健康匯集設(shè)備的應(yīng)用配置 (BluetoothHealthAppConfiguration)桐款。
建立到健康設(shè)備的連接咸这。一些設(shè)備將會(huì)發(fā)起該連接。 對(duì)于這類設(shè)備魔眨,無(wú)需執(zhí)行該步驟媳维。
-
成功連接到健康設(shè)備后,使用文件描述符對(duì)健康設(shè)備執(zhí)行讀/寫操作遏暴。
接收的數(shù)據(jù)需要使用實(shí)現(xiàn)了 IEEE 11073-xxxxx 規(guī)范的健康管理器進(jìn)行解釋侄刽。
完成后,關(guān)閉健康通道并取消注冊(cè)該應(yīng)用朋凉。該通道在長(zhǎng)期閑置時(shí)也會(huì)關(guān)閉州丹。
有關(guān)描述上述步驟的完整代碼示例,請(qǐng)參閱藍(lán)牙 HDP(健康設(shè)備配置文件)杂彭。
以上文章來(lái)自官方文檔