18

Kurzversion:Verminderte BLE startScan Geräte auf Android erkannt 5.0 Lollipop

In meinen Tests mit Android 5.0 Lollipop Ich habe bemerkt, android.bluetooth.le.BluetoothLeScanner weniger BLE Geräte erkennt häufig als Android 4.4 KitKat. Warum ist das und gibt es eine Alternative?

Lange Version:

ich eine Android-Anwendung entwickle, die speziell für das Nexus 7 Tablette, die auf der Erfassung Bluetooth Low Energy (BLE) Geräte konzentriert. Die App interessiert sich hauptsächlich für den RSSI-Wert der Beacons, um ihre Nähe zum Tablet zu ermitteln. Das bedeutet, dass ich keine Verbindung zum BLE-Gerät herstellen muss, da der RSSI-Wert beim Erkennen des Geräts an den Scan-Callback übergeben wird.

In Android 4.4 KitKat, wenn ich BluetoothAdapter.startLeScan(LeScanCallback) anrufen, ruft mein Rückruf nur einmal für jedes erkannte BLE-Gerät. (Ich habe gesehen some discussions behaupten, dass dieses Verhalten je Gerät unterschiedlich sein kann) Ich interessiere mich jedoch für den ständig ändernden RSSI-Wert, so ist die derzeit empfohlene Möglichkeit, kontinuierlich startLeScan und stopLeScan mit einem festgelegten Intervall (250ms in meinem Fall):

Im Wesentlichen gibt dies mir die erforderlichen Ergebnisse, aber dieser Prozess ist sehr ressourcenintensiv und führt schließlich zu einem nicht reagierenden Bluetooth-Adapter.

Aus diesen Gründen habe ich mein Nexus 7 auf Android 5.0 Lollipop aufgerüstet, um zu sehen, ob meine BLE-Probleme behoben würden. In Lollipop ist BluetoothAdapter.startLeScan (LeScanCallback) veraltet und wird durch a new API ersetzt, was mehr Kontrolle über den Scanvorgang ermöglicht. Aus meinen ersten Tests scheint es startScan meinen Rückruf nicht ständig anrufen (auf meinem Nexus 7), wenn die RSSI-Werte ändern, so muß ich immer noch die startScan/stopScan Implementierung verwenden:

@TargetApi(21) 
public class TheNewWay { 

    private static final int SCAN_INTERVAL_MS = 250; 

    private Handler scanHandler = new Handler(); 
    private List<ScanFilter> scanFilters = new ArrayList<ScanFilter>(); 
    private ScanSettings scanSettings; 
    private boolean isScanning = false; 

    public void beginScanning() { 
     ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder(); 
     scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY); 
     scanSettings = scanSettingsBuilder.build(); 

     scanHandler.post(scanRunnable); 
    } 

    private Runnable scanRunnable = new Runnable() { 
     @Override 
     public void run() { 
      BluetoothLeScanner scanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner(); 

      if (isScanning) { 
       scanner.stopScan(scanCallback); 
      } else { 
       scanner.startScan(scanFilters, scanSettings, scanCallback); 
      } 

      isScanning = !isScanning; 

      scanHandler.postDelayed(this, SCAN_INTERVAL_MS); 
     } 
    }; 

    private ScanCallback scanCallback = new ScanCallback() { 
     @Override 
     public void onScanResult(int callbackType, ScanResult result) { 
      super.onScanResult(callbackType, result); 

      int rssi = result.getRssi(); 

      // do something with RSSI value 
     } 

     @Override 
     public void onScanFailed(int errorCode) { 
      super.onScanFailed(errorCode); 

      // a scan error occurred 
     } 
    }; 

} 

Wie Sie sehen können, Ich habe den Scanner mit der ScanSettings-Klasse konfiguriert, mit der Sie die scanMode einstellen können. Ich benutze ScanSettings.SCAN_MODE_LOW_LATENCY, die die folgende Dokumentation hat: "Scan mit höchster Auslastung. Es wird empfohlen, diesen Modus nur zu verwenden, wenn die Anwendung im Vordergrund ausgeführt wird." Klingt genau so, wie ich es will, aber leider bekomme ich nur alle 15 - 30 Sekunden eine Beacon-Erkennung, wobei die KitKat-Version mir alle 1 - 2 Sekunden das gleiche Beacon anzeigt.

Haben Sie eine Idee, was könnte der Grund für diesen Unterschied sein? Fehle ich etwas, vielleicht ein paar neue Einstellungen? Gibt es alternative Möglichkeiten, das oben genannte zu tun?

Vielen Dank im Voraus!

Abel

PS: Ich wollte mehr Links zu Ressourcen enthalten die ich verwendet habe, aber ich habe nicht die rep Punkte für ihn noch nicht.

+0

In Lollipop "startet startScan nicht ständig meinen Rückruf (auf meinem Nexus 7), wenn sich die RSSI-Werte ändern". Aber wird es mindestens einmal oder nur einmal wieder aufgerufen? Entschuldigung, ich habe kein Nexus 7 zum Testen. In meinem Nexus 5 wird es jede Sekunde in SCAN_MODE_LOW_POWER aufgerufen. – sorianiv

+0

@abelcookingfox Ich habe fast das gleiche schlimme Ergebnis wie du, ich benutze One-plus, CM ROM 5.0.2, manchmal das Scannen von über 30 Sekunden aufgerufen, aber manchmal ist es wie tot. Hast du jetzt eine Lösung? – Shawn

+0

Ich habe den Test erneut durchgeführt, mein One plus one Telefon scannt nur 2 Mal, dann würde dieser Callback nie mehr ausgelöst werden. – Shawn

Antwort

5

Ich habe sehr unterschiedliche Ergebnisse mit einem Nexus 5 bekommen, auf dem die neuen Android 5.0 Scanning-APIs laufen. Bei Verwendung von SCAN_MODE_LOW_LATENCY kam es bei BLE-Beacons alle 10 Sekunden zur Erkennung von BLE-Paketen fast in Echtzeit, bei BLE-Beacons, die mit 10 Hz senden.

Sie können die vollständigen Ergebnisse lesen Sie hier:

http://developer.radiusnetworks.com/2014/10/28/android-5.0-scanning.html

Diese Tests basieren aus der Open-Source-Android Beacon Library 2.0 experimentelle android-l-apis Zweig here laufen.

Es ist nicht offensichtlich, was der Unterschied in Ihren Testergebnissen ist, aber es ist möglich, dass das Starten und Stoppen des Scans die Ergebnisse verändert.

EDIT: ist es möglich, die Hardware ist der Unterschied. Sehen Sie einen Bericht ähnlicher Timings auf dem Nexus 4: https://github.com/AltBeacon/android-beacon-library/issues/59#issuecomment-64281446

+0

Danke für die Vorschläge, @davidgyoung! Irgendwelche Updates zu dieser Situation durch Zufall? :) – abelcookingfox

+0

Ich war nicht in der Lage, die Symptome, die Sie beschreiben, zu reproduzieren, also weiß ich nichts mehr als oben beschrieben. – davidgyoung

+0

Hallo David Könnten Sie mir bitte helfen, Scan-Intervall in lescan von Bluetooth in Android-Geräten mit Service hinzuzufügen. –

2

Ich habe sehr ähnliche Ergebnisse mit meinem Nexus 4, sowohl in KitKat und Lollipop erlebt.

Mit KitKat ging der Bluetooth-Adapter schließlich auch nicht mehr; Zuerst dachte ich, dass es mit einem kurzen Scanintervall (200ms) zusammenhängen könnte, aber das Erhöhen dieser Zahl auf eine Sekunde hat nicht geholfen. In diesem Fall habe ich festgestellt, dass manchmal das Problem gelöst wird, wenn der Programmadapter nicht aktiviert wird . Leider kann ich nicht sagen, dass es die ganze Zeit funktioniert.

Jetzt mit Lollipop, in dem ich große Hoffnungen hatte, diese Probleme zu lösen, erlebte ich das gleiche Verhalten, das Sie beschreiben. Ich musste auch die startScan/stopScan-Implementierung verwenden und ähnliche Ergebnisse in Bezug auf die Erkennungszeiten erhalten. Leider habe ich keine Arbeit gefunden, um schneller Ergebnisse zu erzielen.

Basierend auf dem, was Sie beschreiben, nehme ich an, es könnte ein Hardware-Problem sein, obwohl das Nexus 7 und Nexus 4 von verschiedenen Herstellern (Asus und LG) sind.

Ich weiß, dass ich hier nicht viel Hilfe neben dem Versuch, Ihre Frage zu beantworten, Ihnen etwas fehlt; Ich denke nicht, ich denke, das Problem ist so etwas wie die Hardware oder die Bluetooth-API, die sich immer noch nicht so verhält, wie es über verschiedene Geräte sein sollte.

+0

Danke, @marp. Im Moment werde ich weiter mit dem startScan/stopScan-Verfahren arbeiten. – abelcookingfox

5

Ich habe 50 Ruf für einen Kommentar noch nicht, also ertragen Sie mit mir, wird dieser Kommentar in Form einer Antwort sein. In Ihrem Code, sollte nicht dieser Teil:

if (isScanning) { scanner.startScan(...)

sein, dies statt:

if (!isScanning) { 
scanner.startScan(...) 

Da Ihr Code folgen, sind Sie stopScan() vor dem Starten eines Scan-Aufruf. Es kann sich nicht direkt auf das Ergebnis auswirken, wenn die Methode stopScan() idempotent/safe ist. Aber Sie wissen, um der Verständlichkeit des Codes willen sollten Sie die Frage bearbeiten. Und machen Sie dasselbe mit Ihrem Code, manchmal byzantinische Dinge sind im Spiel;)

Haben Sie größere Werte für SCAN_INTERVAL_MS versucht? Wenn ja, wie groß?

+0

Danke, ich habe meine Frage bearbeitet. Mein Code ist korrekt. :) Ja, ich habe ein Scan-Intervall von bis zu 1000 ms versucht, aber das bedeutet nur, dass Sie die Scan-Ergebnisse weniger häufig erhalten. Bei Verwendung eines Scanintervalls <200 kann der Bluetooth-Adapter Geräte nicht immer erkennen. – abelcookingfox

0

Wenn Sie auf Google nach BW13_DayOne_Session1 Bluetooth Advanced suchen, finden Sie ein PDF-Dokument, das Ihnen die Latenzzeiten für Geräte basierend auf den Einstellungen für die Erkennung bietet (siehe Seite 8). Ich nehme an, Ihr Problem hat mit diesen Zeiten zu tun. Sie können dies überprüfen, indem Sie die Werbekonfiguration für das getestete Gerät (Adv Int, Duty Cycle) ermitteln und dann herausfinden, was die API-Einstellungen für die Konfiguration des Scanintervalls usw. tun. Sobald Sie diese haben, können Sie diese Tabelle verwenden interpolieren, um zu sehen, ob Sie die Ergebnisse erhalten, die Sie erwarten.

Ich weiß, das ist eine Software-Site, aber oft bei der Anbindung an Hardware müssen Sie das Protokoll kennen, sonst Ihre Aufnahmen im Dunkeln.

+2

Konnten Sie dieses pdf posten? Ich kann es nicht finden. – bluewhile

+0

Die einzigen Google-Treffer für diesen Suchbegriff sind diese Seite und Spiegel davon! –

Verwandte Themen