Android 藍(lán)牙開發(fā)(一)

一周霉、前言:

普通藍(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)用通過 InputStreamOutputStream 與其他藍(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_STATEEXTRA_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_DURATIONIntent 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)的配置文件代理類。具體的操作是通過這個對象來完成萤厅。


參考:https://mp.weixin.qq.com/s?__biz=MzU5NzA2NjQzMg==&mid=2247484128&idx=1&sn=9d59b9ad66fb68b9569c29566103c009&scene=21#wechat_redirect

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末靴迫,一起剝皮案震驚了整個濱河市楼誓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌慌随,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阁猜,死亡現(xiàn)場離奇詭異,居然都是意外死亡剃袍,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門民效,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人畏邢,你說我怎么就攤上這事∈嫖” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵臂寝,是天一觀的道長。 經(jīng)常有香客問我咆贬,道長,這世上最難降的妖魔是什么掏缎? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮御毅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘端蛆。我一直安慰自己,他們只是感情好今豆,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布嫌拣。 她就那樣靜靜地躺著呆躲,像睡著了一般。 火紅的嫁衣襯著肌膚如雪插掂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天辅甥,我揣著相機(jī)與錄音,去河邊找鬼璃弄。 笑死,一個胖子當(dāng)著我的面吹牛夏块,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播脐供,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼政己!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起匹颤,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎印蓖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赦肃,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年他宛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厅各。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖队塘,靈堂內(nèi)的尸體忽然破棺而出宜鸯,到底是詐尸還是另有隱情,我是刑警寧澤遮怜,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站锯梁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏陌凳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一冯遂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蛤肌,春花似錦、人聲如沸裸准。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至权悟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間峦阁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工榔昔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人撒会。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像诵肛,于是被迫代替她去往敵國和親屹培。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 最近項(xiàng)目使用藍(lán)牙壁顶,之前并沒有接觸溜歪,還是發(fā)現(xiàn)了很多坑,查閱了很多資料许蓖,說的迷迷糊糊,今天特查看官方文檔膊爪。 說下遇到的...
    King9527閱讀 1,788評論 0 1
  • 普通藍(lán)牙設(shè)備官方文檔 Android 平臺包含藍(lán)牙網(wǎng)絡(luò)堆棧支持,憑借此支持米酬,設(shè)備能以無線方式與其他藍(lán)牙設(shè)備交換數(shù)據(jù)...
    sydMobile閱讀 69,439評論 5 43
  • 藍(lán)牙 注:本文翻譯自https://developer.android.com/guide/topics/conn...
    RxCode閱讀 8,645評論 11 99
  • Android平臺支持藍(lán)牙網(wǎng)絡(luò)協(xié)議棧,實(shí)現(xiàn)藍(lán)牙設(shè)備之間數(shù)據(jù)的無線傳輸赃额。本文檔描述了怎樣利用android平臺提供的...
    Camming閱讀 3,300評論 0 3
  • 本文主要介紹Android藍(lán)牙開發(fā)中基礎(chǔ)知識:藍(lán)牙模塊及核心API。關(guān)于藍(lán)牙的連接及通訊功能實(shí)現(xiàn)跳芳,歡迎查閱下一篇文...
    幾圈年輪閱讀 5,001評論 0 10