1. 程式人生 > >android ble藍芽開發

android ble藍芽開發

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);
}
};


傳統藍芽的連結可以看  這裡

更詳細的資料可以參考 這裡