未连接 Gatt 服务器
Not Connecting Gatt Server
我正在尝试通过 Gatt 协议连接两个 android 设备。
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.ParcelUuid;
import android.util.Log;
import java.util.HashSet;
import java.util.Set;
public class GattServer {
private final String TAG = GattServer.class.getSimpleName();
private Context applicationContext;
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private LocationManager locationManager;
BluetoothLeAdvertiser bluetoothLeAdvertiser;
private static GattServer gattServer;
private BluetoothGattServer bluetoothGattServer;
private Set<BluetoothDevice> connectedDevices = new HashSet<>();
public GattServer(Context applicationContext) {
this.applicationContext = applicationContext;
bluetoothManager = (BluetoothManager) applicationContext.getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
locationManager = (LocationManager) applicationContext.getSystemService(Context.LOCATION_SERVICE);
registerBluetoothStateReceiver();
}
public static GattServer getInstance(Context context) {
if (gattServer == null) {
gattServer = new GattServer(context.getApplicationContext());
}
return gattServer;
}
private BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
switch (state) {
case BluetoothAdapter.STATE_ON:
println("Bluetooth adapter state is changed to ON");
break;
case BluetoothAdapter.STATE_OFF:
println("Bluetooth adapter state is changed to OF");
break;
default:
// Do nothing
}
}
};
private void println(String message) {
Log.e(TAG, message);
}
private void registerBluetoothStateReceiver() {
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
try {
applicationContext.registerReceiver(bluetoothStateReceiver, filter);
} catch (Exception e) {
e.printStackTrace();
}
}
private void unregisterBluetoothStateReceiver() {
try {
applicationContext.unregisterReceiver(bluetoothStateReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
stop();
unregisterBluetoothStateReceiver();
gattServer = null;
}
private AdvertiseCallback advertiseCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
println("Advertise Started");
listener.onAdvertiseStarted();
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
println("Advertise Failed : " + errorCode);
listener.onAdvertiseFail(errorCode);
}
};
private void startAdvertising() {
bluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
if (bluetoothLeAdvertiser == null || !bluetoothAdapter.isMultipleAdvertisementSupported()) {
Log.e(TAG, "Failed to create advertiser");
listener.onAdvertiseFail(-1);
return;
}
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
.setConnectable(true)
.setTimeout(0)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
.build();
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.setIncludeTxPowerLevel(false)
.addServiceUuid(new ParcelUuid(GattServerConfiguration.SERVICE_UUID))
.build();
bluetoothLeAdvertiser.startAdvertising(settings, data, advertiseCallback);
}
private BluetoothGattServerCallback gattCallback = new BluetoothGattServerCallback() {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
println("Device Connected : " + device.getAddress());
connectedDevices.add(device);
listener.onDeviceConnected(device);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
println("Device Disconnected : " + device.getAddress());
connectedDevices.remove(device);
listener.onDeviceDisconnected(device);
}
}
@Override
public void onServiceAdded(int status, BluetoothGattService service) {
super.onServiceAdded(status, service);
Log.d(TAG, "onServiceAdded() called with: status = [" + status + "], service = [" + service + "]");
listener.onServiceAdded();
}
@Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
Log.d(TAG, "onCharacteristicReadRequest() called with: device = [" + device + "], requestId = [" + requestId + "], offset = [" + offset + "], characteristic = [" + characteristic + "]");
listener.onReceive(device, characteristic);
}
@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);
Log.d(TAG, "onCharacteristicWriteRequest() called with: device = [" + device + "], requestId = [" + requestId + "], characteristic = [" + characteristic + "], preparedWrite = [" + preparedWrite + "], responseNeeded = [" + responseNeeded + "], offset = [" + offset + "], value = [" + value + "]");
}
@Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
super.onDescriptorReadRequest(device, requestId, offset, descriptor);
Log.d(TAG, "onDescriptorReadRequest() called with: device = [" + device + "], requestId = [" + requestId + "], offset = [" + offset + "], descriptor = [" + descriptor + "]");
if (GattServerConfiguration.CCC_DESCRIPTOR_UUID.equals(descriptor.getUuid())) {
Log.d(TAG, "Config descriptor read");
byte[] returnValue;
if (connectedDevices.contains(device)) {
returnValue = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else {
returnValue = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, returnValue);
} else {
Log.w(TAG, "Unknown descriptor read request");
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null);
}
}
@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);
Log.d(TAG, "onDescriptorWriteRequest() called with: device = [" + device + "], requestId = [" + requestId + "], descriptor = [" + descriptor + "], preparedWrite = [" + preparedWrite + "], responseNeeded = [" + responseNeeded + "], offset = [" + offset + "], value = [" + value + "]");
if (GattServerConfiguration.CCC_DESCRIPTOR_UUID.equals(descriptor.getUuid())) {
Log.d(TAG, "Config descriptor read");
byte[] returnValue;
if (connectedDevices.contains(device)) {
returnValue = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else {
returnValue = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, returnValue);
} else {
Log.w(TAG, "Unknown descriptor read request");
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null);
}
}
@Override
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
super.onExecuteWrite(device, requestId, execute);
Log.d(TAG, "onExecuteWrite() called with: device = [" + device + "], requestId = [" + requestId + "], execute = [" + execute + "]");
}
@Override
public void onNotificationSent(BluetoothDevice device, int status) {
super.onNotificationSent(device, status);
Log.d(TAG, "onNotificationSent() called with: device = [" + device + "], status = [" + status + "]");
}
@Override
public void onMtuChanged(BluetoothDevice device, int mtu) {
super.onMtuChanged(device, mtu);
Log.d(TAG, "onMtuChanged() called with: device = [" + device + "], mtu = [" + mtu + "]");
}
@Override
public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
super.onPhyUpdate(device, txPhy, rxPhy, status);
Log.d(TAG, "onPhyUpdate() called with: device = [" + device + "], txPhy = [" + txPhy + "], rxPhy = [" + rxPhy + "], status = [" + status + "]");
}
@Override
public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
super.onPhyRead(device, txPhy, rxPhy, status);
Log.d(TAG, "onPhyRead() called with: device = [" + device + "], txPhy = [" + txPhy + "], rxPhy = [" + rxPhy + "], status = [" + status + "]");
}
};
private void startServer() {
bluetoothGattServer = bluetoothManager.openGattServer(applicationContext, gattCallback);
if (bluetoothGattServer == null) {
println("Server is null");
return;
}
bluetoothGattServer.addService(GattServerConfiguration.createGattService());
}
public void launch() {
if (isReady()) {
startServer();
startAdvertising();
}
}
private void stopAdvertising() {
if (bluetoothLeAdvertiser == null) return;
bluetoothLeAdvertiser.stopAdvertising(advertiseCallback);
}
private void stopServer() {
if (bluetoothGattServer == null) return;
bluetoothGattServer.close();
}
public void stop() {
stopAdvertising();
stopServer();
connectedDevices.clear();
}
private boolean isReady() {
if (bluetoothManager == null) {
return false;
}
return bluetoothAdapter.isEnabled() && locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
private IGattServer listener;
public void setCallback(IGattServer listener) {
this.listener = listener;
}
}
以上代码,成功启动广告,
另一个设备在 LE 扫描中成功接收设备(使用 UUID 的过滤器)
但是connectGatt()
没有提供任何回调。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
bluetoothGatt = bluetoothDevice.connectGatt(
getApplicationContext(), true, gattCallback,
BluetoothDevice.TRANSPORT_LE
);
} else {
bluetoothGatt = bluetoothDevice.connectGatt(getApplicationContext(), true, gattCallback);
}
Gatt 回调示例代码。
private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
writeLog("onConnectionStateChange() called with: gatt = [" + gatt + "], status = [" + status + "], newState = [" + newState + "]");
broadcastUpdate(
ACTION_GATT_MESSAGE,
"onConnectionStateChange() called with: gatt = $gatt, status = $status, newState = $newState"
);
if (status == 8) {
writeLog("BLE Out Of Range");
broadcastUpdate(ACTION_GATT_MESSAGE, "BLE Out Of Range status == 8");
} else if (status == 19) {
writeLog("BLE Disconnected By Device");
broadcastUpdate(ACTION_GATT_MESSAGE, "BLE Disconnected By Device status == 19");
} else if (status == 22) {
writeLog("BLE Issue with bond");
broadcastUpdate(ACTION_GATT_MESSAGE, "BLE Issue with bond status == 22");
} else if (status == 133 || status == 62) {
writeLog("BLE Device not found");
broadcastUpdate(
ACTION_GATT_MESSAGE,
"BLE Device not found status == 133 || status == 62"
);
disconnect();
close();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
connectDevice(bluetoothAdapter.getRemoteDevice(PrefManager.getInstance(getApplicationContext()).getLeAddress()));
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
connected = true;
broadcastUpdate(ACTION_GATT_CONNECTED);
bluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
connected = false;
broadcastUpdate(ACTION_GATT_DISCONNECTED);
stopSelf();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
writeLog("onServicesDiscovered() called with: gatt = [" + gatt + "], status = [" + status + "]");
if (status == BluetoothGatt.GATT_SUCCESS) {
Intent intent = new Intent(ACTION_GATT_SERVICES_DISCOVERED);
ArrayList<BluetoothGattService> services = new ArrayList<BluetoothGattService>();
for (BluetoothGattService gattService : gatt.getServices()) {
services.add(gattService);
}
intent.putParcelableArrayListExtra("services", services);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
broadcastUpdate(intent);
} else {
broadcastUpdate(ACTION_GATT_NO_SERVICES_DISCOVERED);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
Log.e(
TAG,
"onCharacteristicRead() called with: gatt = $gatt, characteristic = $characteristic, status = $status"
);
if (status == BluetoothGatt.GATT_SUCCESS) {
Intent intent = new Intent(ACTION_DATA_AVAILABLE);
intent.putExtra("bytes", characteristic.getValue());
//lintent.putExtra("data", characteristic.getValue().toString());
broadcastUpdate(intent);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
Log.e(
TAG,
"onCharacteristicWrite() called with: gatt = " + gatt + ", characteristic = " + characteristic + ", status = " + status
);
if (canceled || !connected || writeCharacteristic == null) {
writeLog("Return Form write 1");
return;
}
if (status != BluetoothGatt.GATT_SUCCESS) {
writeLog("Return Form write 2");
broadcastUpdate(ACTION_DATA_WRITE_FAIL);
return;
}
if (canceled) return;
writeLog("Write Success Checking for next bytes");
if (characteristic.getUuid().toString().equals(writeCharacteristic.getUuid().toString())) { // NOPMD - test object identity
writeNext();
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.e(
TAG,
"onCharacteristicChanged() called with: gatt = $gatt, characteristic = $characteristic"
);
if (characteristic.getUuid().toString().equals(readCharacteristic.getUuid().toString())) {
Intent intent = new Intent(ACTION_DATA_AVAILABLE);
intent.putExtra("bytes", characteristic.getValue());
broadcastUpdate(intent);
}
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
Log.e(
TAG,
"onDescriptorRead() called with: gatt = $gatt, descriptor = $descriptor, status = $status"
);
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
writeLog("onDescriptorWrite() called with: gatt = [" + gatt + "], descriptor = [" + descriptor + "], status = [" + status + "]");
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
super.onReliableWriteCompleted(gatt, status);
writeLog("onReliableWriteCompleted() called with: gatt = [" + gatt + "], status = [" + status + "]");
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
writeLog("onReadRemoteRssi() called with: gatt = [" + gatt + "], rssi = [" + rssi + "], status = [" + status + "]");
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
payloadSize = mtu - 3;
writeLog("payload size $payloadSize");
}
enableTxNotification();
}
@Override
public void onServiceChanged(@NonNull BluetoothGatt gatt) {
super.onServiceChanged(gatt);
}
};
我解决了连接问题。
bluetoothGatt = bluetoothDevice.connectGatt(
getApplicationContext(), false, gattCallback,
BluetoothDevice.TRANSPORT_AUTO
);
我正在尝试通过 Gatt 协议连接两个 android 设备。
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.os.ParcelUuid;
import android.util.Log;
import java.util.HashSet;
import java.util.Set;
public class GattServer {
private final String TAG = GattServer.class.getSimpleName();
private Context applicationContext;
private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private LocationManager locationManager;
BluetoothLeAdvertiser bluetoothLeAdvertiser;
private static GattServer gattServer;
private BluetoothGattServer bluetoothGattServer;
private Set<BluetoothDevice> connectedDevices = new HashSet<>();
public GattServer(Context applicationContext) {
this.applicationContext = applicationContext;
bluetoothManager = (BluetoothManager) applicationContext.getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
locationManager = (LocationManager) applicationContext.getSystemService(Context.LOCATION_SERVICE);
registerBluetoothStateReceiver();
}
public static GattServer getInstance(Context context) {
if (gattServer == null) {
gattServer = new GattServer(context.getApplicationContext());
}
return gattServer;
}
private BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
switch (state) {
case BluetoothAdapter.STATE_ON:
println("Bluetooth adapter state is changed to ON");
break;
case BluetoothAdapter.STATE_OFF:
println("Bluetooth adapter state is changed to OF");
break;
default:
// Do nothing
}
}
};
private void println(String message) {
Log.e(TAG, message);
}
private void registerBluetoothStateReceiver() {
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
try {
applicationContext.registerReceiver(bluetoothStateReceiver, filter);
} catch (Exception e) {
e.printStackTrace();
}
}
private void unregisterBluetoothStateReceiver() {
try {
applicationContext.unregisterReceiver(bluetoothStateReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
public void destroy() {
stop();
unregisterBluetoothStateReceiver();
gattServer = null;
}
private AdvertiseCallback advertiseCallback = new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
println("Advertise Started");
listener.onAdvertiseStarted();
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
println("Advertise Failed : " + errorCode);
listener.onAdvertiseFail(errorCode);
}
};
private void startAdvertising() {
bluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
if (bluetoothLeAdvertiser == null || !bluetoothAdapter.isMultipleAdvertisementSupported()) {
Log.e(TAG, "Failed to create advertiser");
listener.onAdvertiseFail(-1);
return;
}
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
.setConnectable(true)
.setTimeout(0)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
.build();
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.setIncludeTxPowerLevel(false)
.addServiceUuid(new ParcelUuid(GattServerConfiguration.SERVICE_UUID))
.build();
bluetoothLeAdvertiser.startAdvertising(settings, data, advertiseCallback);
}
private BluetoothGattServerCallback gattCallback = new BluetoothGattServerCallback() {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
println("Device Connected : " + device.getAddress());
connectedDevices.add(device);
listener.onDeviceConnected(device);
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
println("Device Disconnected : " + device.getAddress());
connectedDevices.remove(device);
listener.onDeviceDisconnected(device);
}
}
@Override
public void onServiceAdded(int status, BluetoothGattService service) {
super.onServiceAdded(status, service);
Log.d(TAG, "onServiceAdded() called with: status = [" + status + "], service = [" + service + "]");
listener.onServiceAdded();
}
@Override
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
Log.d(TAG, "onCharacteristicReadRequest() called with: device = [" + device + "], requestId = [" + requestId + "], offset = [" + offset + "], characteristic = [" + characteristic + "]");
listener.onReceive(device, characteristic);
}
@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);
Log.d(TAG, "onCharacteristicWriteRequest() called with: device = [" + device + "], requestId = [" + requestId + "], characteristic = [" + characteristic + "], preparedWrite = [" + preparedWrite + "], responseNeeded = [" + responseNeeded + "], offset = [" + offset + "], value = [" + value + "]");
}
@Override
public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
super.onDescriptorReadRequest(device, requestId, offset, descriptor);
Log.d(TAG, "onDescriptorReadRequest() called with: device = [" + device + "], requestId = [" + requestId + "], offset = [" + offset + "], descriptor = [" + descriptor + "]");
if (GattServerConfiguration.CCC_DESCRIPTOR_UUID.equals(descriptor.getUuid())) {
Log.d(TAG, "Config descriptor read");
byte[] returnValue;
if (connectedDevices.contains(device)) {
returnValue = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else {
returnValue = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, returnValue);
} else {
Log.w(TAG, "Unknown descriptor read request");
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null);
}
}
@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);
Log.d(TAG, "onDescriptorWriteRequest() called with: device = [" + device + "], requestId = [" + requestId + "], descriptor = [" + descriptor + "], preparedWrite = [" + preparedWrite + "], responseNeeded = [" + responseNeeded + "], offset = [" + offset + "], value = [" + value + "]");
if (GattServerConfiguration.CCC_DESCRIPTOR_UUID.equals(descriptor.getUuid())) {
Log.d(TAG, "Config descriptor read");
byte[] returnValue;
if (connectedDevices.contains(device)) {
returnValue = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE;
} else {
returnValue = BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
}
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, returnValue);
} else {
Log.w(TAG, "Unknown descriptor read request");
bluetoothGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null);
}
}
@Override
public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
super.onExecuteWrite(device, requestId, execute);
Log.d(TAG, "onExecuteWrite() called with: device = [" + device + "], requestId = [" + requestId + "], execute = [" + execute + "]");
}
@Override
public void onNotificationSent(BluetoothDevice device, int status) {
super.onNotificationSent(device, status);
Log.d(TAG, "onNotificationSent() called with: device = [" + device + "], status = [" + status + "]");
}
@Override
public void onMtuChanged(BluetoothDevice device, int mtu) {
super.onMtuChanged(device, mtu);
Log.d(TAG, "onMtuChanged() called with: device = [" + device + "], mtu = [" + mtu + "]");
}
@Override
public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
super.onPhyUpdate(device, txPhy, rxPhy, status);
Log.d(TAG, "onPhyUpdate() called with: device = [" + device + "], txPhy = [" + txPhy + "], rxPhy = [" + rxPhy + "], status = [" + status + "]");
}
@Override
public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
super.onPhyRead(device, txPhy, rxPhy, status);
Log.d(TAG, "onPhyRead() called with: device = [" + device + "], txPhy = [" + txPhy + "], rxPhy = [" + rxPhy + "], status = [" + status + "]");
}
};
private void startServer() {
bluetoothGattServer = bluetoothManager.openGattServer(applicationContext, gattCallback);
if (bluetoothGattServer == null) {
println("Server is null");
return;
}
bluetoothGattServer.addService(GattServerConfiguration.createGattService());
}
public void launch() {
if (isReady()) {
startServer();
startAdvertising();
}
}
private void stopAdvertising() {
if (bluetoothLeAdvertiser == null) return;
bluetoothLeAdvertiser.stopAdvertising(advertiseCallback);
}
private void stopServer() {
if (bluetoothGattServer == null) return;
bluetoothGattServer.close();
}
public void stop() {
stopAdvertising();
stopServer();
connectedDevices.clear();
}
private boolean isReady() {
if (bluetoothManager == null) {
return false;
}
return bluetoothAdapter.isEnabled() && locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
private IGattServer listener;
public void setCallback(IGattServer listener) {
this.listener = listener;
}
}
以上代码,成功启动广告,
另一个设备在 LE 扫描中成功接收设备(使用 UUID 的过滤器)
但是connectGatt()
没有提供任何回调。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
bluetoothGatt = bluetoothDevice.connectGatt(
getApplicationContext(), true, gattCallback,
BluetoothDevice.TRANSPORT_LE
);
} else {
bluetoothGatt = bluetoothDevice.connectGatt(getApplicationContext(), true, gattCallback);
}
Gatt 回调示例代码。
private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
writeLog("onConnectionStateChange() called with: gatt = [" + gatt + "], status = [" + status + "], newState = [" + newState + "]");
broadcastUpdate(
ACTION_GATT_MESSAGE,
"onConnectionStateChange() called with: gatt = $gatt, status = $status, newState = $newState"
);
if (status == 8) {
writeLog("BLE Out Of Range");
broadcastUpdate(ACTION_GATT_MESSAGE, "BLE Out Of Range status == 8");
} else if (status == 19) {
writeLog("BLE Disconnected By Device");
broadcastUpdate(ACTION_GATT_MESSAGE, "BLE Disconnected By Device status == 19");
} else if (status == 22) {
writeLog("BLE Issue with bond");
broadcastUpdate(ACTION_GATT_MESSAGE, "BLE Issue with bond status == 22");
} else if (status == 133 || status == 62) {
writeLog("BLE Device not found");
broadcastUpdate(
ACTION_GATT_MESSAGE,
"BLE Device not found status == 133 || status == 62"
);
disconnect();
close();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
connectDevice(bluetoothAdapter.getRemoteDevice(PrefManager.getInstance(getApplicationContext()).getLeAddress()));
return;
}
if (newState == BluetoothProfile.STATE_CONNECTED) {
connected = true;
broadcastUpdate(ACTION_GATT_CONNECTED);
bluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
connected = false;
broadcastUpdate(ACTION_GATT_DISCONNECTED);
stopSelf();
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
writeLog("onServicesDiscovered() called with: gatt = [" + gatt + "], status = [" + status + "]");
if (status == BluetoothGatt.GATT_SUCCESS) {
Intent intent = new Intent(ACTION_GATT_SERVICES_DISCOVERED);
ArrayList<BluetoothGattService> services = new ArrayList<BluetoothGattService>();
for (BluetoothGattService gattService : gatt.getServices()) {
services.add(gattService);
}
intent.putParcelableArrayListExtra("services", services);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
broadcastUpdate(intent);
} else {
broadcastUpdate(ACTION_GATT_NO_SERVICES_DISCOVERED);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
Log.e(
TAG,
"onCharacteristicRead() called with: gatt = $gatt, characteristic = $characteristic, status = $status"
);
if (status == BluetoothGatt.GATT_SUCCESS) {
Intent intent = new Intent(ACTION_DATA_AVAILABLE);
intent.putExtra("bytes", characteristic.getValue());
//lintent.putExtra("data", characteristic.getValue().toString());
broadcastUpdate(intent);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
Log.e(
TAG,
"onCharacteristicWrite() called with: gatt = " + gatt + ", characteristic = " + characteristic + ", status = " + status
);
if (canceled || !connected || writeCharacteristic == null) {
writeLog("Return Form write 1");
return;
}
if (status != BluetoothGatt.GATT_SUCCESS) {
writeLog("Return Form write 2");
broadcastUpdate(ACTION_DATA_WRITE_FAIL);
return;
}
if (canceled) return;
writeLog("Write Success Checking for next bytes");
if (characteristic.getUuid().toString().equals(writeCharacteristic.getUuid().toString())) { // NOPMD - test object identity
writeNext();
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.e(
TAG,
"onCharacteristicChanged() called with: gatt = $gatt, characteristic = $characteristic"
);
if (characteristic.getUuid().toString().equals(readCharacteristic.getUuid().toString())) {
Intent intent = new Intent(ACTION_DATA_AVAILABLE);
intent.putExtra("bytes", characteristic.getValue());
broadcastUpdate(intent);
}
}
@Override
public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorRead(gatt, descriptor, status);
Log.e(
TAG,
"onDescriptorRead() called with: gatt = $gatt, descriptor = $descriptor, status = $status"
);
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
super.onDescriptorWrite(gatt, descriptor, status);
writeLog("onDescriptorWrite() called with: gatt = [" + gatt + "], descriptor = [" + descriptor + "], status = [" + status + "]");
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
super.onReliableWriteCompleted(gatt, status);
writeLog("onReliableWriteCompleted() called with: gatt = [" + gatt + "], status = [" + status + "]");
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
super.onReadRemoteRssi(gatt, rssi, status);
writeLog("onReadRemoteRssi() called with: gatt = [" + gatt + "], rssi = [" + rssi + "], status = [" + status + "]");
}
@Override
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
super.onMtuChanged(gatt, mtu, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
payloadSize = mtu - 3;
writeLog("payload size $payloadSize");
}
enableTxNotification();
}
@Override
public void onServiceChanged(@NonNull BluetoothGatt gatt) {
super.onServiceChanged(gatt);
}
};
我解决了连接问题。
bluetoothGatt = bluetoothDevice.connectGatt(
getApplicationContext(), false, gattCallback,
BluetoothDevice.TRANSPORT_AUTO
);