android ble藍芽開發
阿新 • • 發佈:2019-01-26
1.獲得藍芽介面卡
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) { BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); mBluetoothAdapter = mBluetoothManager.getAdapter(); } else { mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } return mBluetoothAdapter;
2.開啟關閉藍芽
//開啟藍芽 public void enableBluetooth() { if (!mBluetoothAdapter.isEnabled()) { new Thread(new Runnable() { @Override public void run() { mBluetoothAdapter.enable(); } }).start(); } } //關閉藍芽 public void disableBluetooth() { if (mBluetoothAdapter.isEnabled()) mBluetoothAdapter.disable(); }
3.掃描ble藍芽
//掃描藍芽 public void startScan() { Log.e(TAG, "startScan: "); stopScan(); closeBluetooth(); if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } mBluetoothAdapter.startLeScan(leScanHook); }
4.掃描ble藍芽的回撥
public BluetoothAdapter.LeScanCallback leScanHook = new BluetoothAdapter.LeScanCallback() { public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { Log.e(TAG, "Found:" + device.getName() + " " + rssi + " " + Arrays.toString(scanRecord)); if (device.getName().equals(" ")) { adress = device.getAddress(); connect(adress); } } };
5. 連結藍芽
//連結外設藍芽 public boolean connect(final String address) { Log.e(TAG, "connect: "); stopScan(); closeBluetooth(); if (mBluetoothAdapter == null || address == null) { return false; } final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); if (device == null) { return false; } mBluetoothGatt = device.connectGatt(getBaseContext(), false, mGattCallback); return true; }
6.連結藍芽的回撥(這個callback是很重要的,ble藍芽通訊差不多就是這個回調了)
public BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { private final int HIDE_MSB_8BITS_OUT_OF_16BITS = 0x00FF; private final int SHIFT_LEFT_8BITS = 8; private final int SHIFT_LEFT_16BITS = 16; private final int GET_BIT24 = 0x00400000; private BluetoothGattCharacteristic mHTIntervalCharacter; private BluetoothGattCharacteristic mHTCharacteristic; private BluetoothGattCharacteristic mBatteryCharacteristic; private boolean isBatteryServiceFound = false; private boolean isHTServiceFound = false; private BluetoothGattService mHTService, mBatteryService; public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { //連結狀態改變 super.onConnectionStateChange(gatt, status, newState); if (gatt != mBluetoothGatt) return; Log.e(TAG, "onConnectionStateChange: status = " + status + ",newState = " + newState); if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) {//連結成功 mHandler.sendEmptyMessage(MESSAGE_UPDATE_CONNECTED_STATE); gatt.discoverServices();//成功後用得到的通用屬性協議 gatt 去查詢服務 } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {//連結失敗 connect(adress); mHandler.sendEmptyMessageDelayed(MESSAGE_CONNECT_OUT_TIME, 3 * 1000); } } else if (status == 133) {//連結失敗 這邊連結失敗返回的是133,為什麼會返回這個暫時還不知道。 connect(adress); mHandler.sendEmptyMessageDelayed(MESSAGE_CONNECT_OUT_TIME, 3 * 1000); } } public void onServicesDiscovered(BluetoothGatt gatt, int status) { //在查詢到服務之後回撥這個 if (gatt != mBluetoothGatt) //檢測這個通用屬性協議是否是當前的通用屬性協議; return; if (status == BluetoothGatt.GATT_SUCCESS) { List<BluetoothGattService> services = gatt.getServices(); for (BluetoothGattService service : services) { if (service.getUuid().equals(HT_SERVICE_UUID)) { //具體的某個服務 HT_SERVICE_UUID 具體可以看藍芽的協議相關 isHTServiceFound = true; mHTService = service; } if (service.getUuid().equals(BATTERY_SERVICE)) { //具體的某個服務 BATTERY_SERVICE mBatteryService = service; isBatteryServiceFound = true; } } if (!isHTServiceFound) { gatt.disconnect(); return; } if (isBatteryServiceFound) { readBatteryLevel(); } } } @Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { //在讀取到藍芽裝置資訊的回撥 if (status == BluetoothGatt.GATT_SUCCESS) { if (characteristic.getUuid().equals(BATTERY_LEVEL_CHARACTERISTIC)) { int batteryValue = characteristic.getValue()[0]; Message message = Message.obtain(); message.arg1 = batteryValue; message.what = MESSAGE_UPDATE_BATTERY_LEVEL; mHandler.sendMessage(message); if (isHTServiceFound) { enableHTIndication(); ChangeHTP_Interval(); } } } } @Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { double tempValue; if ((characteristic.getUuid().equals(HT_IMEDIATE_MEASUREMENT_CHARACTERISTIC_UUID)) || (characteristic.getUuid().equals(HT_MEASUREMENT_CHARACTERISTIC_UUID))) { try { //獲得的溫度 tempValue = decodeTemperature(characteristic.getValue()); Message message = Message.obtain(); Bundle bundle = new Bundle(); bundle.putDouble("temperature", tempValue); message.setData(bundle); message.what = MESSAGE_UPDATE_TEMPERATURE; mHandler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } } } private void readBatteryLevel() { mBatteryCharacteristic = mBatteryService .getCharacteristic(BATTERY_LEVEL_CHARACTERISTIC); if (mBatteryCharacteristic != null) { mBluetoothGatt.readCharacteristic(mBatteryCharacteristic); //讀取對應的電池資訊 回撥是onCharacteristicRead } } private void ChangeHTP_Interval() { final byte[] interval_val = {0x0a, 0x00}; mHTIntervalCharacter = mHTService .getCharacteristic(HT_MEASUREMENT_INTERVAL_CHARACTERISTIC_UUID); mHTIntervalCharacter.setValue(interval_val); mBluetoothGatt.writeCharacteristic(mHTIntervalCharacter); } private void enableHTIndication() { Log.e(TAG, "enableHTIndication()"); //haracteristic.getDescriptor(UUID)得到相應的descriptor mHTCharacteristic = mHTService.getCharacteristic(HT_MEASUREMENT_CHARACTERISTIC_UUID); mBluetoothGatt.setCharacteristicNotification(mHTCharacteristic, true); BluetoothGattDescriptor descriptor = mHTCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID); descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE/* ENABLE_NOTIFICATION_VALUE */);// ENABLE_INDICATION_VALUE); //設定descriptor 相對應的characteristic可更新 回撥就是onCharacteristicChanged 而且這個會讓藍芽裝置不聽的傳送資訊 mBluetoothGatt.writeDescriptor(descriptor); } };
傳統藍芽的連結可以看 這裡
更詳細的資料可以參考 這裡