2016-07-07 16 views
12

Das ist der Werbetreibende (Hinweis data als AdvertiseData Typ bestanden)Android: Bluetooth Low Energy Scanner empfängt Null-Daten

private void advertise() { 
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    BluetoothLeAdvertiser advertiser = bluetoothAdapter.getBluetoothLeAdvertiser(); 
    AdvertiseSettings settings = new AdvertiseSettings.Builder() 
      .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED) 
      .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM) 
      .setConnectable(false) 
      .build(); 
    ParcelUuid pUuid = new ParcelUuid(UUID.fromString("cf2c82b6-6a06-403d-b7e6-13934e602664")); 
    AdvertiseData data = new AdvertiseData.Builder() 
      //.setIncludeDeviceName(true) 
      .addServiceUuid(pUuid) 
      .addServiceData(pUuid, "123456".getBytes(Charset.forName("UTF-8"))) 
      .build(); 
    AdvertiseCallback advertiseCallback = new AdvertiseCallback() { 
     @Override 
     public void onStartSuccess(AdvertiseSettings settingsInEffect) { 
      Log.i(tag, "Advertising onStartSuccess"); 
      super.onStartSuccess(settingsInEffect); 
     } 

     @Override 
     public void onStartFailure(int errorCode) { 
      Log.e(tag, "Advertising onStartFailure: " + errorCode); 
      super.onStartFailure(errorCode); 
     } 
    }; 
    advertiser.startAdvertising(settings, data, advertiseCallback); 
} 

Es beginnt erfolgreich.

Dies ist der Scanner

private void discover() { 
    ScanSettings settings = new ScanSettings.Builder() 
      .setScanMode(ScanSettings.SCAN_MODE_BALANCED) 
      .build(); 
    mBluetoothLeScanner.startScan(null, settings, mScanCallback); 
} 

private ScanCallback mScanCallback = new ScanCallback() { 
    @Override 
    public void onScanResult(int callbackType, ScanResult result) { 
     super.onScanResult(callbackType, result); 
     Log.i(tag, "Discovery onScanResult"); 
     if (result == null) { 
      Log.i(tag, "no result"); 
      return; 
     } 
     ScanRecord scanRecord = result.getScanRecord(); 
     List<ParcelUuid> list = scanRecord != null ? scanRecord.getServiceUuids() : null; 
     if (list != null) { 
      Log.i(tag, scanRecord.toString()); 
      for (ParcelUuid uuid : list) { 
       byte[] data = scanRecord.getServiceData(uuid); 
      } 
    } 

    @Override 
    public void onBatchScanResults(List<ScanResult> results) { 
     super.onBatchScanResults(results); 
     Log.i(tag, "Discovery onBatchScanResults"); 
    } 

    @Override 
    public void onScanFailed(int errorCode) { 
     super.onScanFailed(errorCode); 
     Log.e(tag, "Discovery onScanFailed: " + errorCode); 
    } 
}; 

In der Callback onScarnResult ich die Scan-Datensatz toString() protokollieren, die diesen Ausgang

ScanRecord [mAdvertiseFlags=2, 
     mServiceUuids=[cf2c82b6-6a06-403d-b7e6-13934e602664], 
     mManufacturerSpecificData={}, 
     mServiceData={000082b6-0000-1000-8000-00805f9b34fb=[49, 50, 51, 52, 53, 54]}, 
     mTxPowerLevel=-2147483648, mDeviceName=null] 

die UUID Matches erzeugt, leider das Ergebnis

byte[] data = scanRecord.getServiceData(uuid) 

ist null. bemerkte ich, dass die toString Ausgabe der ASCII-Codes der beworbenen Datenzeichen „123456“ hatte, die 49,50,51,52,53,54

mServiceData={000082b6-0000-1000-8000-00805f9b34fb=[49, 50, 51, 52, 53, 54]} 

sind Ich möchte das Recht beworben, Daten empfangen , mache ich etwas falsch?

EDIT: das Manifest hat Berechtigungen für Bluetooth, BT-Admin und Standort. Der dritte startet eine Anfrage zur Laufzeit in Android 6

EDIT: durch Drucken des gesamten Scanrecord Sie diese Ausgabe

Scanrecord bekommen [mAdvertiseFlags = -1, mServiceUuids = [cf2c82b6-6a06-403d-b7e6 -13934e602664], mManufacturerSpecificData = {}, { mServiceData = 000082b6-0000-1000-8000-00805f9b34fb = [49, 50, 51, 52, 53, 54]}, mTxPowerLevel = -2147483648, mDeviceName = null]

Grundsätzlich können Sie die Uuid d nicht verwenden Dies wird vom Werbetreibenden unterstützt, der sich im Array mServiceUuids befindet, da der mit mServiceData verknüpfte Schlüssel ein anderer ist. Also änderte ich den Code auf diese Weise die Datenzuordnung zu navigieren und den Wert bekommen (bitte sehen Sie die beiden if-Blöcke)

public void onBatchScanResults(List<ScanResult> results) { 
     super.onBatchScanResults(results); 
     for (ScanResult result : results) { 
      ScanRecord scanRecord = result.getScanRecord(); 
      List<ParcelUuid> uuids = scanRecord.getServiceUuids(); 
      Map<ParcelUuid, byte[]> map = scanRecord.getServiceData(); 
      if (uuids != null) { 
       for (ParcelUuid uuid : uuids) { 
        byte[] data = scanRecord.getServiceData(uuid); 
        Log.i(tag, uuid + " -> " + data + " contain " + map.containsKey(uuid)); 
       } 
      } 

      if (map != null) { 
       Set<Map.Entry<ParcelUuid, byte[]>> set = map.entrySet(); 
       Iterator<Map.Entry<ParcelUuid, byte[]>> iterator = set.iterator(); 
       while (iterator.hasNext()) { 
        Log.i(tag, new String(iterator.next().getValue())); 
       } 
      } 
     } 
    } 

In der Tat, die Linie

map.containsKey(uuid) 

false zurück, weil Die Uuid des Werbetreibenden wird von der Datenzuordnung nicht verwendet.

Ich musste die Karte navigieren, um den Wert zu finden (2. Wenn-Block), aber ich habe keine Mittel zu wissen, ob das der Wert ist, der mich interessiert. So oder so kann ich den Wert nicht erhalten wenn das System einen anderen Schlüssel eingibt, den ich nicht kenne, während ich den Code des Scanners in der Empfänger-App abspiele.

Wie kann ich mit diesem Problem auf dem Empfänger umgehen? Ich würde gerne das Datenfeld verwenden, aber der String-Schlüssel, um sie zu bekommen, ist nicht a priori bekannt und wird vom System entschieden.

Antwort

0

Versuchen Sie, die ScanFilter Hinzufügen und die Ergebnisse

private void discover() 
{ 
    List<ScanFilter> filters = new ArrayList<ScanFilter>(); 

    ScanFilter filter = new ScanFilter.Builder() 
      .setServiceUuid(new ParcelUuid(UUID.fromString( 
    getString(R.string.ble_uuid)))) 
      .build(); 
    filters.add(filter); 

Link zur Verwendung Quellcode retreive: https://github.com/tutsplus/Android-BluetoohLEAdvertising/blob/master/app/src/main/java/com/tutsplus/bleadvertising/MainActivity.java