我的BluetoothGattServerCallback在这里处理两个事件STATE_CONNECTED
和STATE_DISCONNECTED
private static class CallBack extends BluetoothGattServerCallback {
private Set<BluetoothDevice> mRegisteredDevices = new HashSet<>();
private MainActivity mMainActivity;
public CallBack(Set<BluetoothDevice> registeredDevices, MainActivity mainActivity){
mRegisteredDevices = registeredDevices;
mMainActivity = mainActivity;
}
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
Log.i(TAG,"onConnectionStateChange()");
switch (newState)
{
case STATE_CONNECTED :
handleStateConnected( device, status, newState);
break;
case STATE_DISCONNECTED :
handleStateDisconnected( device, status, newState);
break;
}
}
这里是处理程序STATE_CONNECTED
private void handleStateConnected(BluetoothDevice device, int status, int newState)
{
Log.i(TAG, "BluetoothDevice CONNECTED: " + device);
mRegisteredDevices.add(device);
stopAdvertising();
}
这里是处理程序STATE_DISCONNECTED
private void handleStateDisconnected(BluetoothDevice device, int status, int newState)
{
Log.i(TAG, "BluetoothDevice DISCONNECTED: " + device);
mRegisteredDevices.remove(device);
startAdvertising();
}
在STATE_CONNECTED
上,我希望手机停止广告,在STATE_DISCONNECTED
上,我希望手机恢复广告;默认行为似乎是设备在连接后将继续播发广告,因此我分别在事件处理程序stopAdvertising()
和startAdvertising()
中添加了handleStateConnected()
和handleStateDisconnected()
。
电话现在进入连接和重新连接的无限循环,原因是在致电stopAdvertising()
之后,电话将断开连接,导致它再次开始播发广告,之后将进行连接。
我的应用程序的控制流程是开始广告,然后设置GATT服务器:
private void initServer(){
Log.v(TAG,"initServer()");
mBluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = mBluetoothManager.getAdapter();
// We can't continue without proper Bluetooth support
if (!checkBluetoothSupport(bluetoothAdapter)) {
finish();
}
// Register for system Bluetooth events (GATT server started in receiver)
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(mBluetoothReceiver, filter);
if (!bluetoothAdapter.isEnabled()) {
Log.d(TAG, "Bluetooth is currently disabled...enabling");
bluetoothAdapter.enable();
} else {
startAdvertising();
startServer();
}
}
这里是startAdvertising()
public static void startAdvertising() {
Log.i(TAG,"startAdvertising()");
BluetoothAdapter bluetoothAdapter = mBluetoothManager.getAdapter();
mBluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
if (mBluetoothLeAdvertiser == null) {
Log.w(TAG, "Failed to create mBleAdvertiser");
return;
}
Log.v(TAG,"created advertizer");
AdvertiseSettings settings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
.setConnectable(true)
.setTimeout(0) // Limit advertising to a given amount of time A value of 0 will disable the time limit
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
.build();
boolean isNameChanged = BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME);
if(isNameChanged) Log.d(TAG,"Device name changed successfully.");
AdvertiseData data = new AdvertiseData.Builder()
.setIncludeDeviceName(true)
.setIncludeTxPowerLevel(false)
.addServiceUuid(ParcelUuid.fromString(Services.GloService.UUID))
.build();
mBluetoothLeAdvertiser
.startAdvertising(settings, data, mAdvertiseCallback);
}
这里是startServer()
private void startServer() {
Log.i(TAG,"startServer()");
mBluetoothGattServer =
MyProfile.getOpenServer(this, mBluetoothManager,mRegisteredDevices,this);
if (mBluetoothGattServer == null) {
Log.w(TAG, "Unable to create GATT server");
return;
}
}
这是MyProfile.getOpenServer
,它返回服务器对象,该服务器对象使用在文章顶部声明的回调进行了初始化。
public static BluetoothGattServer getOpenServer(Context ctx,
BluetoothManager bluManager,
Set<BluetoothDevice> registeredDevices,
MainActivity mainActivity){
mBluetoothManager = bluManager;
CallBack callBack = new CallBack(registeredDevices, mainActivity);
BluetoothGattServer server = bluManager.openGattServer(ctx, callBack);
BluetoothGattService myService = getMyService();
server.addService(myService);
return server;
}
答案 0 :(得分:1)
这是我过去所做的一件事,有助于解决此问题。没有保证,但这是我发现的最佳解决方法。
当在服务器端收到STATE_CONNECTED事件时,请调用BluetoothGattServer.connect(BluetoothDevice,boolean)。这是我以前使用过的代码段。
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
gattServer.connect(device, false); // prevents disconnection when advertising stops
// stop advertising here or whatever else you need to do
break;
}
}