Подтвердить что ты не робот

Android BluetoothGatt - статус 133 - регистрация обратного вызова

Прежде всего, я прочитал SOLVED: обратный вызов GATT не смог зарегистрировать и сделал шаги, предложенные в этом сообщении, для решения этой проблемы без успеха. Рекомендуемое исправление там, если вы еще не прочитали, это сделать все вызовы BLE из основного потока напрямую или с помощью обработчика.

Я работаю над приложением BLE, которое хочет запустить службу (вызываемую из активности каждые 10 секунд), которая выполняет следующие задачи:

1)Gets list of our products available to connect to (done, works)

2)For each available device:

          2a)connect to device
          2b)discover services
          2c)read 5 characteristics in this fashion:
             2c1)read characteristic
             2c2)onCharacteristicRead parse data
             2c3)when finished with data read next characteristic
             2c4)repeat until all are read (this is done using a state var and switch statement)
         2d)disconnect from device
         2e)connect to next device
         2f)repeat until all devices are read from
         2g)stopSelf()

Итак, проблема... Все отлично работает для немного. Я могу выполнить весь запуск службы {startService (...); в mainActivity}, чтобы закончить {stopSelf(); в службе} 6 раз.

В 7-й раз я получаю BluetoothGatt Не удалось зарегистрировать обратный вызов. Я не уверен, почему я могу запустить его 6 раз успешно, а затем провалиться в 7-й раз.

Имейте в виду, что я делаю все вызовы BLE из основного потока, и это было подтверждено в журнале cat из нескольких мест.

Вот схема моего кода:

SERVICE.JAVA

private Handler handler = new Handler();
private BluetoothGatt cGatt = null;
private int unitIndex = 0; // keep track of currently connected unit
private int state = 0; //used to keep track of which characteristic to read next

public int onStartCommand(Intent intent, int flags, int startId) 
{
    Log.i(TAG, "Service Started...");
    //get ArrayList of units

    if(units.size > 0)
        handler.post(connectNextRunnable); //calls connectNextDevice()
    else
        stopSelf();   
}

private Runnable discoverServices = new Runnable()
{
    public void run()
    {
        cGatt.discoverServices();
    }
}

private Runnable readNextValue = new Runnable()
{
    public void run()
    {
        BluetoothGattCharacteristic c = null;
        switch(state)
        {
            //set c to appropriate characteristic
        default: // all characteristics read
            unitIndex++;
            handler.post(connectNextRunnable)
            return
        }

        cGatt.readCharacteristic(c);
    }
}

private void connectNextDevice()
{
    if(unitIndex == 0)
        store System.nanoTime in variable

    if(unitIndex >= units.size) //finished will all units
        stopSelf();

    if(unitIndex < units.size)
        cGatt.disconnect //if null
        cGatt.connectGatt(this, false, gattCallback)
}

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() 
{
    public void onConnectionStateChange() 
    {
        handler.post(discoverServices);
    }

    public void onServicesDeiscovered() 
    {
        handler.post(readNextValue);
    }

    public void onCharacteristicRead() 
    {
        ParseData();
    }

    private void ParseData()
    {
        //do stuff with data
        handler.post(readNextValue);
    }
}

Итак, как я уже сказал, все элементы BLE вызывается из основного потока через обработчик. Служба успешно работает 6 раз от начала до конца. В 7-й раз я получаю, что немой не удалось зарегистрировать обратный вызов.

Я могу предоставить больше информации о logcat, если вы считаете, что это актуально. Я не был в исходном сообщении, потому что я выводил много информации для проверки полученных данных и т.д.

Ниже приведена информация о logcat для 7-го запуска моей службы от начала до конца.

08-15 12:00:10.746: I/PMIQ BTS(32027): Service Started...
08-15 12:00:10.746: I/PMIQ BTS(32027): Units: 1
08-15 12:00:10.746: D/AbsListView(32027): unregisterIRListener() is called 
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to next device...
08-15 12:00:10.766: I/PMIQ BTS(32027): Unit index = 0
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to pmIQ-IQ130_D93A
08-15 12:00:10.766: I/System.out(32027): main
08-15 12:00:10.766: D/BluetoothGatt(32027): connect() - device: 00:1E:C0:19:D9:3A, auto: false
08-15 12:00:10.766: D/BluetoothGatt(32027): registerApp()
08-15 12:00:10.766: D/BluetoothGatt(32027): registerApp() - UUID=e9d10870-4b09-451c-a9fa-c6b5f3594a77
08-15 12:00:10.766: I/BluetoothGatt(32027): Client registered, waiting for callback
08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0
08-15 12:00:10.766: I/PMIQ BTS(32027): CONECTION STATE CHANGED...Binder_2
**08-15 12:00:10.766: E/BluetoothGatt(32027): Failed to register callback**
08-15 12:00:10.766: I/PMIQ BTS(32027): Could not connect to null ... 257
08-15 12:00:10.766: I/PMIQ BTS(32027): Connecting to next device...
08-15 12:00:10.766: I/PMIQ BTS(32027): Unit index = 1
08-15 12:00:10.766: I/PMIQ BTS(32027): ******************************
08-15 12:00:10.766: I/PMIQ BTS(32027): Start Time: 4360642409647
08-15 12:00:10.766: I/PMIQ BTS(32027): End Time: 4360648970925
08-15 12:00:10.766: I/PMIQ BTS(32027): Difference: 6561278
08-15 12:00:10.766: I/PMIQ BTS(32027): Time to complete: 6
08-15 12:00:10.766: I/PMIQ BTS(32027): ******************************
08-15 12:00:10.876: I/PMIQ BTS(32027): ...Service Destroyed

Если вы сделали это здесь, спасибо! Я не мог найти ЛЮБОЙ информации о том, что означает = 133 означает?! Это происходит только тогда, когда обратный вызов завершается с ошибкой. Каждый раз это статус = 0.

08-15 12:00:10.766: D/BluetoothGatt(32027): onClientRegistered() - status=133 clientIf=0

Если бы кто-нибудь мог ответить на это, это могло бы мне очень помочь. Или, если кто-нибудь скажет мне, почему он работает только 6 раз. Может быть полезно любое понимание или догадка!

Спасибо всем!

4b9b3361

Ответ 1

Хорошо, я понял это. Проблема заключалась в основном в контроле, когда я читал документацию BluetoothGatt. Я звонил .disconnect(), но не .close(). Поскольку Galaxy s4 может обрабатывать только 6 подключений одновременно, моя служба работает только 6 раз. Добавление .close() в мой код позволило ему правильно отключить соединение и освободить эти используемые соединения.

Источник, из-за которого я перечитал документы более внимательно!

Поэтому не забудьте использовать .close() на вашем объекте BluetoothGatt, если у вас есть повторяющееся соединение с одним и тем же устройством!

Ответ 2

После нескольких месяцев исследований и выдергивания волос я нашел решение, о котором обычно не говорят.

Ваш обычный запрос на подключение выглядит примерно так:

cGatt.connectGatt(this, false, gattCallback);

Существует еще одна версия команды connectGatt с 4-м параметром. Этот параметр указывает, к какому типу устройства Bluetooth вы подключаетесь. Я добавил "2", чтобы указать, что я подключаюсь через Bluetooth LE. (это называется "транспорт", простите, если мое объяснение неверно, но оно решило все мои проблемы)

Попробуй это:

cGatt.connectGatt(this, false, gattCallback, 2);

И БАМ, теперь мой кошмар # 133 закончен (я молюсь)!

Ответ 3

ОС Android <6.0 :

mBluetoothDevice.connectGatt(context, false, callback);

ОС Android> = 6.0 :

mBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);

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

Ответ 4

Попробуйте использовать следующий обходной путь:

private static boolean gatt_status_133 = false;

final Handler handler = new Handler();

public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {

    if (newState == BluetoothProfile.STATE_CONNECTED) {
        mConnectionState = STATE_CONNECTED;
        Log.i(TAG, "Connected to GATT server.");
        // Attempts to discover services after successful connection.
        Log.i(TAG, "Attempting to start service discovery:" +
                mBluetoothGatt.discoverServices());

    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
        if(status == 133)
        {
            gatt_status_133=true;
        }
        else{
            mConnectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server."); 
        }
    }
}


@RequiresApi(api = Build.VERSION_CODES.M)
public boolean connect(final String address) {
    if (mBluetoothAdapter == null || address == null) {
        Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
        return false;
    }

    // Previously connected device.  Try to reconnect.
    if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
            && mBluetoothGatt != null) {
        Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
        if (mBluetoothGatt.connect()) {
            mConnectionState = STATE_CONNECTING;
            return true;
        } else {
            return false;
        }
    }

    final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    if (device == null) {
        Log.w(TAG, "Device not found.  Unable to connect.");
        return false;
    }

    mBluetoothGatt= device.connectGatt(this, false, mGattCallback, BluetoothDevice.TRANSPORT_LE);
    Log.d(TAG, "Trying to create a new connection.");
    mBluetoothDeviceAddress = address;
    mConnectionState = STATE_CONNECTING;

    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if(gatt_status_133)
            {
                Log.d(TAG, "Catch issue");
                connect(address);
                gatt_status_133=false;
            }
        }
    }, 4000);

    return true;
}

Ответ 5

  • На некоторых устройствах это исправленоmBluetoothDevice.connectGatt(context, false, callback, BluetoothDevice.TRANSPORT_LE);

  • на некоторых устройствах, таких как Samsung S7, A8, была проблема с ScanSettings.Builder(). setReportDelay (400)//или 500 мс. оно не должно быть 0 или больше, например 1000 мс. ScanSettings settings = new ScanSettings.Builder() .setScanMode(ScanSettings.SCAN_MODE_BALANCED) .setReportDelay(400) .build();