2017-09-05 91 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永远不会被调用;所以没有连接状态来检查。 –