2017-09-05 50 views
0

我想發送消息給BLE設備。根據我的理解,首先必須發現設備服務,然後將消息發送到服務特性。因此,這裏是我做過什麼:從未發現的BLE服務

public class BluetoothLeService extends Service { 

private BluetoothManager mBluetoothManager; 
private BluetoothAdapter mBluetoothAdapter; 
private String mBluetoothDeviceAddress; 
private BluetoothGatt mBluetoothGatt; 

private String macAddress; 
private String serviceUuid; 
private String characteristicUuid; 
private Application app; 
private int transmissionValue = 450;  

public BluetoothLeService(String address, String serviceUuid, String characteristicUuid) { 
    this.macAddress = address; 
    this.serviceUuid = serviceUuid; 
    this.characteristicUuid = characteristicUuid; 
} 


private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 
    @Override 
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 
     System.out.println("connectionStateChange: " + status); 
     if (STATE_CONNECTED == newState) { 
      gatt.discoverServices(); 
     } 
    } 

    @Override 
    public void onServicesDiscovered(BluetoothGatt gatt, int status) { 
     if(gatt.getDevice().getName().equals("MyDeviceName")) { 
      sendMessageAfterDiscovery(gatt); 
     } 
    } 

}; 

public boolean initialize(Application app) { 
    this.app = app; 
    if (mBluetoothManager == null) { 
     mBluetoothManager = (BluetoothManager) app.getSystemService(Context.BLUETOOTH_SERVICE); 
     if (mBluetoothManager == null) { 
      return false; 
     } 
    } 

    mBluetoothAdapter = mBluetoothManager.getAdapter(); 
    if (mBluetoothAdapter == null) { 
     return false; 
    } 
    return true; 
} 


public boolean connect() { 
    return connect(macAddress); 
} 

public boolean connect(final String address) { 
    this.macAddress = address; 
    if (mBluetoothAdapter == null || macAddress == null) { 
     return false; 
    } 

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress); 
    if (device == null) { 
     Log.w(TAG, "Device not found. Unable to connect."); 
     return false; 
    } 
    mBluetoothGatt = device.connectGatt(this, false, mGattCallback); 
    return true; 
} 

public void writeCharacteristic(int value) { 
    this.transmissionValue = value; 
    BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(this.macAddress); 
    BluetoothGatt mBG = mDevice.connectGatt(app.getApplicationContext(), true, mGattCallback); 
    System.out.println("device name: " + mBG.getDevice().getName()); 

} 

private void sendMessageAfterDiscovery(BluetoothGatt gatt) { 
    BluetoothGattService mSVC = gatt.getService(UUID.fromString(serviceUuid)); 

    BluetoothGattCharacteristic mCH = mSVC.getCharacteristic(UUID.fromString(characteristicUuid)); 
    mCH.setValue(transmissionValue, BluetoothGattCharacteristic.FORMAT_UINT16, 0); 
    System.out.println("characteristic writable: " + isCharacteristicWriteable(mCH)); 

    System.out.println("success? " + gatt.writeCharacteristic(mCH)); 
} 

public static boolean isCharacteristicWriteable(BluetoothGattCharacteristic pChar) { 
    return (pChar.getProperties() & (BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) != 0; 
} 

}

而這裏就是我要發送消息的代碼:

private void sendMessage() { 
    BluetoothLeService ble = new BluetoothLeService("B0:00:00:00:00:C0", "0000fff0-1111-0000-0000-00805f9b34fb","0000fff1-1111-0000-0000-00805f9b34fb"); 
    ble.initialize(app); 
    ble.connect();, 
    ble.writeCharacteristic(450) 
} 

現在,每當我想連接到該設備併發送一條消息,onServiceDiscovered方法從未被調用,雖然設備被識別,因爲我可以獲取設備的名稱。也沒有錯誤被拋出。

爲什麼此方法從未被調用過?難道我做錯了什麼? 我已經檢查了權限,並在清單中將該類添加爲服務。

感謝您的幫助......

回答

1

你需要調用discoverServices從GATT回調onConnectionStateChange方法中。 discoverServices方法的文檔:

查找遠程設備提供的服務以及它們的 特徵和描述符。

這是一個異步操作。一旦完成服務發現 ,觸發的onServicesDiscovered(BluetoothGatt, int)回調爲 。如果發現成功,則可以使用getServices()函數檢索遠程服務 。

在你的情況,更新您的代碼如下所示應該做的伎倆:

@Override 
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 
    System.out.println("connectionStateChange: " + status); 

    if (STATE_CONNECTED == newState) { 
     gatt.discoverServices(); 
    } 
} 
+0

我只是去嘗試; 但是當我在onConnectionStateChange中調用它時,這個方法永遠不會被調用,但我仍然在connectGatt之後得到deviceName; 我更新了代碼 –

+0

您是否已驗證連接狀態是否以'STATE_CONNECTED'返回? – stkent

+0

onConnectionStateChange永遠不會被調用;所以沒有連接狀態來檢查。 –