藍(lán)牙(BLE)自動(dòng)配對(duì)、發(fā)現(xiàn)服務(wù)

作為菜鳥鳞绕,記錄下今年藍(lán)牙入坑1年的一些問題,方便回顧尸曼;

藍(lán)牙的相應(yīng)api就不貼了们何;
要實(shí)現(xiàn)自動(dòng)配對(duì)先注冊(cè)廣播:
/**
* 搜索BroadcastReceiver
*/
private final BroadcastReceiver searchDevices = new BroadcastReceiver() {
@SuppressLint("NewApi")
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
BluetoothDevice device = null;
// 搜索設(shè)備時(shí),取得設(shè)備的MAC地址
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() == BluetoothDevice.BOND_NONE) {
String str = " 未配對(duì)|" + device.getName() + "|"
+ device.getAddress();
LogUtils.e(str);
}
} else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
LogUtils.e("action:" + action);
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
switch (device.getBondState()) {
case BluetoothDevice.BOND_BONDING:
LogUtils.e(TAG, "正在配對(duì)......");
break;
case BluetoothDevice.BOND_BONDED:
LogUtils.e(TAG, "配對(duì)成功控轿!");
break;
case BluetoothDevice.BOND_NONE:
LogUtils.e(TAG, "取消配對(duì)");
default:
break;
}
} else if (intent.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
LogUtils.e("action:" + action);
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//1.確認(rèn)配對(duì)
device.setPin(strPsw.getBytes());
//如果沒有將廣播終止冤竹,則會(huì)出現(xiàn)一個(gè)一閃而過的配對(duì)框拂封。
abortBroadcast();
}
}
}
};
配對(duì):之前沒接觸藍(lán)牙相關(guān)api的時(shí)候,也是學(xué)網(wǎng)上的api用反射區(qū)實(shí)現(xiàn)鹦蠕;后來谷歌爸爸在9.0限制了不能使用反射獲取隱藏api(親測(cè)冒签,兩部p20,8.0可以配對(duì)钟病,9.0無法配對(duì))萧恕,這個(gè)反射實(shí)現(xiàn)的自動(dòng)陪對(duì)也就尷尬了。后面看api肠阱,發(fā)現(xiàn)可以直接使用票唆;
在掃描到設(shè)備后連接,根據(jù) BluetoothDevice.getBondState() == BluetoothDevice.BOND_NONE
判斷是否已經(jīng)配對(duì)屹徘,沒有配對(duì)調(diào)用BluetoothDevice.createBond()之后在廣播中監(jiān)聽走趋,在監(jiān)聽到BluetoothDevice.ACTION_PAIRING_REQUEST后調(diào)用 device.setPin(strPsw.getBytes());將PIN碼設(shè)置進(jìn)去,好了就是這么簡(jiǎn)單噪伊,目前我在華為p20簿煌、榮耀8等幾部手機(jī)上都測(cè)試沒問題。后續(xù)再多試幾部手機(jī)鉴吹。

發(fā)現(xiàn)服務(wù):藍(lán)牙連接后在BluetoothGattCallback接口回調(diào)方法onConnectionStateChange(BluetoothGatt gatt, int status, int newState)中調(diào)用gatt.discoverServices()發(fā)現(xiàn)服務(wù)姨伟,這個(gè)地方有坑。有時(shí)候發(fā)現(xiàn)服務(wù)不了(個(gè)人認(rèn)為因?yàn)檫@些回調(diào)都是在異步線程豆励,異步嘛就是得看看什么時(shí)候有空了就執(zhí)行)授滓。換了個(gè)辦法就是gatt不拿onConnectionStateChange回調(diào)回來的,直接用BluetoothGatt mBluetoothGatt=BluetoothDevice.connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback)連接時(shí)候的mBluetoothGatt.discoverServices()發(fā)現(xiàn)服務(wù)肆糕,在onConnectionStateChange回調(diào)后在主線程中調(diào)mBluetoothGatt.discoverServices()般堆;我目前試的基本都能成功。
切到主線程我是用的 handler诚啃。
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
Message message = mainHandler.obtainMessage();
message.what = BleMsg.MSG_DISCOVER_SERVICES;
mainHandler.sendMessage(message);
}
}
private MainHandler mainHandler = new MainHandler(Looper.getMainLooper());
private final class MainHandler extends Handler {

    MainHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case BleMsg.MSG_DISCOVER_SERVICES: {
                if (bluetoothGatt != null) {
                  mBluetoothGatt.discoverServices()
                }
            }
            default:
                super.handleMessage(msg);
                break;
        }
    }
}

以上記錄淮摔,有錯(cuò)誤還請(qǐng)?jiān)彙?br> 有問題可以一起交流~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市始赎,隨后出現(xiàn)的幾起案子和橙,更是在濱河造成了極大的恐慌,老刑警劉巖造垛,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魔招,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡五辽,警方通過查閱死者的電腦和手機(jī)办斑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人乡翅,你說我怎么就攤上這事鳞疲。” “怎么了蠕蚜?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵尚洽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我靶累,道長(zhǎng)腺毫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任挣柬,我火速辦了婚禮潮酒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凛忿。我一直安慰自己澈灼,他們只是感情好竞川,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布店溢。 她就那樣靜靜地躺著,像睡著了一般委乌。 火紅的嫁衣襯著肌膚如雪床牧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天遭贸,我揣著相機(jī)與錄音戈咳,去河邊找鬼。 笑死壕吹,一個(gè)胖子當(dāng)著我的面吹牛著蛙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耳贬,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼踏堡,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了咒劲?” 一聲冷哼從身側(cè)響起顷蟆,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎腐魂,沒想到半個(gè)月后帐偎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛔屹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年削樊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兔毒。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嫉父,死狀恐怖沛硅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绕辖,我是刑警寧澤摇肌,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站仪际,受9級(jí)特大地震影響围小,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜树碱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一肯适、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧成榜,春花似錦框舔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挣输,卻和暖如春纬凤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撩嚼。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工停士, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人完丽。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓恋技,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親逻族。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜻底,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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