Android BluetoothLeAdvertiser.stopAdvertising()导致设备断开连接

Android BluetoothLeAdvertiser.stopAdvertising()导致设备断开连接,android,bluetooth-lowenergy,Android,Bluetooth Lowenergy,在这里,我处理两个事件STATE\u CONNECTED和STATE\u DISCONNECTED 这里是处理程序状态\u已断开连接 在连接状态下,我希望我的手机停止广告,在断开连接状态下,我希望手机恢复广告;默认行为似乎是设备连接后将继续播发,因此我在事件处理程序handleStateConnected和handleStateConnected中分别添加了stopAdvertising和StartAvertising 手机现在进入一个iFine连接和重新连接的循环,原因是在呼叫stopAdve

在这里,我处理两个事件STATE\u CONNECTED和STATE\u DISCONNECTED

这里是处理程序状态\u已断开连接

在连接状态下,我希望我的手机停止广告,在断开连接状态下,我希望手机恢复广告;默认行为似乎是设备连接后将继续播发,因此我在事件处理程序handleStateConnected和handleStateConnected中分别添加了stopAdvertising和StartAvertising

手机现在进入一个iFine连接和重新连接的循环,原因是在呼叫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();
    }
}
这是StartAversing

这是startServer

下面是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;
}

这是我过去做过的一件有助于解决这个问题的事情。没有保证,但这是我找到的最好的解决办法

当您在服务器端获得STATE_CONNECTED事件时,调用BluetoothGattServer.connectBluetoothDevice,布尔值。这是我以前用过的一个片段

        @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;
            }
        }

这是我多年来一直在安卓上工作的一个问题。没有一种很好的方法可以在所有设备上解决这个问题。最近我有幸在AOSP平台上工作,我们在BlueDroid级别解决了这个问题。这就是问题的根源所在。@Greg Moens是否有安卓系统的解决方案?我发现没有任何一款可以在所有设备上运行。有一种修复方法似乎有所帮助。我得帮你把它挖出来。给我一点。不幸的是,它对我不起作用。我也很困惑,为什么要在已经连接的设备上调用connect。我想知道BluetoothGattServer.connect方法是否用于与某种广告侦听器结合使用,例如在接收、解析数据包时,然后在有效负载中的某些数据上,连接到的设备。很抱歉,它无法工作。这对我来说同样令人困惑,我总是假设它使服务器处于某种状态,意识到它不应该断开连接。这只虫子从棒棒糖开始就存在了,似乎哪儿也去不了。
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();
    }
}
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);
}
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;
    }
}
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;
}
        @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;
            }
        }