0
我目前正在從藍牙LE LE開始從android到android交換小值的項目。 我使用nexus9作爲android周邊設備,Moto G作爲中心。完美的中央掃描外圍設備和外圍設備的服務正在被添加,現在我需要在外設上寫入特徵,然後外設將確認它到中央,但外圍設備發送特定字節到中央而不是讀取中央特徵,即使這個中央工作正常外設。 這裏是我的Android中央安卓android安卓通過ble通信
private void startScanning() {
if ((btAdapter != null) && (!isScanning)) {
if (scanner == null) {
Log.d(TAG, "scanner was null");
scanner = btAdapter.getBluetoothLeScanner();
}
if (scanCallback == null)
setScanCallback(null);
scanner.startScan(createScanFilters(), createScanSettings(), scanCallback);
isScanning = true;
Log.d(TAG, "in startScanning");
//Toast.makeText(context, context.getString(R.string.scan_started), Toast.LENGTH_SHORT).show();
}
}
public void setScanCallback(final ScanCallback callback) {
scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult scanResult) {
super.onScanResult(callbackType, scanResult);
Log.d(TAG, scanResult.getDevice().getName() + " ");
deviceNames.add(scanResult.getDevice().getName());
deviceRSSIs.add(String.valueOf(scanResult.getRssi()));
adapter.notifyDataSetChanged();
scanResult.getDevice().connectGatt(context, false, new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
Set<BluetoothGattCharacteristic> characteristicSet;
switch (newState) {
case BluetoothProfile.STATE_DISCONNECTING:
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.d(TAG, gatt.getDevice().getName() + " is disconnected");
//gatt.close();
break;
case BluetoothProfile.STATE_CONNECTED:
Log.d(TAG, gatt.getDevice().getName() + " is connected");
gatt.discoverServices();
break;
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "Discovered services central");
// TODO: Keep this here to examine characteristics
// eventually we should get rid of the discoverServices step
boolean foundService = false;
try {
List<BluetoothGattService> serviceList = gatt.getServices();
for (BluetoothGattService service : serviceList) {
if (service.getUuid().equals(serviceUUID)) {
foundService = true;
HashSet<BluetoothGattCharacteristic> characteristicSet = new HashSet<>();
characteristicSet.addAll(service.getCharacteristics());
discoveredCharacteristics.put(gatt.getDevice().getAddress(), characteristicSet);
for (BluetoothGattCharacteristic characteristic : characteristicSet) {
if (characteristic.getUuid().equals(characteristicUUID)) {
characteristic.setValue(dataToSend.getBytes());
boolean chr = gatt.writeCharacteristic(characteristic);
characteristic = gatt.getService(serviceUUID).getCharacteristic(characteristicUUID);
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
boolean desc = gatt.writeDescriptor(descriptor);
// setIndictaionSubscription(gatt, characteristic, true);
}
}
}
}
} catch (Exception e) {
Log.d(TAG, "Exception analyzing discovered services " + e.getLocalizedMessage());
e.printStackTrace();
}
if (!foundService)
Log.d(TAG, "Could not discover chat service!");
} else
Log.d(TAG, "Discovered services appears unsuccessful with code " + status);
super.onServicesDiscovered(gatt, status);
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
Log.d(TAG, "onDescriptorWrite");
}
@Override
public void onCharacteristicChanged(final BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) {
Log.d(TAG, "onCharacteristicChanged");
if (!characteristic.getValue().toString().isEmpty()) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getBaseContext(), new String(characteristic.getValue()), Toast.LENGTH_LONG).show();
gatt.readRemoteRssi();
}
});
}
super.onCharacteristicChanged(gatt, characteristic);
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
Log.d(TAG, "onCharacteristicWrite");
Exception exception = null;
if (status != BluetoothGatt.GATT_SUCCESS) {
String msg = "Write was not successful with code " + status;
Log.d(TAG, msg);
exception = new UnknownServiceException(msg);
}
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
Log.i("RSSIValue", gatt.getDevice().getName() + " " + String.valueOf(rssi) + " " + String.valueOf(status));
super.onReadRemoteRssi(gatt, rssi, status);
}
});
}
};
}
代碼在這裏是我的外設代碼。
private AdvertiseCallback mAdvCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
if (settingsInEffect != null) {
Log.d(TAG, "Advertise success TxPowerLv="
+ settingsInEffect.getTxPowerLevel()
+ " mode=" + settingsInEffect.getMode());
} else {
Log.d(TAG, "Advertise success");
}
}
@Override
public void onStartFailure(int errorCode) {
Log.d(TAG, "Advertising failed with code " + errorCode);
}
};
private AdvertiseData createAdvData() {
AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
dataBuilder.addServiceUuid(new ParcelUuid(serviceUUID));
dataBuilder.setIncludeTxPowerLevel(false);
dataBuilder.setIncludeDeviceName(true);
// builder.setManufacturerData(0x1234578, manufacturerData);
return dataBuilder.build();
}
private AdvertiseSettings createAdvSettings() {
AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder();
builder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
builder.setConnectable(false);
return builder.build();
}
private void stopAdvertising() {
if (isAdvertising) {
gattServer.close();
advertiser.stopAdvertising(mAdvCallback);
isAdvertising = false;
}
}
public void createMessage() {
// Chop Message! You can only advertise 20 bytes at a time through ble
byte[] message = ("my text need to send").getBytes();
mDataToSend = new ArrayList<>();
dataToSendIndex = 0;
for(int i=0;i<Math.ceil((float)message.length/(float)20);i++) {
byte[] slice = new byte[20];
for(int ii=0;ii<slice.length && i*20 + ii < message.length;ii++) {
slice[ii] = message[i*20 + ii];
}
mDataToSend.add(slice);
}
// Start sending the message
sendMessage();
}
public void sendMessage() {
if(dataToSendIndex >= mDataToSend.size()) { // If we have incremented through the message, the message is sent
Log.d("auto", "PeripheralActivity > sendMessage() > Message Sent");
// Done Sending!
return;
}
// Set the value of the characteristic to the next data to send
mCharacteristic.setValue(mDataToSend.get(dataToSendIndex));
// Notify the subscriber you have changed the value
gattServer.notifyCharacteristicChanged(btClient, mCharacteristic, true);
// Increment index
dataToSendIndex ++;
}
BluetoothGattServerCallback gattCallback = new BluetoothGattServerCallback() {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
}
// @Override
// public void onServiceAdded(int status, BluetoothGattService service) {
// super.onServiceAdded(status, service);
// }
@Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
Log.d(TAG, characteristic.toString());
}
@Override
public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
btClient = device;
gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);
createMessage();
}
@Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
super.onDescriptorReadRequest(device, requestId, offset, descriptor);
}
@Override
public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
btClient = device;
gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
createMessage();
}
// @Override
// public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
// super.onExecuteWrite(device, requestId, execute);
// }
@Override
public void onNotificationSent(BluetoothDevice device, int status) {
super.onNotificationSent(device, status);
sendMessage();
}
// @Override
// public void onMtuChanged(BluetoothDevice device, int mtu) {
// super.onMtuChanged(device, mtu);
// }
};
private void startGattServer() {
// Create GATT Service
service = new BluetoothGattService(serviceUUID , BluetoothGattService.SERVICE_TYPE_PRIMARY);
// Create Config Descriptor
BluetoothGattDescriptor dataDescriptor = new BluetoothGattDescriptor(CLIENT_CHARACTERISTIC_CONFIG, BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);
// Add Descriptor
mCharacteristic.addDescriptor(dataDescriptor);
BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);
// Add Characteristic
service.addCharacteristic(mCharacteristic);
gattServer = manager.openGattServer(this, gattCallback);
gattServer.addService(service);
}
PS:可能有一個基本的錯誤,我可能無法檢測它,任何幫助將是非常可觀的:)