BluetoothLeAdvertiser.stopAdvertising () вызывает отключение устройства - PullRequest
0 голосов
/ 01 декабря 2018

Здесь мой 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() соответственно.

Телефон теперь переходит вцикл соединения и повторного подключения ifinite, причина в том, что после вызова 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;
}

1 Ответ

0 голосов
/ 02 декабря 2018

Вот одна вещь, которую я сделал в прошлом, которая помогает с этой проблемой.Никаких гарантий, но это лучший обходной путь, который я нашел.

Когда вы получаете событие 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;
            }
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...