2015-11-11 4 views
6

Holen Ich versuche, die UUID von einem entfernten Bluetooth-Gerät wie dieses zu holen:Android 6.0 Anfragen Paarung mit Remote-Geräten, wenn UUID

 device.fetchUuidsWithSdp(); 

Dies funktioniert geräuschlos und ohne Zutun des Benutzers auf allen Geräten außer denen mit Android 6.0, die sichtbar mit einem Paarungsdialog fragt, um sich mit dem entfernten Gerät zu verbinden, um die UUID zu holen. Ist das ein erwartetes Verhalten? Wo ist das dokumentiert? Gibt es eine Möglichkeit, die UUID-Erkennung auszulösen, ohne sie explizit vom anderen Ende zulassen zu müssen?

+0

auf den Quellcode des BluetoothDevice Sah Arbeit für [Lutscher] (https://android.googlesource.com /platform/frameworks/base/+/lollipop-release/core/java/android/bluetooth/BluetoothDevice.java#1013) und [Marshmallow] (https://android.googlesource.com/platform/frameworks/base/+/ Marshmallow-Release/Core/Java/Android/Bluetooth/BluetoothDevice.java # 1081) aber nur eine Runtime-Berechtigung Anmerkung hinzugefügt wurde. Also kann ich nicht erklären warum ein "Pairing Dialog" erscheint. Vielleicht, um dem Benutzer bewusst zu machen, dass Sie mit einem Gerät kommunizieren? –

+0

@jmols vielleicht. Aber deshalb möchte ich eine offizielle Antwort von Google. Das Abrufen von UUIDs bedeutet nicht notwendigerweise den Zugriff auf persönliche Daten. Ich würde viel lieber einen Dialog zeigen, wenn eine sichere Socket-Verbindung hergestellt wird und nicht vorher. –

+0

@dustedrob das Abrufen von UUIDs bedeutet die Verwendung von Standortberechtigungen. –

Antwort

3

ich eine Abhilfe zu dies mit der versteckten sdpSearch Methode gefunden haben, statt fetchUuidsWithSdp. Dies erfordert ein wenig Nachdenken. Das funktionierte für mich auf Android 6.0 und 5.1.1, ohne dass die Geräte versuchen zu koppeln. Hoffe, dass dies hilft, und fühlen Sie sich frei, die eher schlechte Ausnahmebehandlung zu verbessern.

public class DeviceFinder{ 

public interface Callback{ 
    void onDeviceFound(BluetoothDevice bd); 
    void onFinishedCallback(); 
    void onStartCallback(); 
} 

private ArrayList<BluetoothDevice> tempDevices = new ArrayList<>(); 
private Callback mCallback; 
private Context mContext; 
private String ACTION_SDP_RECORD; 
private String EXTRA_SDP_SEARCH_RESULT; 

private BroadcastReceiver mReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 
     if (BluetoothDevice.ACTION_FOUND.equals(action)){ 
      // Aggregating found devices 
      BluetoothDevice bd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      tempDevices.add(bd); 
     }else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){ 
      // Prepare for new search 
      tempDevices = new ArrayList<>(); 
      mCallback.onStartCallback(); 
     }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){ 
      // Do a sdpSearch for all found devices 
      for (BluetoothDevice bd : tempDevices){ 
       try { 
        Method m = bd.getClass().getDeclaredMethod("sdpSearch", ParcelUuid.class); 
        m.invoke(bd, new ParcelUuid(/* your uuid here */)); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
      mCallback.onFinishedCallback(); 
     }else if(ACTION_SDP_RECORD.equals(action)){ 
      // check if the device has the specified uuid 
      BluetoothDevice bd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      if (intent.getIntExtra(EXTRA_SDP_SEARCH_RESULT, 1) == 0){ 
       mCallback.onDeviceFound(bd); 
      } 
     } 
    } 
}; 


public DeviceFinder(Context context, Callback mCallback){ 
    this.mCallback = mCallback; 
    this.mContext = context; 

    try { 
     Field f = BluetoothDevice.class.getDeclaredField("ACTION_SDP_RECORD"); 
     ACTION_SDP_RECORD = ((String)f.get(null)); 
     f = BluetoothDevice.class.getDeclaredField("EXTRA_SDP_SEARCH_STATUS"); 
     EXTRA_SDP_SEARCH_RESULT = ((String)f.get(null)); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 


    IntentFilter intentFilter = new IntentFilter(); 
    intentFilter.addAction(BluetoothDevice.ACTION_FOUND); 
    intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); 
    intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 
    intentFilter.addAction(ACTION_SDP_RECORD); 
    context.registerReceiver(mReceiver, intentFilter); 
    startScan(); 
} 

public void startScan(){ 
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    if (!bluetoothAdapter.isDiscovering()) { 
     bluetoothAdapter.startDiscovery(); 
    } 
} 

public void unregisterReciever(){ 
    mContext.unregisterReceiver(mReceiver); 
} 
} 

edit: sdpSearch wurde in Android 6.0 hinzugefügt, so dass es nicht für frühere Versionen

+0

Sehr interessant! Ich probiere es aus und melde mich so schnell wie möglich. –

+2

Nach wochenlangen Tests funktioniert es super. Nur um für jeden anderen klar zu machen, dass diese versteckte Methode nur mit Android 6.0 beginnt. Vielen Dank! –

2

Update

Google's official response to your question:

Hallo, Wir verstehen Sie Abfrage auf bestimmte Verwendung haben, die hier nachgeschlagen in Stackoverflow werden kann.

https://stackoverflow.com/questions/14812326/android-bluetooth-get-uuids-of-discovered-devices

Dank


In Android 6.0 gibt es Änderungen an Berechtigungen. Einführung von Laufzeitberechtigungen, anstatt einer globalen Akzeptanz aller App erforderlichen Berechtigungen bei der Installation der App.

Kurz gesagt, sind die Berechtigungstypen in zwei Typen unterteilt, normal oder gefährlich. Jede Erlaubnis, die in die Privatsphäre eines Benutzers eingreift, wird als gefährlich angesehen.

Berechtigungen werden auch in Gruppen ähnlicher Berechtigungen platziert, z. B. für den Zugriff auf den genauen Standort und den groben Standort.

Benutzer haben bei der Verwendung der App die Wahl, die Erlaubnis einer bestimmten Gruppe zu akzeptieren, die als gefährlich angesehen wird. Sobald die Berechtigung für eine bestimmte Gruppe für diesen App-Lauf erteilt wurde, wird sie nicht erneut nach Berechtigungen innerhalb derselben Gruppe gefragt, sondern nach Berechtigungen von anderen Gruppen gefragt.

Details siehe unten:

Runtime permisssions.

Diese Version enthält ein neues Berechtigungsmodell, mit dem Benutzer die App-Berechtigungen zur Laufzeit direkt verwalten können. Dieses Modell bietet Benutzern eine verbesserte Transparenz und Kontrolle über Berechtigungen, während die Installations- und Auto-Update-Prozesse für App-Entwickler optimiert werden. Benutzer können Berechtigungen für installierte Apps einzeln erteilen oder entziehen.

In Ihren Apps, die auf Android 6.0 (API-Level 23) oder höher abzielen, sollten Sie sicherstellen, dass Sie zur Laufzeit nach Berechtigungen suchen und diese anfordern. Um festzustellen, ob für Ihre App eine Berechtigung erteilt wurde, rufen Sie die neue Methode checkSelfPermission() auf. Rufen Sie die neue requestPermissions() -Methode auf, um eine Berechtigung anzufordern. Auch wenn Ihre App nicht auf Android 6.0 (API-Level 23) ausgerichtet ist, sollten Sie Ihre App unter dem neuen Berechtigungsmodell testen.

.../

Beginning with Android 6.0 (API level 23) Benutzer gewähren und App-Berechtigungen zur Laufzeit widerrufen, anstatt so zu tun, wenn sie die App installieren.Daher müssen Sie Ihre App unter weiteren Bedingungen testen. Vor Android 6.0 konnten Sie vernünftigerweise davon ausgehen, dass, wenn Ihre App überhaupt ausgeführt wird, sie über alle Berechtigungen verfügt, die sie im App-Manifest deklariert. Unter dem neuen Berechtigungsmodell können Sie diese Annahme nicht mehr treffen.

Berechtigungen gelten als normal or dangerous

Bluetooth Zugriff als normaler Erlaubnis angesehen wird, während die Paarung oder Details einer App das Lesen als gefährlich angesehen wird.

Gefährliche Berechtigungen umfassen Bereiche, in denen die App Daten oder Ressourcen benötigt, die private Informationen des Benutzers enthalten oder potenziell die gespeicherten Daten des Benutzers oder den Betrieb anderer Apps beeinträchtigen könnten. Zum Beispiel ist die Fähigkeit, die Kontakte des Benutzers zu lesen, eine gefährliche Erlaubnis. Wenn eine App erklärt, dass sie eine gefährliche Berechtigung benötigt, muss der Benutzer der App explizit die Berechtigung erteilen.

Also, wenn Informationen von einem Gerät anfordert:

Wenn eine App eine gefährliche Erlaubnis in seinem Manifest aufgeführte anfordert, und die App haben derzeit keine Berechtigungen in der Berechtigungsgruppe, zeigt das System ein Dialogfeld für den Benutzer, der die Berechtigungsgruppe beschreibt, auf die die App zugreifen möchte. Das Dialogfeld beschreibt nicht die spezifische Berechtigung in dieser Gruppe. Wenn beispielsweise eine App die Berechtigung READ_CONTACTS anfordert, wird im Systemdialogfeld lediglich angegeben, dass die App Zugriff auf die Kontakte des Geräts benötigt. Wenn der Benutzer eine Genehmigung erteilt, gibt das System der App nur die angeforderte Berechtigung.

Details zur Implementierung siehe Working With System Permissions.


bearbeitenAls Reaktion auf your- Kommentar

enter image description here

Es multiple issues mit bluetooth bugs und die Veröffentlichung von Android 6.0 sind. Wie es mit 5.0 war, wird erwartet, dass diese mit dem nächsten Patch behoben werden. Allerdings sehe ich dein Problem nicht als Fehler.

Und nachdem ich your post here on google gesehen habe, antwortet meine Antwort direkt, was Sie als ein Fehler wahrnehmen.

Ihr Screenshot:

enter image description here

Und von your code here on github:

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.1" 

    defaultConfig { 
     applicationId "me.bluetoothuuidsample" 
     minSdkVersion 18 
     targetSdkVersion 23 
     versionCode 1 
     versionName "1.0" 
    } 

Die Eibisch Geräte genau verhalten, wie sie mit Laufzeitberechtigungen bestimmt sind, aber ich bin sicher, dass Google dies bestätigen für dich.

Um zu verhindern, mit der Umstellung zu diesem Zeitpunkt beschäftigen zu müssen, verwenden Sie das Ziel sdk als weniger als 23.

targetSdkVersion 22 

Dieser Blog Cheese bis ins Detail geht.Everything every Android Developer must know about new Android's Runtime Permission

bearbeiten 2

Fetching UUIDs erfordert Standort Erlaubnis, gibt es einen Beitrag hier das geht mehr ins Detail ist: https://stackoverflow.com/a/33045489/3956566

+0

Entschuldigung, das hat nichts mit dem Problem zu tun. Ich bin mir bewusst, dass das Bluetooth-Scannen Standortberechtigungen erfordert, aber ich habe es bereits hinzugefügt. –

+1

@dustedrob Ich empfehle dringend, dass Sie meine Antwort durchlesen, da sie Ihr Problem zu 100% anspricht. Meine Antwort bezieht sich nicht auf 'Bluetooth-Scanning erfordert Location-Berechtigungen' Es spricht Laufzeit-Permissions an und verwendet als Beispiel für Gruppen die Standortberechtigungen –

Verwandte Themen