一周霉、前言:
普通藍(lán)牙設(shè)備官方文檔
Android 平臺包含藍(lán)牙網(wǎng)絡(luò)堆棧支持
,憑借此支持逻族,設(shè)備能以無線方式與其他藍(lán)牙設(shè)備交換數(shù)據(jù)掠抬。應(yīng)用框架提供了通過 Android Bluetooth API 訪問藍(lán)牙功能的途徑氮块。使用 Bluetooth API Android 應(yīng)用可以執(zhí)行下面的操作:
- 掃描其他藍(lán)牙設(shè)備
- 查詢本地藍(lán)牙適配器的配對藍(lán)牙設(shè)備
- 建立 RFCOMM 通道
- 通過服務(wù)發(fā)現(xiàn)連接到其他設(shè)備
- 與其他設(shè)備進(jìn)行雙向數(shù)據(jù)傳輸
- 管理多個連接
傳統(tǒng)藍(lán)牙適用于電池使用強(qiáng)度較大的操作,例如 Android 設(shè)備之間的流傳輸和通信等诡宗。針對具有低功耗要求的藍(lán)牙設(shè)備滔蝉,Android 4.3(API 18)中引入了面向低功耗藍(lán)牙的 API 支持。
二塔沃、名詞介紹:
使用 Android Bluetooth API 來完成使用藍(lán)牙進(jìn)行通信的四項(xiàng)主要任務(wù):設(shè)置藍(lán)牙
蝠引、查找局部區(qū)域內(nèi)的配對設(shè)備或可用設(shè)備
、連接設(shè)備
蛀柴,以及在設(shè)備之間傳輸數(shù)據(jù)
立肘。
關(guān)于藍(lán)牙的 API 在 android.bluetooth
包中,下面介紹一下和藍(lán)牙相關(guān)的主要類:
1名扛、BluetoothAdapter
本地藍(lán)牙適配器谅年,是所有
藍(lán)牙交互的入口點(diǎn)
,表示藍(lán)牙設(shè)備自身的一個藍(lán)牙設(shè)備適配器肮韧,整個系統(tǒng)只有一個藍(lán)牙適配器
融蹂。通過它可以發(fā)現(xiàn)其他藍(lán)牙設(shè)備,查詢綁定(配對)設(shè)備的列表弄企,使用已知的 Mac 地址實(shí)例化BluetoothDevice
以及創(chuàng)建BluetoothServerSocket
用來偵聽來自其他設(shè)備的通信超燃。
2、BluetoothDevice
表示遠(yuǎn)程的藍(lán)牙設(shè)備拘领。利用它可以通過
BluetoothSocket
請求與某個遠(yuǎn)程設(shè)備建立連接意乓,或查詢有關(guān)該設(shè)備的信息,例如設(shè)備的名稱约素、地址届良、類和綁定狀態(tài)等。
3圣猎、BluetoothSocket
表示藍(lán)牙套接字接口(與 TCP Socket 相似)士葫。這是允許應(yīng)用通過
InputStream
和OutputStream
與其他藍(lán)牙設(shè)備交換數(shù)據(jù)的節(jié)點(diǎn)。正是利用這個對象來完成藍(lán)牙設(shè)備間的數(shù)據(jù)交換送悔,
4慢显、BluetoothServerSocket
表示用于偵聽傳入請求的開發(fā)服務(wù)器套接字(類似于 TCP ServerSocket)要連接兩臺 Android 設(shè)備,其中一臺設(shè)備必須使用此類開發(fā)的一個服務(wù)器套接字欠啤。當(dāng)一臺遠(yuǎn)程藍(lán)牙設(shè)備向此設(shè)備發(fā)出連接請求時荚藻,
BluetoothServerSocket
將會在接受連接后返回已連接的BluethoothSocket
。
5洁段、BluetoothClass
描述藍(lán)牙設(shè)備的一般特性和功能应狱。這是一組只讀屬性,用于定義設(shè)備的主要和次要設(shè)備類及其服務(wù)眉撵。不過侦香,它不能可靠地描述設(shè)備支持的所有藍(lán)牙配置文件和服務(wù),而是適合作為設(shè)備類型提示纽疟。
6罐韩、BluetoothProfile
表示藍(lán)牙配置文件的接口。藍(lán)牙配置文件是適用于設(shè)備間
藍(lán)牙通信的無線接口規(guī)范
污朽。免提配置文件便是一個示例散吵。如需了解關(guān)于配置文件的詳細(xì)討論,參考下面配置文件的講解
7蟆肆、BluetoothHeadset
提供藍(lán)牙耳機(jī)支持矾睦,以便與手機(jī)配合使用。其中包括藍(lán)牙耳機(jī)和免提(1.5版)配置文件炎功。
BluetoothProfile 的實(shí)現(xiàn)類
8枚冗、BlutoothA2dp
定義
高質(zhì)量音頻
如何通過藍(lán)牙連接和流式傳輸,從一臺設(shè)備傳輸?shù)搅硪慌_設(shè)備蛇损×尬拢“A2DP”代表高級音頻分發(fā)配置文件。是BluetoothProfile的實(shí)現(xiàn)類
9淤齐、BluetoothHealth
表示用于控制藍(lán)牙服務(wù)的健康設(shè)備配置文件代理股囊。
BluetoothProfile 的實(shí)現(xiàn)類。
10更啄、BluetoothGatt
BluetoothProfile 的實(shí)現(xiàn)類
稚疹。與低功耗藍(lán)牙通信有關(guān)的配置文件代理
11、BluetoothHealthCallback
用于實(shí)現(xiàn)
BluetoothHealth
回調(diào)的抽象類祭务。必須擴(kuò)展此類并實(shí)現(xiàn)回調(diào)方法内狗,以接收關(guān)于應(yīng)用注冊狀態(tài)和藍(lán)牙通道狀態(tài)變化的更新內(nèi)容。
12义锥、BluetoothHealthAppConfiguration
表示第三方藍(lán)牙健康應(yīng)用注冊的應(yīng)用配置其屏,以便與遠(yuǎn)程藍(lán)牙健康設(shè)備通信
13、BluetoothProfile.ServiceListener
在 BluetoothProfile IPC
客戶端連接到服務(wù)(即缨该,運(yùn)行特定配置文件的內(nèi)部服務(wù))或斷開服務(wù)連接時向其發(fā)送通知的接口偎行。
三、基本使用:
1贰拿、藍(lán)牙權(quán)限
使用藍(lán)牙必須聲明權(quán)限 BLUETOOTH 才可以執(zhí)行藍(lán)牙通信蛤袒。
<mainifest>
<uses-permission android:name = "android.permission.BLUETOOTH"/>
<!--啟用應(yīng)用啟動設(shè)備發(fā)現(xiàn)或者操作藍(lán)牙設(shè)備的超級管理員-->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
</mainifest>
2、設(shè)置藍(lán)牙
1膨更、獲取藍(lán)牙適配器
所有的藍(lán)牙 Activity 都是需要
BluetoothAdapter
的妙真。獲取BluetoothAdapter
調(diào)用BluetoothAdapter
的靜態(tài)方法getDefaultAdapter()
方法。會返回一個表示設(shè)備自身的藍(lán)牙適配器(藍(lán)牙無線裝置)的 BluetoothAdapter荚守。
整個系統(tǒng)有一個藍(lán)牙適配器珍德,我們的應(yīng)用可以通過 BluetoothAdapter 這個對象與之交互练般。如果 getDefaultAdapter()返回 null 則說明該設(shè)備不支持藍(lán)牙
。
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter == null){
// 說明此設(shè)備不支持藍(lán)牙操作
}
3锈候、啟用藍(lán)牙
需要確認(rèn)是否已經(jīng)開啟藍(lán)牙
isEnabled()
薄料。返回 false 則說明藍(lán)牙處于關(guān)閉狀態(tài)泵琳。請求啟用藍(lán)牙。使用ACTION_REQUEST_ENABLE
操作 Intent 調(diào)用startActivityForResult()
將通過系統(tǒng)設(shè)置發(fā)出啟用藍(lán)牙的請求获列。也可以通過mBluetoothAdapter.enable()
直接打開藍(lán)牙。
// 沒有開始藍(lán)牙
if(!mBluetoothAdapter.isEnabled()){
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,REQUEST_ENBLE_BT);
}
我們的應(yīng)用也可以選擇偵聽
ACTION_STATE_CHANGED
廣播 Intent迫悠。每當(dāng)藍(lán)牙狀態(tài)發(fā)生變化時,系統(tǒng)會廣播此 Intent巩梢。此廣播包含額外字段EXTRA_STATE
和EXTRA_PREVIOUS_STATE
分別表示新的和舊的藍(lán)牙狀態(tài)。
4验烧、查找設(shè)備
使用
BluetoothAdapter
可以通過設(shè)備發(fā)現(xiàn)或通過查詢配對設(shè)備的列表來查找遠(yuǎn)程藍(lán)牙設(shè)備。設(shè)備發(fā)現(xiàn)是一個掃描過程碍拆,它會搜索局部區(qū)域內(nèi)已啟用藍(lán)牙功能的設(shè)備,然后請求一些關(guān)于各臺設(shè)備的信息感混。這個過程也稱為發(fā)現(xiàn)、查詢弧满、掃描。
局部區(qū)域內(nèi)的藍(lán)牙設(shè)備僅在其當(dāng)前已啟用可檢測性時才會響應(yīng)發(fā)現(xiàn)請求
庭呜。如果設(shè)備可以檢測到,它將通過共享一些信息(例如設(shè)備名稱募谎、類及其唯一MAC地址)來響應(yīng)發(fā)現(xiàn)請求。利用此信息阴汇,執(zhí)行發(fā)現(xiàn)的設(shè)備可以選擇發(fā)起到被發(fā)現(xiàn)設(shè)備的連接。在首次與遠(yuǎn)程設(shè)備建立連接后搀庶,將會自動向用戶顯示配對請求铜异。設(shè)備完成配對后秸架,將會保存關(guān)于該設(shè)備的基本信息(如 設(shè)備名稱、MAC 地址)咕宿。并且可以使用 Bluetooth API 讀取這些信息蜡秽。利用遠(yuǎn)程設(shè)備的已知 Mac 地址可以隨時向其發(fā)起連接,而不需執(zhí)行發(fā)現(xiàn)操作(假定該設(shè)備處于有效范圍內(nèi))
被配對和被連接之間存在差別芽突。被配對意味著兩臺設(shè)備知曉彼此的存在,具有可用于身份驗(yàn)證的共享鏈路密鑰寞蚌,并且能夠與彼此建立加密連接
。被連接意味著設(shè)備當(dāng)前共享一個 RFCOMM 通道壹哺,并且能夠向彼此傳輸數(shù)據(jù)。當(dāng)前的 Android Bluetooth API 要求對設(shè)備進(jìn)行配對管宵,然后才能建立 RFCOMM 連接(在使用 Bluetooth API 發(fā)起加密連接時,會自動執(zhí)行配對)箩朴。Android 設(shè)備是默認(rèn)處于不可檢測狀態(tài)的。
5炸庞、查詢配對的設(shè)備
在執(zhí)行設(shè)備發(fā)現(xiàn)之前,有必要查詢已配對的設(shè)備集合埠居。用來了解設(shè)備是否處于已知狀態(tài)。通過
getBondedDevices()
來實(shí)現(xiàn)拐格,這將返回表示已配對設(shè)備的一組BluetoothDevice
。
例如:我們可以查詢所有已配對的設(shè)備捏浊,然后使用 ArrayAdapter 向用戶顯示每臺設(shè)備的名稱:
Set<BluetoothDevice> pairedDevices = mBlutooothAdapter.getBondedDevices();
if(pairedDevices.size() > 0){
for(BluetoothDevice device:pairedDevices){
// 把名字和地址取出來添加到適配器中
mArrayAdapter.add(device.getName()+"\n"+ device.getAddress());
}
}
要發(fā)起連接僅需要知道目標(biāo)藍(lán)牙設(shè)備的 Mac 地址就可以了。
6金踪、發(fā)現(xiàn)設(shè)備
發(fā)現(xiàn)設(shè)備使用
startDiscovery()
該進(jìn)程為異步進(jìn)程浊洞。該方法會立刻返回一個布爾值法希,指示是否已成功啟動發(fā)現(xiàn)操作。發(fā)現(xiàn)進(jìn)程通常包含約 12 秒的查詢掃描苫亦,之后對發(fā)現(xiàn)的設(shè)備進(jìn)行掃描,以檢索其藍(lán)牙設(shè)備的名字屋剑。
我們的應(yīng)用必須針對
ACTION_FOUND
Intent 注冊一個 BroadcastReceiver,以便接受每臺發(fā)現(xiàn)的設(shè)備的信息唉匾。針對每臺設(shè)備,系統(tǒng)會廣播ACTION_FOUND
Intent巍膘。這個 Intent 會攜帶額外的字段EXTRA_DEVICE 和 EXTRA_CLASS
。這兩者分別包含BluetoothDevice 和 BluetoothClass
峡懈。
// 創(chuàng)建一個接受 ACTION_FOUND 的 BroadcastReceiver
private final BroadcastReceiver mReceiver = new BroadcastReceiver(){
public void onReceive(Context context,Intent intent){
String action = intent.getAction();
// 當(dāng) Discovery 發(fā)現(xiàn)了一個設(shè)備
if(BluetoothDevice.ACTION_FOUND.equals(action)){
// 從 Intent 中獲取發(fā)現(xiàn)的 BluetoothDevice
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 將名字和地址放入要顯示的適配器中
mArrayAdapter.add(device.getName + "\n" + device.getAddress());
}
}
};
// 注冊這個 BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReiver,filter);
// 在 onDestroy 中 unRegister
注意 執(zhí)行 discovery 對于藍(lán)牙適配器來說是一個非常繁重的過程与斤,并且會消耗大量資源。在找到要連接的設(shè)備后幽告,要確保使用 cancelDiscovery() 來停止發(fā)現(xiàn),然后嘗試連接
冗锁。如果您已經(jīng)和某臺設(shè)備進(jìn)行連接,那么這個時候執(zhí)行發(fā)現(xiàn)操作會大幅度的減少此連接可用的帶寬冻河!因此不應(yīng)該在處于連接狀態(tài)的時候執(zhí)行發(fā)現(xiàn)操作!
7叨叙、啟用可檢測性
如果我們希望我們的設(shè)備是可以被其他設(shè)備檢測到的,可以使用
ACTION_REQUEST_DISCOVERABLE
來操作 Intent 調(diào)用startActivityForResult(Intent,int)
擂错。這樣會通過系統(tǒng)設(shè)置發(fā)出啟用可檢測到模式的請求(無需停止我們的應(yīng)用)。默認(rèn)情況下,設(shè)備會變?yōu)榭蓹z測狀態(tài)并且持續(xù) 120 秒鐘昨凡。我們還可以通過EXTRA_DISCOVERABLE_DURATION
Intent Extra
來定義不同的持續(xù)時間。可以設(shè)置的最大持續(xù)時間為 3600 秒便脊。值為 0 表示始終可以被檢測到。任何小于 0 或者大于 3600 的值都會自動設(shè)置為 120 秒鐘哪痰。
例如:
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);
startActivityForResult(discoverableIntent);
將顯示對話框,請求用戶允許將設(shè)備設(shè)為可檢測到晌杰。如果用戶響應(yīng)為 YES,則設(shè)備將變?yōu)榭蓹z測到并持續(xù)指定的時間量乎莉。然后您的 Activity 將會收到對 onActivityResult() 回調(diào)的調(diào)用送讲,其結(jié)果代碼等于設(shè)備可檢測到的持續(xù)時間。如果用戶響應(yīng) NO 或者出現(xiàn)錯誤哼鬓,結(jié)果代碼為 RESULT_CANCELED
如果設(shè)備沒有打開藍(lán)牙,則啟用設(shè)備可檢測性的時候會自動啟用藍(lán)牙异希。
設(shè)備將在分配的時間內(nèi)以靜默方式保持可檢測到模式。如果我們希望在可檢測到模式發(fā)生變化時收到通知称簿,可以利用
ACTION_SCAN_MODE_CHANGED
Intent 注冊 BroadcastReceiver。它將包含額外字段 EXTRA_SCAN_MODE 和 EXTRA_PREVIOUS_SCAN_MODE,兩者分別告訴我們新的和舊的掃描模式憨降。每個字段可能包括SCAN_MODE_CONNECTABLE_DISCOVERABLE(可檢測到模式)、SCAN_MODE_CONNECTABLE(未處于可檢測模式但可以接受連接)授药、SCAN_MODE_NOE(未處于可檢測到模式并且無法連接)
8、連接設(shè)備
要在兩臺設(shè)備上的應(yīng)用之間創(chuàng)建連接悔叽,必須同時實(shí)現(xiàn)服務(wù)端和客戶端機(jī)制,因?yàn)槠渲幸慌_設(shè)備必須開放服務(wù)器套接字笨蚁,而另一臺設(shè)備必須發(fā)起連接(使用服務(wù)器設(shè)備的
MAC
地址發(fā)起連接)。當(dāng)服務(wù)器和客戶端在同一RFCOMM
通道上分別擁有已連接的 BluetoothSocket 時赚窃,二者將被視為彼此連接。在這種情況下每臺設(shè)備都能獲得輸入和輸出流式傳輸勒极,并且可以開始傳輸數(shù)據(jù)。
服務(wù)端和客戶端分別以不同的方式來獲得
BluetoothSocket
辱匿。服務(wù)器將在傳入連接被接受時收到套接字∝移撸客戶端將在其打開到服務(wù)器的RFCOMM
通道時收到該套接字。
一種實(shí)現(xiàn)方式是自動將每臺設(shè)備準(zhǔn)備為一個服務(wù)器昨忆,從而使每臺設(shè)備開發(fā)一個服務(wù)器套接字并偵聽連接。然后任一設(shè)備可以發(fā)起與另一臺設(shè)備的連接邑贴,并成為客戶端÷<荩或者其中一臺設(shè)備可顯示“托管”連接并按需開放一個服務(wù)器套接字,從而另一臺設(shè)備則直接發(fā)起連接繁疤。
在連接之前如果兩個設(shè)備沒有配對,則系統(tǒng)會自動發(fā)出配對請求稠腊。
9、連接為服務(wù)器
當(dāng)連接兩臺設(shè)備時架忌,其中一臺必須保持開發(fā)的
BluetoothServerSocket
來充當(dāng)服務(wù)器,用于監(jiān)聽傳入的連接請求鳖昌,在接受了請求后提供一個已經(jīng)連接的BluetoothSocket
。從BluetoothServerSocket
連接獲取BluetoothSocket
后就可以調(diào)用 close 來關(guān)閉這個等待了许昨。
10、關(guān)于 UUID
通用唯一標(biāo)識符(UUID)糕档,用于表示唯一標(biāo)識信息的字符串ID拌喉,128位∧虮常可以使用網(wǎng)絡(luò)上眾多的隨機(jī) UUID 生成器,然后通過
formString(String)
來初始化一個 UUID田藐。
服務(wù)器套接字接受連接的基本過程
- 通過
listenUsingRfcommWithServiceRecord(String,UUID)獲取 BluetoothServerSocket
字符串是我們自己定義的服務(wù)的可識別名稱,可以直接使用包名汽久。系統(tǒng)會自定將其寫入到設(shè)備上的新服務(wù)發(fā)現(xiàn)協(xié)議(SDP)數(shù)據(jù)庫條目中。UUID 也在 SDP 中景醇,作為與客戶端設(shè)備連接協(xié)議的匹配規(guī)則。只有客戶端和這里的UUID 一樣了才可以會被連接
-
accept()
偵聽連接請求
阻塞調(diào)用三痰,將在連接被接受或者發(fā)生異常的時候返回,操作成功后散劫,會返回
BluetoothSocket
。
- 除非要接受更多的連接舷丹,否則調(diào)用
close()
來關(guān)閉這個監(jiān)聽
這樣會釋放服務(wù)器套接字及其所有資源抒钱,但不會關(guān)閉已經(jīng)連接的 BluetoothSocket。與 TCP/IP 不同的是谋币,RFCOMM 一次只允許每個通道有一個已經(jīng)連接的客戶端。
放在子線程中去執(zhí)行蕾额。
例子:
private class AcceptThread extend Thread{
private final BluetoothServerSocket mServerSocket;
public AcceptThread(){
mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME,MY_UUID);
}
public void run(){
BluetoothSocket socket = null;
while(true){
socket = mServerSocket.accept();
if(socket!=null){
// 自定義方法
manageConnectedSocket(socket);
mServerSocket.close();
break;
}
}
}
public void cancle(){
mServerSocket.close();
}
}
11、連接為客戶端
要想和保持開發(fā)服務(wù)器套接字的設(shè)備建立連接退个,必須首先要獲取該設(shè)備的 BluetoothDevice 對象。然后使用這個對象來獲取 BluetoothSocket 并發(fā)起連接语盈。
客戶端連接的基本過程
通過 BluetoothDevice的createRfcommSocketToServiceRecord(UUID) 獲取 BluetoothSocket 對象,這里的 UUID 要和服務(wù)器端的一致
通過 connect() 發(fā)起連接
執(zhí)行此方法后刀荒,系統(tǒng)將會在遠(yuǎn)程設(shè)備上執(zhí)行 SDP 查找,來匹配 UUID缠借。如果查找成功了并且遠(yuǎn)程設(shè)備接受了該連接,它將共享 RFCOMM 通道在連接期間使用泼返。這個時候 connect() 就會返回。這個方法也是阻塞的绅喉,如果失敗或者超時(12秒之后),將引發(fā)異常霹疫。
調(diào)用 connect() 的時候要確保客戶端沒有執(zhí)行發(fā)現(xiàn)操作丽蝎。如果執(zhí)行了會大幅度降低連接的速度,增加失敗的可能屠阻。
例子
private class ConnectThread extend Thread{
private BluetoothDevice mDevice;
private BluetoothSocket mSocket;
public ConnectThread(BluetoothDevice device){
mDevice = device;
// 這里的 UUID 需要和服務(wù)器的一致
mSocket = device.createRfcommSocketToServiceRecord(My_UUID);
}
public void run(){
// 關(guān)閉發(fā)現(xiàn)設(shè)備
mBluetoothAdapter.cancelDiscovery();
try{
mSocket.connect();
}catch(IOException connectException){
try{
mSocket.close();
}catch(IOException closeException){
return;
}
}
// 自定義方法
manageConnectedSocket(mmSocket);
}
public void cancle(){
try{
mSocket.close();
}catch(IOException closeException){
}
}
}
在連接之前調(diào)用 cancleDiscovery()
在進(jìn)行連接之前應(yīng)該始終調(diào)用這個方法,而且調(diào)用的時候無需檢測是否正在掃描国觉。
12、管理連接
建立連接后的兩個設(shè)備都有一個
BluetoothSocket
通過這個 Socket 就可以在這兩個設(shè)備間傳輸數(shù)據(jù)了麻诀。
過程:
- 獲取 InputStream 和 OutputStream
- 使用 read(byte[])和 write(byte [])讀取或者寫入流式傳輸
13、使用配置文件
從 Android 3.0 開始蝇闭, Bluetooth API 便支持使用藍(lán)牙配置文件。藍(lán)牙配置文件是適用于設(shè)備間藍(lán)牙通信的無線接口規(guī)范呻引。
1、藍(lán)牙配置文件就是設(shè)備間通信(藍(lán)牙設(shè)備)的一種規(guī)范
免提配置文件便是一個示例逻悠,對于連接到無線耳機(jī)的手機(jī),兩臺設(shè)備都必須支持免提配置文件童谒。我們也可以通過實(shí)現(xiàn)接口 BluetoothProfile
來寫入自己的類來支持特定的藍(lán)牙配置文件。Android API 提供了以下的幾種藍(lán)牙配置文件的實(shí)現(xiàn):
耳機(jī)
:耳機(jī)配置文件提供了藍(lán)牙耳機(jī)的支持惠啄。也就是這個配置文件提供了手機(jī)和藍(lán)牙耳機(jī)進(jìn)行通信的一種規(guī)范任内。使用BluetoothHeadset
類,用于進(jìn)程間通信來控制藍(lán)牙耳機(jī)服務(wù)的代理死嗦。這個類包含 AT 命令支持。A2DP
: 高級音頻分發(fā)配置文件(A2DP)越除。定義了高質(zhì)量音頻如何通過藍(lán)牙連接和流式傳輸,從一個設(shè)備傳輸?shù)搅硪粋€設(shè)備摘盆。BluetoothAdp
類,是用于通過進(jìn)程間通信(IPC)來控制藍(lán)牙 A2DP 服務(wù)的代理孩擂。健康設(shè)備
: Android 4.0(API 14)引入了對藍(lán)牙健康設(shè)備配置文件(HDP)的支持。這樣就允許我們創(chuàng)建的應(yīng)用可以使用藍(lán)牙與支持藍(lán)牙功能的健康設(shè)備進(jìn)行通信类垦。(心率檢測儀、血糖儀蚤认、溫度計等等)。詳解的配置要查看健康設(shè)備配置文件糕伐。
2、使用配置文件的基本步驟
- 獲取默認(rèn)適配器 BluetoothAdapter
- 使用
getProfileProxy()
良瞧,建立到配置文件所關(guān)聯(lián)的配置文件代理對象的連接。 - 設(shè)置監(jiān)聽
BluetoothProfile.ServiceListener
莺褒。這個監(jiān)聽會在客戶端連接到服務(wù)或者斷開服務(wù)連接的時候發(fā)送通知雪情。 - 在
onServiceConnected()
中獲取配置文件代理對象的句柄。 - 獲取配置文件代理對象后巡通,可以里脊將其用于監(jiān)聽連接狀態(tài)和執(zhí)行其他與該配置文件相關(guān)的操作。
3宴凉、例子: 如何連接到 BluetoothHeadset 代理對象,以便能夠控制耳機(jī)配置文件:
BluetoothHeadset mBluetoothHeadset;
// 獲取默認(rèn)藍(lán)牙適配器
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 設(shè)置監(jiān)聽(監(jiān)聽連接狀態(tài))
private BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener(){
public void onServiceConnected(int profile,BluetoothProfile proxy){
if(profile == BluetoothProfile.HEADSET){
mBluetoothHeadset = (BluetoothHeadset)
}
}
public void onServiceDisconnected(int profile){
if(profile == BluetoothProfile.HEADSET){
mBluetoothHeadset = null;
}
}
}
// 建立與配置文件代理的連接
mBluetoothAdapter.getProfileProxy(contenxt,mProfileListener,BluetoothProfile.HEADSET);
// 使用 mBluetoothHeadset 代理內(nèi)部的方法
// 使用完畢后關(guān)閉
mBluetoothAdapter.closeProfileProxy(mBluetoothHeadset);
14弥锄、供應(yīng)商特定的 AT 命令
從 Android 3.0 開始蟆沫。應(yīng)用可以注冊接受耳機(jī)所發(fā)送的預(yù)定義的供應(yīng)商特定 AT 命令的系統(tǒng)廣播(例如 Plantronics +XEVENT命令)(也就是說我們的應(yīng)用可以接受耳機(jī)藍(lán)牙商預(yù)定義的命令)温治。如:應(yīng)用可以接受指示所連接設(shè)備的電池電量的廣播,并根據(jù)需要通知用戶或采取其他操作熬荆。使用
ACTION_VENDOR_SPECIFIC_HEADSET_EVENT
intent 創(chuàng)建廣播接收器,用來處理耳機(jī)供應(yīng)商特定的 AT 命令卤恳。
15、健康設(shè)備配置文件
Android 4.0 引入了對藍(lán)牙健康設(shè)備配置文件(HDP)的支持突琳。這可以使用我們的應(yīng)用使用藍(lán)牙與支持藍(lán)牙功能的健康設(shè)備進(jìn)行通信(心率檢測儀、血糖儀拆融、溫度計拆座、臺秤)
創(chuàng)建 HDP 應(yīng)用:
- 獲取 BluetoothHealth 代理對象
與常規(guī)耳機(jī)和 A2DP 類似挪凑。使用 ServiceListener 和 HEALTH 配置文件類型參數(shù)來調(diào)用 getProfileProxy(),來和配置文件代理對象建立連接躏碳。 - 創(chuàng)建 BluetoothHealthCallback 并注冊充當(dāng)健康匯集設(shè)備的應(yīng)用配置(BluetoothHealthAPPConfiguration)
- 建立到健康設(shè)備的連接
- 成功連接到健康設(shè)備后,使用文件描述符對健康設(shè)備執(zhí)行讀寫操作
- 完成后菇绵,關(guān)閉健康通道并取消注冊該應(yīng)用,該通道長時間閑置也會關(guān)閉镇眷。
四、總結(jié):
關(guān)于普通藍(lán)牙設(shè)備和普通藍(lán)牙設(shè)備之間的連接通信
- 通過 BluetoothAdapter 的 getDefaultAdapter 方法獲取系統(tǒng)唯一的藍(lán)牙適配器(如果返回為 null 則說明此設(shè)備不支持藍(lán)牙)
- 通過 BluetoothAdapter 的 isEnable 方法判斷是否已經(jīng)打開藍(lán)牙
- 可以通過 BluetoothAdapter.ACTION_REQUEST_ENABLE intent 來開啟藍(lán)牙欠动,也可以直接 .enable 開啟藍(lán)牙
- 通過 調(diào)用 startDiscovery 開啟發(fā)現(xiàn)周邊設(shè)備(持續(xù) 12 秒),這個時候需要注冊廣播接收器來接受發(fā)現(xiàn)的藍(lán)牙設(shè)備(及時關(guān)閉這個操作)
- 通過 BluetoothDevice 就可以進(jìn)行建立連接具伍,(分為客戶端和服務(wù)端類似于 Socket 連接)
- 然后建立連接后就可以通過 BluetoothSocket獲取里面的流來進(jìn)行讀寫通信
關(guān)于藍(lán)牙設(shè)備和藍(lán)牙儀器(藍(lán)牙耳機(jī)、電子秤等等類似產(chǎn)品)
這種之間的通信是通過配置文件代理來實(shí)現(xiàn)的人芽。
都有一個對應(yīng)的配置文件代理類。具體的操作是通過這個對象來完成萤厅。