Android BLE API: GATT-Benachrichtigung nicht erhalten

70

Zum Testen verwendetes Gerät: Nexus 4, Android 4.3

Die Verbindung funktioniert einwandfrei, aber die onCharacteristicChangedMethode meines Rückrufs wird nie aufgerufen. Ich registriere mich jedoch für Benachrichtigungen mit setCharacteristicNotification(char, true)inside onServicesDiscoveredund diese Funktion gibt sogar true zurück.

Geräteprotokoll (es gibt eigentlich keine Nachrichten an alle , wenn Meldungen sollten erscheinen / werden über das Bluetooth - Gerät gesendet):

07-28 18:15:06.936  16777-16809/de.ffuf.leica.sketch D/BluetoothGatt: setCharacteristicNotification() - uuid: 3ab10101-f831-4395-b29d-570977d5bf94 enable: true
07-28 18:15:06.936    4372-7645/com.android.bluetooth D/BtGatt.GattService: registerForNotification() - address=C9:79:25:34:19:6C enable: true
07-28 18:15:06.936    4372-7645/com.android.bluetooth D/BtGatt.btif: btif_gattc_reg_for_notification
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.btif: btgattc_handle_event: Event 1018
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.GattService: onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=3ab10101-f831-4395-b29d-570977d5bf94
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.btif: btgattc_handle_event: Event 1016
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.btif: btgattc_handle_event: Event 1018
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.GattService: onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=3ab10102-f831-4395-b29d-570977d5bf94
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.btif: btgattc_handle_event: Event 1016
07-28 18:15:06.946    4372-7684/com.android.bluetooth E/bt-btif: already has a pending command!!
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.btif: btgattc_handle_event: Event 1013
07-28 18:15:06.946    4372-7684/com.android.bluetooth E/bt-btif: already has a pending command!!
07-28 18:15:06.946    4372-7645/com.android.bluetooth D/BtGatt.btif: btgattc_handle_event: Event 1013
07-28 18:15:06.946    4372-7684/com.android.bluetooth E/bt-btif: already has a pending command!!
07-28 18:15:06.976    4372-7645/com.android.bluetooth D/BtGatt.btif: btif_gattc_upstreams_evt: Event 9

GATT-Benachrichtigungen funktionieren unter iOS einwandfrei und die App funktioniert im Wesentlichen genauso wie unter Android (Registrierung für Benachrichtigungen usw.).

Hat jemand anderes dies mit einer möglichen Lösung erlebt?

Boni2k
quelle

Antworten:

83

Anscheinend haben Sie vergessen, den Deskriptor zu schreiben, der Ihr BLE-Gerät anweist, in diesen Modus zu wechseln. Weitere Informationen zum Deskriptor finden Sie in den Codezeilen unter http://developer.android.com/guide/topics/connectivity/bluetooth-le.html#notification

Ohne diesen Deskriptor erhalten Sie niemals Aktualisierungen eines Merkmals. Anrufen setCharacteristicNotificationist nicht genug. Dies ist ein häufiger Fehler.

Code abgeschnitten

protected static final UUID CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

public boolean setCharacteristicNotification(BluetoothDevice device, UUID serviceUuid, UUID characteristicUuid,
        boolean enable) {
    if (IS_DEBUG)
        Log.d(TAG, "setCharacteristicNotification(device=" + device.getName() + device.getAddress() + ", UUID="
                + characteristicUuid + ", enable=" + enable + " )");
    BluetoothGatt gatt = mGattInstances.get(device.getAddress()); //I just hold the gatt instances I got from connect in this HashMap
    BluetoothGattCharacteristic characteristic = gatt.getService(serviceUuid).getCharacteristic(characteristicUuid);
    gatt.setCharacteristicNotification(characteristic, enable);
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID);
    descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[] { 0x00, 0x00 });
    return gatt.writeDescriptor(descriptor); //descriptor write operation successfully started? 
}
Eine Welt
quelle
Ich habe gerade den Code aus Android 4.3-Beispielen ausprobiert, konnte ihn jedoch nicht benachrichtigen. Könnten Sie bitte die Codes teilen, die sich auf die Benachrichtigung beziehen? Vielen Dank.
ZhangChn
2
@ Boni2k GATT_NO_RESOURCES = -128 oder 128; GATT_INTERNAL_ERROR = -127 oder 129; GATT_ERROR = -123 oder 133; GATT_ALREADY_OPEN = -115 oder 141. Ich habe sie von den Samsung BLE Sdk-Leuten bekommen. Diese Statuscodes scheinen dem Android BLE SDK zu entsprechen, außer dass das Byte als Typ signiert wurde. Die ganze Liste ist hier: img-developer.samsung.com/onlinedocs/samsung_ble_docs_200/…
OneWorld
1
Ich sehe, dass ich eine Verzögerung (z. B. Thread.sleep oder Handler.post) zwischen setCharacteristicNotification und writeDescriptor induzieren muss. Wenn ich das nicht tue, bekomme ich nie den onCharacteristicChanged. Kann jemand bestätigen, dass er etwas Ähnliches sieht? Beachten Sie, dass das Beispiel unter developer.android.com/guide/topics/connectivity/… ein subtiles "..." zwischen den beiden Anrufen aufweist, was darauf hinweist, dass Sie diese beiden Anrufe nicht immer zuverlässig sofort ausführen können zurück.
Swooby
3
Es ist kein Fehler, es ist ein Fehler in der API. Der Sinn von setCharacteristicNotification besteht darin, Benachrichtigungen zu aktivieren - dies sollte festgelegt werden.
Glenn Maynard
6
Diese zusätzlichen notwendigen Schritte sollten wirklich dokumentiert werden. Es gibt zu viele und zu schwere undokumentierte Vorbehalte, die Entwickler bei der Implementierung der BLE-Kommunikation unter Android beachten müssen.
Lars Blumberg
42

@ Boni2k - Ich habe die gleichen Probleme. In meinem Fall habe ich 3 Benachrichtigungsmerkmale und eine Handvoll Lese- / Schreibmerkmale.

Was ich gefunden habe ist, dass es eine gewisse Abhängigkeit zwischen writeGattDescriptorund gibt readCharacteristic. Alle writeGattDescriptors müssen an erster Stelle stehen und vollständig sein, bevor Sie readCharacteristic-Aufrufe ausgeben.

Hier ist meine Lösung mit Queues . Jetzt bekomme ich Benachrichtigungen und alles andere funktioniert gut:

Erstellen Sie zwei Warteschlangen wie folgt:

private Queue<BluetoothGattDescriptor> descriptorWriteQueue = new LinkedList<BluetoothGattDescriptor>();
private Queue<BluetoothGattCharacteristic> characteristicReadQueue = new LinkedList<BluetoothGattCharacteristic>();

Schreiben Sie dann alle Ihre Deskriptoren unmittelbar nach der Entdeckung mit dieser Methode:

public void writeGattDescriptor(BluetoothGattDescriptor d){
    //put the descriptor into the write queue
    descriptorWriteQueue.add(d);
    //if there is only 1 item in the queue, then write it.  If more than 1, we handle asynchronously in the callback above
    if(descriptorWriteQueue.size() == 1){   
        mBluetoothGatt.writeDescriptor(d);      
    }
}

und dieser Rückruf:

public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {         
        if (status == BluetoothGatt.GATT_SUCCESS) {
            Log.d(TAG, "Callback: Wrote GATT Descriptor successfully.");           
        }           
        else{
            Log.d(TAG, "Callback: Error writing GATT Descriptor: "+ status);
        }
        descriptorWriteQueue.remove();  //pop the item that we just finishing writing
        //if there is more to write, do it!
        if(descriptorWriteQueue.size() > 0)
            mBluetoothGatt.writeDescriptor(descriptorWriteQueue.element());
        else if(readCharacteristicQueue.size() > 0)
            mBluetoothGatt.readCharacteristic(readQueue.element());
    };

Die Methode zum Lesen eines Merkmals sieht dann normalerweise folgendermaßen aus:

public void readCharacteristic(String characteristicName) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }
    BluetoothGattService s = mBluetoothGatt.getService(UUID.fromString(kYourServiceUUIDString));
    BluetoothGattCharacteristic c = s.getCharacteristic(UUID.fromString(characteristicName));
    //put the characteristic into the read queue        
    readCharacteristicQueue.add(c);
    //if there is only 1 item in the queue, then read it.  If more than 1, we handle asynchronously in the callback above
    //GIVE PRECEDENCE to descriptor writes.  They must all finish first.
    if((readCharacteristicQueue.size() == 1) && (descriptorWriteQueue.size() == 0))
        mBluetoothGatt.readCharacteristic(c);              
}

und mein gelesener Rückruf:

public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
        readCharacteristicQueue.remove();
        if (status == BluetoothGatt.GATT_SUCCESS) {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);                                
        }
        else{
            Log.d(TAG, "onCharacteristicRead error: " + status);
        }

        if(readCharacteristicQueue.size() > 0)
            mBluetoothGatt.readCharacteristic(readCharacteristicQueue.element());
    }
Miznick
quelle
4
Achten Sie auf die Synchronität der BLE-Implementierung in Android. Sie können Anfragen problemlos unfreiwillig stornieren, wenn Sie solche Warteschlangen nicht wie Sie verwenden. Siehe stackoverflow.com/questions/18011816/… Ich bin mir nicht sicher, ob writeDescriptor () vor readCharacteristic ausgeführt werden muss, wenn Sie mit Ihrer Annahme richtig liegen. Vielleicht kümmert sich Ihre Lösung (Warteschlangen) nur um die Synchronität und behebt Ihr Problem auf diese Weise. Ich lese und schreibe tatsächlich Eigenschaften, bevor ich den Deskriptor schreibe.
OneWorld
Ich glaube du hast recht. Die Transaktionen sind synchron und die Reihenfolge ist irrelevant. Jede Transaktion muss ihren Rückruf abschließen, bevor eine andere Transaktion ausgegeben wird, und alles funktioniert ordnungsgemäß. Es könnte sinnvoll sein, eine Warteschlange für alle Transaktionen zu verwenden und jede mit einem Typ zu versehen (Schreibdeskriptor,
Leseeigenschaft, Schreibcharakteristik
Ihr Code ist gut zu gehen, aber hier habe ich ein Problem, dies zu verwenden. Es gibt einige Probleme, mit denen ich konfrontiert bin, weil ich neu bei BLE bin. Bei readCharacteristicQueue und readQueue bekomme ich Fehler. Bitte fügen Sie einen vollständigen Code bei, um diesen Fehler zu beheben. Vielen Dank
Deepak
Code sieht theoretisch in Ordnung aus, aber manchmal bekomme ich keinen charakteristischen Rückruf, also ...
Thomas
1
Nordic hat eine Klasse geschrieben, die sich damit befasst GattManager. Siehe github.com/NordicSemiconductor/puck-central-android
Timmmm
11

Wenn Sie den Wert auf den Deskriptor setzen descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE), anstatt ihn zu setzen , setzen Sie descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE). Die Rückrufe für onCharacteristicChanged werden jetzt aufgerufen.

user2926265
quelle
Können Sie klarstellen, was "Indikation" tun soll? Aufgrund der Dokumente war ich mir sicher, dass das richtige Flag in diesem Fall ENABLE_NOTIFICATION_VALUE war, aber Sie sind jetzt die zweite Person auf dieser Seite, die vorgeschlagen hat, dass ENABLE_INDICATION_VALUE das richtige Flag ist. Was ist der Unterschied und Anwendungsfall für jeden?
Jkraybill
2
Dies hängt von der Implementierung des Bluetooth-Profils im Bluetooth-Gerät ab. Es wird entweder "Benachrichtigung" oder "Anzeige" zum Posten von Updates verwendet. Sie müssen also herausfinden, welches Ihr Gerät verwendet.
Boni2k
1
Wie Boni2k sagte, hängt es vom Bluetooth-Profil ab. Wenn Ihr Dienst den Standardprofilen folgt, sollten Sie diese Informationen [hier] finden können ( developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx ). Wenn Sie dies programmgesteuert wissen möchten, können Sie die Methode getProperties () für Ihr Merkmal aufrufen und ein bitweises UND für die Eigenschaft ausführen, die überprüft werden soll, ob sie sich von 0 unterscheidet. Diese Aktivität wird dann unterstützt.
user2926265
Was mich hier stört, ist, dass die Android-Dokumentation besagt, dass setCharacteristicNotifications für JEDE Benachrichtigungen oder Anzeigen funktioniert. Ich gehe also davon aus, dass sie die Eigenschaften intern überprüfen und die richtigen Flags in das Merkmal schreiben. Sie verwenden auch die Methode in ihrem Beispiel, die mit einigen HeartRate-Monitoren funktioniert hat. Wissen Sie, ob die Methode fehlerhaft ist? Mein Verständnis ist, dass man BEIDE Anzeige- / Benachrichtigungsflags nicht setzen kann, obwohl einige Geräte dies möglicherweise akzeptieren. Wenn sie das tun, würde ich sagen, dass ihre Methode falsch ist.
Brian Reinhold
6

Ich gehe davon aus (Sie haben Ihren Quellcode nicht angegeben), dass Sie ihn nicht wie von Google gewünscht implementiert haben :

(1)

mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);

und dann

(2)

BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);

Ich nehme an, 2 fehlt. In diesem Fall wird meiner Meinung nach eine Benachrichtigung auf niedriger Ebene ausgelöst, die jedoch niemals an die Anwendungsschicht gemeldet wird.

Marian Paździoch
quelle
6

In früheren Versionen von Android traten Probleme auf, die Benachrichtigungen erhielten (ein Hinweis, der registriert wurde), und es trat danach immer ein seltsames Trennungsereignis auf. Wie sich herausstellte, haben wir uns für Benachrichtigungen zu fünf Merkmalen registriert.

Der in LogCat entdeckte Fehler war:

02-05 16:14:24.990    1271-1601/? E/bt-btifMax Notification Reached, registration failed.

Vor 4.4.2 war die Anzahl der Registrierungen auf 4 begrenzt! 4.4.2 erhöhte diese Grenze auf 7.

Durch die Reduzierung der Anzahl der Registrierungen in früheren Versionen konnten wir diese Einschränkung umgehen.

Dan Wuensch
quelle
5
Auf 4 begrenzt? Worte können nicht beschreiben, wie erbärmlich das ist. Sogar 7 ist lächerlich.
Gregory Higley
4

Nun, dieser API-Name führt sicherlich zu einigen Verwirrungen für App-Entwickler, wenn er / sie nicht der Bluetooth-Hintergrundprogrammierer war.

Zitieren Sie aus Sicht der Bluetooth-Kernspezifikation aus der Kernspezifikation 4.2, Band 3, Teil G, Abschnitt 3.3.3.3 "Konfiguration der Client-Eigenschaften":

Der charakteristische Deskriptorwert ist ein Bitfeld. Wenn ein Bit gesetzt ist, muss diese Aktion aktiviert werden, andernfalls wird sie nicht verwendet.

und Abschnitt 4.10

Benachrichtigungen können mithilfe des Deskriptors für die Konfiguration der Clientmerkmale konfiguriert werden (siehe Abschnitt 3.3.3.3).

Dies besagt eindeutig, dass, wenn der Client die Benachrichtigung (oder Anzeige, die eine Antwort benötigt) vom Server erhalten möchte, das Bit "Benachrichtigung" auf 1 schreiben sollte ("Bit" Anzeige "auch ansonsten auf 1).

Der Name "setCharacteristicNotification" gibt uns jedoch einen Hinweis darauf, dass der Client Benachrichtigungen erhalten würde, wenn wir die Parameter dieser API als TURE festlegen. Leider hat diese API nur das lokale Bit gesetzt, um die Benachrichtigung zuzulassen, die an Apps gesendet wird, wenn eine Remote-Benachrichtigung eingeht. Siehe Code von Bluedroid:

    /*******************************************************************************
    **
    ** Function         BTA_GATTC_RegisterForNotifications
    **
    ** Description      This function is called to register for notification of a service.
    **
    ** Parameters       client_if - client interface.
    **                  bda - target GATT server.
    **                  p_char_id - pointer to GATT characteristic ID.
    **
    ** Returns          OK if registration succeed, otherwise failed.
    **
    *******************************************************************************/

    tBTA_GATT_STATUS BTA_GATTC_RegisterForNotifications (tBTA_GATTC_IF client_if,
                                                         BD_ADDR bda,
                                                         tBTA_GATTC_CHAR_ID *p_char_id)

{
    tBTA_GATTC_RCB      *p_clreg;
    tBTA_GATT_STATUS    status = BTA_GATT_ILLEGAL_PARAMETER;
    UINT8               i;

    if (!p_char_id)
    {
        APPL_TRACE_ERROR("deregistration failed, unknow char id");
        return status;
    }

    if ((p_clreg = bta_gattc_cl_get_regcb(client_if)) != NULL)
    {
        for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
        {
            if ( p_clreg->notif_reg[i].in_use &&
                 !memcmp(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN) &&
                  bta_gattc_charid_compare(&p_clreg->notif_reg[i].char_id, p_char_id))
            {
                APPL_TRACE_WARNING("notification already registered");
                status = BTA_GATT_OK;
                break;
            }
        }
        if (status != BTA_GATT_OK)
        {
            for (i = 0; i < BTA_GATTC_NOTIF_REG_MAX; i ++)
            {
                if (!p_clreg->notif_reg[i].in_use)
                {
                    memset((void *)&p_clreg->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));

                    p_clreg->notif_reg[i].in_use = TRUE;
                    memcpy(p_clreg->notif_reg[i].remote_bda, bda, BD_ADDR_LEN);

                    p_clreg->notif_reg[i].char_id.srvc_id.is_primary = p_char_id->srvc_id.is_primary;
                    bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.srvc_id.id, &p_char_id->srvc_id.id);
                    bta_gattc_cpygattid(&p_clreg->notif_reg[i].char_id.char_id, &p_char_id->char_id);

                    status = BTA_GATT_OK;
                    break;
                }
            }
            if (i == BTA_GATTC_NOTIF_REG_MAX)
            {
                status = BTA_GATT_NO_RESOURCES;
                APPL_TRACE_ERROR("Max Notification Reached, registration failed.");
            }
        }
    }
    else
    {
        APPL_TRACE_ERROR("Client_if: %d Not Registered", client_if);
    }

    return status;
}'

Was also zählte, war die Deskriptor-Schreibaktion.

Guo Xingmin
quelle
1

Hier ist eine einfache Möglichkeit, aber lassen Sie mich wissen, wenn Sie Nachteile feststellen.

Schritt 1 Deklarieren Sie boolesche Variablen

private boolean char_1_subscribed = false;
private boolean char_2_subscribed = false;
private boolean char_3_subscribed = false;

Schritt 2 Abonnieren Sie das erste Merkmal im Rückruf onServicesDiscovered:

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    if (status == BluetoothGatt.GATT_SUCCESS) {
        broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
    } else {
        Log.w(TAG, "onServicesDiscovered received: " + status);
    }
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if(!char_1_subscribed)
        subscribeToNotification(gatt.getService(UUID_SERVICE).getCharacteristic(UUID_CHAR_1)); char_1_subscribed = true;
}

Schritt 3

Abonnieren Sie andere, nachdem der Rückruf onCharacteristicChanged ausgelöst wurde

@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
                                    BluetoothGattCharacteristic characteristic) {
    if(UUID_CHAR_1.equals(characteristic.getUuid()))
    {
        if(!char_1_subscribed)
            subscribeToNotification(gatt.getService(UUID_SERVICE).getCharacteristic(UUID_CHAR_2)); char_2_subscribed = true;
    }
    if(UUID_CHAR_2.equals(characteristic.getUuid()))
    {
        if(!char_3_subscribed)
            subscribeToNotification(gatt.getService(UUID_SERVICE).getCharacteristic(UUID_CHAR_3)); char_3_subscribed = true;
    }
}
JBaczuk
quelle
1

Dieser arbeitet für mich:

Rufen Sie diese Funktion auf Ihrem Peripheriegerät auf, um das Master-Gerät über eine Änderung einer Eigenschaft zu informieren:

private BluetoothGattServer server;
//init....

//on BluetoothGattServerCallback...

//call this after change the characteristic
server.notifyCharacteristicChanged(device, characteristic, false);

in Ihrem Master-Gerät: Aktivieren Sie setCharacteristicNotification, nachdem Sie den Dienst erkannt haben:

@Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        services = mGatt.getServices();
        for(BluetoothGattService service : services){
            if( service.getUuid().equals(SERVICE_UUID)) {
                characteristicData = service.getCharacteristic(CHAR_UUID);
                for (BluetoothGattDescriptor descriptor : characteristicData.getDescriptors()) {
                    descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                    mGatt.writeDescriptor(descriptor);
                }
                gatt.setCharacteristicNotification(characteristicData, true);
            }
        }
        if (dialog.isShowing()){
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    dialog.hide();
                }
            });
        }
   }

Jetzt können Sie überprüfen, ob sich Ihr charakteristischer Wert ändert, z. B. die Funktion onCharacteristicRead (dies funktioniert auch für die Funktion onCharacteristicChanged):

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        Log.i("onCharacteristicRead", characteristic.toString());
        byte[] value=characteristic.getValue();
        String v = new String(value);
        Log.i("onCharacteristicRead", "Value: " + v);
}
Doni
quelle
0

Ich hatte noch einen weiteren Grund, den ich hinzufügen möchte, da er mich den ganzen Tag verrückt gemacht hat:

Auf meinem Samsung Note 3 habe ich keine Benachrichtigungen über geänderte Werte erhalten, während der gleiche Code auf jedem anderen Gerät funktioniert hat, mit dem ich getestet habe.

Durch einen Neustart des Geräts wurden alle Probleme behoben. Offensichtlich, aber wenn Sie in dem Problem sind, vergessen Sie zu denken.

Christian
quelle
-1

Ich habe die Probleme mit Benachrichtigungen für BLE auch auf Android erlebt. Es gibt jedoch eine voll funktionsfähige Demo, die einen Bluetooth-Wrapper enthält BluetoothAdapter. Der Wrapper wird aufgerufen BleWrapperund mit der Demo-Anwendung BLEDemo geliefert, die im Application Accelerator- Paket enthalten ist. Hier herunterladen: https://developer.bluetooth.org/Pages/Bluetooth-Android-Developers.aspx . Sie müssen sich vor dem Herunterladen mit Ihrer E-Mail-Adresse oben rechts registrieren. Die Projektlizenz ermöglicht die kostenlose Nutzung, Codeänderung und Veröffentlichung.

Meiner Erfahrung nach verarbeitet die Android-Demoanwendung BLE-Benachrichtigungsabonnements sehr gut. Ich habe noch nicht zu viel in den Code eingetaucht, um zu sehen, wie der Wrapper tatsächlich verpackt wird.

Im Play Store ist eine Android-App verfügbar, mit der die Application Accelerator- Demo angepasst werden kann . Da die Benutzeroberfläche fast gleich aussieht, wird sie vermutlich auch verwendet BleWrapper. Laden Sie die App hier herunter: https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner

Lars Blumberg
quelle