關(guān)于硬件設(shè)備的藍(lán)牙連接一般都有給的demo,一般情況下按照demo去寫就可以了,但是實(shí)際情況下,
有時(shí)候,實(shí)際應(yīng)用,要比demo要復(fù)雜一些,比如設(shè)備使用過程中,直接就斷開,斷電等異常情況比較多.
我看網(wǎng)上處理藍(lán)牙操作,有主動連接硬件設(shè)備的,這樣的連接方式應(yīng)該穩(wěn)定一些,因?yàn)槲疫@邊用,藍(lán)牙掃描的方式,實(shí)現(xiàn)了
所以我就沒有再去改代碼,看了一下網(wǎng)上的代碼,也沒有太難,記錄一下自己的實(shí)現(xiàn)方式,以后可以復(fù)制粘貼使用.
實(shí)現(xiàn)方式:藍(lán)牙要先開啟,然后,程序去掃描附近藍(lán)牙設(shè)備,如果找到的藍(lán)牙設(shè)備中,發(fā)現(xiàn)有和自己提前設(shè)置的mac地址
一樣的就主動去連接這個(gè)設(shè)備,就相當(dāng)于找到這個(gè)設(shè)備了,然后就可以去操作設(shè)備了.
android中使用藍(lán)牙的時(shí)候,需要引入藍(lán)牙使用權(quán)限:
需要在AndroidManifest.xml 文件中添加藍(lán)牙權(quán)限 <!--藍(lán)牙權(quán)限--> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
然后,如果對接的硬件,還需要其他權(quán)限,會有說明文檔,也需要添加上
然后需要定義些,藍(lán)牙需要的變量
0.定義藍(lán)牙相關(guān)變量
private String mac_address=""; private BluetoothAdapter bluetoothAdapter; private BluetoothGatt mBluetoothGatt; private BluetoothGattService bluetoothGattService; private BluetoothGattCharacteristic writeCharacteristic; private BluetoothGattCharacteristic notifyCharacteristic; private ReentrantLock commLock =new ReentrantLock(); private BluetoothDevice currentDevice;
1.然后,去初始化藍(lán)牙,這個(gè)在onCreate方法中調(diào)用,就可以了.
private void lk_xyj_initBloodPressure() { bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter == null) { Toast.makeText(this, "說明此設(shè)備不支持藍(lán)牙操作", Toast.LENGTH_LONG).show(); return; } }
2.然后再去,搜索設(shè)備
//1.搜索樂康血壓計(jì) private void lk_xyj_searchDevice() { // 注冊Receiver來獲取藍(lán)牙設(shè)備相關(guān)的結(jié)果 IntentFilter intent = new IntentFilter("android.bluetooth.device.action.UUID"); intent.addAction(BluetoothDevice.ACTION_FOUND); // 用BroadcastReceiver來取得搜索結(jié)果 intent.addAction(BluetoothDevice.EXTRA_UUID); intent.addAction(BluetoothDevice.ACTION_UUID); intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); intent.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); intent.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(lk_xyj_searchDevices, intent); bluetoothAdapter.startDiscovery(); BaseApplication.context().showDialog(FaceBodyCheckActivity.this, "正在連接設(shè)備..."); }
可以看到上面,注冊了一個(gè)廣播接收器,來接收藍(lán)牙的信息
注冊完藍(lán)牙廣播接收器,以后然后bluetoothAdapter,startDiscovery() 這個(gè)是開啟藍(lán)牙掃描
3.然后看到藍(lán)牙掃描中
//2.樂康血壓計(jì)搜索,廣播類 private BroadcastReceiver lk_xyj_searchDevices = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(BluetoothDevice.ACTION_FOUND)) { //found device currentDevice = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);// BluetoothDevice device = intent// .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (mac_address.equals(currentDevice.getAddress())) { bluetoothAdapter.cancelDiscovery(); mBluetoothGatt = currentDevice.connectGatt(FaceBodyCheckActivity.this, false, lk_xyj_GattCallback); } } else if (BluetoothDevice.ACTION_UUID.equals(action)) { currentDevice = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);// BluetoothDevice device = intent// .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (mac_address.equals(currentDevice.getAddress())) { bluetoothAdapter.cancelDiscovery(); mBluetoothGatt = currentDevice.connectGatt(FaceBodyCheckActivity.this, false, lk_xyj_GattCallback); } } } };
這個(gè)方法,是只要收到藍(lán)牙的廣播信息就走這個(gè)方法,并且,會把當(dāng)前掃描的藍(lán)牙設(shè)備賦值給currentDevice 然后獲取currentDevice的mac地址
然后判斷這個(gè)掃描到的設(shè)備的mac和我們要連接的設(shè)備的mac是否一樣,如果一樣,就取消bluetoothAdapter.cancelDiscovery() 取消藍(lán)牙繼續(xù)掃描
然后,去連接這個(gè)設(shè)備currentDevice.connectGatt(FaceBodyCheckActivity.this,false,lk_xyj_GattCallback);
這個(gè)是去連接,掃描到的這個(gè)藍(lán)牙設(shè)備,連接以后,去回調(diào),lk_xyj_GattCallback這個(gè)對象.
4.然后連接設(shè)備以后的回調(diào)
//3.樂康血壓計(jì),handler類 Handler lk_xyj_mainHandler = new Handler(); private BluetoothGattCallback lk_xyj_GattCallback = new BluetoothGattCallback() { // 這里有9個(gè)要實(shí)現(xiàn)的方法,看情況要實(shí)現(xiàn)那些,用到那些就實(shí)現(xiàn)那些 //當(dāng)連接狀態(tài)發(fā)生改變的時(shí)候 @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, final int newState) { mBluetoothGatt.discoverServices(); lk_xyj_mainHandler.post(new Runnable() { @Override public void run() { if (newState == BluetoothProfile.STATE_CONNECTED) { BaseApplication.context().closeDialog(); ToastUtils.toast(FaceBodyCheckActivity.this,"設(shè)備啟動成功"); } else { Toast.makeText(FaceBodyCheckActivity.this, "設(shè)備連接已斷開", Toast.LENGTH_SHORT).show(); } } }); }; //回調(diào)響應(yīng)特征寫操作的結(jié)果。 @Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { System.out.println(222222); } ; //回調(diào)響應(yīng)特征讀操作的結(jié)果。 @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { System.out.println(3333333); } //當(dāng)服務(wù)被發(fā)現(xiàn)的時(shí)候回調(diào)的結(jié)果 @Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { try { //設(shè)置serviceUUID,原型是:BluetoothGattService bluetoothGattService = bluetoothGatt.getService(UUID.fromString(SERVICESUUID)); bluetoothGattService = mBluetoothGatt.getService(UUID.fromString(DeviceFinal.LK_XYJ_SERVICESUUID)); //設(shè)置寫入特征UUID,原型是:BluetoothGattCharacteristic writeCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(WRITEUUID)); writeCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(DeviceFinal.LK_XYJ_WRITEUUID)); //設(shè)置監(jiān)聽特征UUID,原型是:BluetoothGattCharacteristic notifyCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(NOTIFYUUID)); notifyCharacteristic = bluetoothGattService.getCharacteristic(UUID.fromString(DeviceFinal.LK_XYJ_NOTIFYUUID)); //開啟監(jiān)聽 boolean re = gatt.setCharacteristicNotification(notifyCharacteristic, true); System.out.println(re); } catch (Exception e) { e.printStackTrace(); lk_xyj_mainHandler.post(new Runnable() { @Override public void run() { ToastUtils.toast(FaceBodyCheckActivity.this,"所選設(shè)備不是血壓計(jì),請確認(rèn)后再試!");// xyj_start.setVisibility(View.GONE);// xyj_sub.setVisibility(View.GONE);// lk_xyj_msg.setText("所選設(shè)備不是血壓計(jì),請確認(rèn)后再試!"); } }); } } //接受數(shù)據(jù)回調(diào) @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { byte[] value = characteristic.getValue(); final String str = lk_xyj_bytesToHex(value); System.out.println(lk_xyj_bytesToHex(value)); lk_xyj_mainHandler.post(new Runnable() { @Override public void run() { if (str.indexOf("0240dd0200") != -1) { BigInteger amount = new BigInteger(String.valueOf(str.charAt(10)) String.valueOf(str.charAt(11)), 16);// lk_xyj_msg.setText(amount ""); lk_xyj_subTempData(amount.intValue()); } else if (str.indexOf("0240dd0c") != -1) { String sb = String.valueOf(str.charAt(12)) String.valueOf(str.charAt(13)); String db = String.valueOf(str.charAt(16)) String.valueOf(str.charAt(17)); String pr = String.valueOf(str.charAt(24)) String.valueOf(str.charAt(25)); BigInteger SBPvalue = new BigInteger(sb, 16); BigInteger DBPvalue = new BigInteger(db, 16); BigInteger PRPvalue = new BigInteger(pr, 16); if (!sb.equals("ff")) { lk_xyj_spvalue=SBPvalue ""; lk_xyj_dpvalue=DBPvalue ""; lk_xyj_prvalue=PRPvalue "";// lk_xyj_sp.setText(SBPvalue "");// lk_xyj_dp.setText(DBPvalue "");// lk_xyj_pr.setText(PRPvalue ""); //xyj_sub.setVisibility(View.VISIBLE); //發(fā)送血壓數(shù)據(jù) lk_xyj_subData(); } else { String err = String.valueOf(str.charAt(24)) String.valueOf(str.charAt(25)); String errStr = ""; switch (new BigInteger(err, 16).intValue()) { case 1: errStr = "傳感器震蕩異常"; break; case 2: errStr = "檢測不到足夠的心跳或算不出血壓"; break; case 3: errStr = "測量結(jié)果異常"; break; case 4: errStr = "袖帶過松或漏氣(10 秒內(nèi)加壓不到 30mmHg)"; break; case 5: errStr = "氣管被堵住"; break; case 6: errStr = "測量時(shí)壓力波動大"; break; case 7: errStr = "壓力超過上限"; break; case 8: errStr = "標(biāo)定數(shù)據(jù)異常或未標(biāo)定"; break; default: errStr = "血壓計(jì)異常"; } Toast.makeText(FaceBodyCheckActivity.this, errStr, Toast.LENGTH_LONG).show(); Toast.makeText(FaceBodyCheckActivity.this, "請重新測量", Toast.LENGTH_LONG).show();// lk_xyj_msg.setText(errStr); } } } });// System.out.println("ReceiveSuccess" new BytesHexStrTranslate().bytesToHexFun1(value)); } //當(dāng)連接能被被讀的操作 @Override public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { super.onDescriptorRead(gatt, descriptor, status); System.out.println(555555); } };
可以看到上面回調(diào)函數(shù)就可以判斷設(shè)備連接成功還是連接失敗.
并且連接成功以后,如果收到藍(lán)牙的測量數(shù)據(jù)會回調(diào)對應(yīng)的方法.
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請發(fā)送郵件至 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除。