[Android] Android 操作 Bluetooth(一)——藍(lán)牙2.3等

[TOC]

0x00 藍(lán)牙(Bluetooth)

這個(gè)小硬件已經(jīng)是 android 機(jī)器的標(biāo)配了磷仰,由于平時(shí)不怎么用嘱巾,因此到現(xiàn)在都沒(méi)有去研究過(guò)÷帽。現(xiàn)在有一個(gè)簡(jiǎn)單的小需求:通過(guò)藍(lán)牙連接一個(gè)串口設(shè)備讀取其上面的數(shù)據(jù)蚜退,遂寫(xiě)此文恢总。

最終效果:從已配對(duì)的設(shè)備列表中選擇我們的串口藍(lán)牙設(shè)備(從),連接巢掺,然后讀取數(shù)據(jù)句伶。

0x01 簡(jiǎn)單使用

藍(lán)牙設(shè)備的詳細(xì)使用,可以參考Android關(guān)于藍(lán)牙的官方文檔陆淀。如果你和我一樣考余,之前沒(méi)有研究過(guò)藍(lán)牙,估計(jì)看到最后也會(huì)有一堆問(wèn)題存在:什么主設(shè)備轧苫、從設(shè)備楚堤、UUID是干嘛的,如何免密要配對(duì)等等含懊。不著急身冬,我們慢慢來(lái)。

上面已經(jīng)說(shuō)到岔乔,我們的設(shè)備已經(jīng)提前配對(duì)完成(怎么配對(duì):網(wǎng)絡(luò)設(shè)置中中找到藍(lán)牙酥筝,然后搜索,找到你的設(shè)備雏门,然后配對(duì)嘿歌。這個(gè)時(shí)候可能會(huì)提示輸入密碼,默認(rèn)密碼比如0000茁影,1234等)宙帝。我們只需要連接即可。下面簡(jiǎn)述操作步驟:

  1. 添加藍(lán)牙權(quán)限

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    
  2. 判斷是否支持藍(lán)牙

    private void initBluetooth() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (null == mBluetoothAdapter) {
            tvContent.setText("BluetoothAdapter is null");
            return;
        }
        if (!mBluetoothAdapter.isEnabled()) {
            tvContent.setText("BluetoothAdapter is disable, please open it");
    
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, REQUEST_ENABLE_BT);
        }
    
        tvContent.setText("Bluetooth init success");
    }
    

    首先是判斷是否有藍(lán)牙適配器募闲,如果沒(méi)有步脓,BluetoothAdapter.getDefaultAdapter() 返回 null。然后判斷藍(lán)牙設(shè)備是否啟用 mBluetoothAdapter.isEnabled() 浩螺,如果未啟用靴患,則發(fā)送一個(gè) Intent 來(lái)讓用戶啟用藍(lán)牙,這個(gè) Intent 是系統(tǒng)的年扩,我們?cè)?onActivityResult 中處理用戶操作結(jié)果蚁廓,如果用戶順利開(kāi)啟藍(lán)牙访圃,則會(huì)返回 RESULT_OK厨幻。

  3. 獲取設(shè)備列表

    Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    if (null != pairedDevices && pairedDevices.size() > 0) {
      for (BluetoothDevice device : pairedDevices) {
          ......
          String msg = String.format("%s %s\n", device.getName(), device.getAddress());
          ......
      }
    }
    

    這個(gè)時(shí)候我們可以拿到 BluetoothDevice ,這個(gè)對(duì)象中保存了已配對(duì)藍(lán)牙設(shè)備的信息,比如名稱(chēng)况脆,MAC地址饭宾,狀態(tài),UUID等信息格了,我們需要保存下來(lái)看铆,在接下來(lái)的連接時(shí)候會(huì)使用。

  4. 連接設(shè)備

    有了 BluetoothDevice 信息盛末,我們就可以連接這個(gè)已經(jīng)配對(duì)的藍(lán)牙設(shè)備了弹惦。

    public static final UUID DEFAULT_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
    
    try {
       if(null == mSocket){
           mSocket = mDevice.createRfcommSocketToServiceRecord(DEFAULT_UUID);
       }
       mSocket.connect(); // 阻塞的
    
       mIn = mSocket.getInputStream();
    } catch (IOException e) {
       e.printStackTrace();
       return false;
    }
    

    連接成功后,我們會(huì)得到一個(gè) BluetoothSocket 對(duì)象悄但,然后調(diào)用其阻塞的 connect() 方法棠隐,等待兩臺(tái)設(shè)備連接成功(所以這個(gè)時(shí)候必須在另外一個(gè)線程中進(jìn)行)。當(dāng)兩臺(tái)設(shè)備連接成功之后會(huì)繼續(xù)向下執(zhí)行檐嚣。

  5. 讀取數(shù)據(jù)

    連接成功之后助泽,我們可以通過(guò) mSocket.getInputStream() 獲得一個(gè)輸入流,結(jié)下來(lái)的操作就是流的操作了嚎京,這個(gè)和普通 socket 中輸入輸出流的操作一樣了嗡贺。

    try {
       mBytes = mIn.read(readBuffer);
       System.arraycopy(readBuffer, 0, tempBuffer, mCount, mBytes);
       mCount += mBytes;
       if (mCount >= SIZE) {
           parseData(tempBuffer);
           mCount = 0;
       }
    } catch (IOException e) {
       e.printStackTrace();
    }
    

0x02 總結(jié)

Android藍(lán)牙(主從)的操作:

  • 檢查是否支持,是否啟用(包括是否可見(jiàn)等)
  • 掃描設(shè)備
  • 配對(duì)
  • 連接
  • 數(shù)據(jù)交換
  • 等等

這里只講了檢查部分操作鞍帝,涉及的掃描與配對(duì)可能是更復(fù)雜一些的诫睬,在接下來(lái)講述。

最后帕涌,項(xiàng)目代碼可參考這里github/ttdevs/air岩臣。

0x03 簡(jiǎn)單分享一個(gè)java線程的封裝:

/**
 * Created by ttdevs
 * 2017-01-22 (android)
 * https://github.com/ttdevs
 */
public abstract class BaseWorkerThread extends Thread {

    private boolean isRunning = true;

    @Override
    public void run() {
        super.run();
        isRunning = workerBefore();

        while (isRunning) {
            workerCycle();
        }

        workerAfter();
    }

    /**
     * 提前執(zhí)行 true: 繼續(xù) false: 結(jié)束
     *
     * @return
     */
    public boolean workerBefore() {
        return true;
    }

    /**
     * 工作方法,被循環(huán)調(diào)用
     *
     * @return true: 繼續(xù) false: 結(jié)束
     */
    public abstract void workerCycle();


    /**
     * 結(jié)束執(zhí)行
     */
    public void workerAfter() {

    }

    /**
     * 開(kāi)始線程
     */
    public void startThread() {
        isRunning = true;
        try {
            start();
        } catch (Exception e) {
            e.printStackTrace();
            isRunning = false;
        }
    }

    /**
     * 結(jié)束線程
     */
    public void stopThread() {
        isRunning = false;
    }
}

參考

https://developer.android.google.cn/guide/topics/connectivity/bluetooth.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宵膨,一起剝皮案震驚了整個(gè)濱河市架谎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辟躏,老刑警劉巖谷扣,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異捎琐,居然都是意外死亡会涎,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén)瑞凑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)末秃,“玉大人,你說(shuō)我怎么就攤上這事籽御×纺剑” “怎么了惰匙?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)铃将。 經(jīng)常有香客問(wèn)我项鬼,道長(zhǎng),這世上最難降的妖魔是什么劲阎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任绘盟,我火速辦了婚禮,結(jié)果婚禮上悯仙,老公的妹妹穿的比我還像新娘龄毡。我一直安慰自己,他們只是感情好锡垄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布稚虎。 她就那樣靜靜地躺著,像睡著了一般偎捎。 火紅的嫁衣襯著肌膚如雪蠢终。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,301評(píng)論 1 301
  • 那天茴她,我揣著相機(jī)與錄音寻拂,去河邊找鬼。 笑死丈牢,一個(gè)胖子當(dāng)著我的面吹牛祭钉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播己沛,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼慌核,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了申尼?” 一聲冷哼從身側(cè)響起垮卓,我...
    開(kāi)封第一講書(shū)人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎师幕,沒(méi)想到半個(gè)月后粟按,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡霹粥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年灭将,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片后控。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庙曙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浩淘,到底是詐尸還是另有隱情捌朴,我是刑警寧澤吴攒,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站男旗,受9級(jí)特大地震影響舶斧,放射性物質(zhì)發(fā)生泄漏欣鳖。R本人自食惡果不足惜察皇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泽台。 院中可真熱鬧什荣,春花似錦、人聲如沸怀酷。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蜕依。三九已至桅锄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間样眠,已是汗流浹背友瘤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留檐束,地道東北人辫秧。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像被丧,于是被迫代替她去往敵國(guó)和親盟戏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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