2015-11-11 8 views
6

sto cercando di recuperare i UUID da un dispositivo Bluetooth remoto come questo:Android 6.0 richieste di accoppiamento con dispositivi remoti quando va a prendere UUID

 device.fetchUuidsWithSdp(); 

Questo funziona silenziosamente e senza l'interazione dell'utente su tutti i dispositivi ad eccezione di quelli con Android 6.0 che chiede visibilmente con una finestra di dialogo di accoppiamento per connettersi con il dispositivo remoto per recuperare l'UUID. È un comportamento previsto? Dove è documentato? C'è un modo per attivare la scoperta UUID senza doverlo esplicitamente consentire dall'altra parte?

+0

guardato il codice sorgente del BluetoothDevice per [lecca-lecca] (https://android.googlesource.com /platform/frameworks/base/+/lollipop-release/core/java/android/bluetooth/BluetoothDevice.java#1013) e [marshmallow] (https://android.googlesource.com/platform/frameworks/base/+/ marshmallow-release/core/java/android/bluetooth/BluetoothDevice.java # 1081) ma è stata aggiunta solo un'annotazione di autorizzazione al runtime. Quindi non posso spiegare perché compare una "finestra di dialogo di accoppiamento". Forse per rendere l'utente consapevole del fatto che stai comunicando con un dispositivo? –

+0

@jmols forse. Ma è per questo che vorrei una risposta ufficiale da parte di Google. Recuperare UUID non significa necessariamente accedere ai dati personali. Preferisco di gran lunga mostrare una finestra di dialogo quando viene stabilita una connessione socket sicura e non prima. –

+0

@dustedrob recuperare UUID significa utilizzare le autorizzazioni di posizione. –

risposta

3

ho trovato una soluzione a questo utilizzando il metodo sdpSearch nascosto invece di fetchUuidsWithSdp. Ciò richiede un po 'di riflessione. Questo ha funzionato per me su Android 6.0 e 5.1.1, senza che i dispositivi provassero ad accoppiarsi. Spero che questo aiuti e sentiti libero di migliorare la gestione delle eccezioni piuttosto scarsa.

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 è stato aggiunto in Android 6.0, in modo che non funziona per le versioni precedenti

+0

Molto interessante! Lo proverò e ti ricontatterò il prima possibile. –

+2

Dopo settimane di test funziona alla grande. Giusto per chiarire a chiunque altro che questo metodo nascosto esiste solo a partire da Android 6.0. Grazie! –

2

aggiornamento

Google's official response to your question:

Ciao, Ci risulta che ha query particolare utilizzo, che possono essere consultati qui a StackOverflow.

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

Grazie


In Android 6.0 vi sono modifiche alle autorizzazioni. Presentazione delle autorizzazioni di runtime, piuttosto che l'accettazione globale di tutte le autorizzazioni necessarie dell'app all'installazione dell'applicazione.

In breve, i tipi di autorizzazioni sono genericamente inseriti in due tipi, normali o pericolosi. Qualsiasi permesso che infrange la privacy di un utente è considerato pericoloso.

Le autorizzazioni vengono inoltre inserite in gruppi di autorizzazioni simili, ad esempio accesso alla posizione fine e posizione approssimativa.

Gli utenti possono scegliere se utilizzare l'app per accettare il permesso di un determinato gruppo considerato pericoloso. Una volta che viene concessa l'autorizzazione per un particolare gruppo per l'esecuzione dell'app, non viene chiesto di nuovo le autorizzazioni all'interno dello stesso gruppo, ma verranno richieste le autorizzazioni di altri gruppi, come richiesto.

vedi dettagli sotto:

Runtime permisssions.

Questa versione introduce un nuovo modello di autorizzazioni, in cui gli utenti possono ora gestire direttamente le autorizzazioni delle app in fase di runtime. Questo modello offre agli utenti visibilità e controllo migliori sulle autorizzazioni, semplificando allo stesso tempo l'installazione e i processi di aggiornamento automatico per gli sviluppatori di app. Gli utenti possono concedere o revocare le autorizzazioni individualmente per le app installate.

Nelle app che hanno come target Android 6.0 (livello API 23) o superiore, assicurati di verificare e richiedere autorizzazioni in fase di esecuzione. Per determinare se alla tua app è stata concessa un'autorizzazione, chiama il nuovo metodo checkSelfPermission(). Per richiedere un'autorizzazione, chiama il nuovo metodo requestPermissions(). Anche se la tua app non ha come target Android 6.0 (livello API 23), devi testare la tua app con il nuovo modello di autorizzazioni.

.../

Beginning with Android 6.0 (API level 23), gli utenti conferire e revocare le autorizzazioni delle app in fase di esecuzione, invece di farlo quando si installa l'applicazione.Di conseguenza, dovrai testare la tua app in una gamma più ampia di condizioni. Prima di Android 6.0, si può ragionevolmente presumere che se la tua app è in esecuzione, ha tutte le autorizzazioni che dichiara nel manifest dell'app. Sotto il nuovo modello di autorizzazioni, non è più possibile fare questa ipotesi.

Permessi sono classificati come normal or dangerous

accesso Bluetooth è considerata come un permesso normale, mentre l'associazione o la lettura di dettagli di un app è considerato pericoloso.

Le autorizzazioni pericolose riguardano le aree in cui l'app richiede dati o risorse che coinvolgono le informazioni private dell'utente o che potrebbero potenzialmente influire sui dati memorizzati dell'utente o sul funzionamento di altre app. Ad esempio, la possibilità di leggere i contatti dell'utente è un permesso pericoloso. Se un'app dichiara di aver bisogno di un'autorizzazione pericolosa, l'utente deve concedere esplicitamente l'autorizzazione all'app.

Così, quando la richiesta di informazioni da un dispositivo:

Se un'applicazione richiede un permesso pericoloso elencato nel suo manifesto, e l'applicazione non dispone attualmente di tutte le autorizzazioni del gruppo di autorizzazioni, il sistema mostra un finestra di dialogo per l'utente che descrive il gruppo di autorizzazioni a cui l'app vuole accedere. La finestra di dialogo non descrive l'autorizzazione specifica all'interno di quel gruppo. Ad esempio, se un'app richiede l'autorizzazione READ_CONTACTS, la finestra di dialogo di sistema dice solo che l'app deve accedere ai contatti del dispositivo. Se l'utente concede l'approvazione, il sistema fornisce all'app solo l'autorizzazione richiesta.

Vedere Working With System Permissions per dettagli di implementazione.


modificareIn risposta a your- commentare

enter image description here

ci sono multiple issues con bluetooth bugs e il rilascio di Android 6.0. come c'era con 5.0, è previsto che questi saranno corretti con la prossima patch. Tuttavia, non vedo il tuo problema come un bug.

E dopo aver visto your post here on google, la mia risposta risponde direttamente a ciò che percepisce come un bug.

tuo screen shot:

enter image description here

E da 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" 
    } 

Il marshmallow dispositivi si comportano esattamente come sono destinati a con i permessi di esecuzione, ma sono sicuro che Google confermerà questo per te.

Per evitare avere a che fare con il passaggio in questa fase, utilizzare l'SDK destinazione come meno di 23.

targetSdkVersion 22 

Questo blog Cheesefactory va in dettaglio bene.Everything every Android Developer must know about new Android's Runtime Permission

Edit 2

Recupero UUID richiede posizione permesso, c'è un post qui che è va in ulteriori dettagli: https://stackoverflow.com/a/33045489/3956566

+0

Siamo spiacenti, questo non ha nulla a che fare con il problema in questione. Sono consapevole che la scansione Bluetooth richiede i permessi di posizione ma l'ho già aggiunto. –

+1

@dustedrob Vi consiglio caldamente di leggere la mia risposta, poiché risolve il problema al 100%. La mia risposta non affronta 'La scansione Bluetooth richiede i permessi di localizzazione ', si occupa delle permsioni di runtime e usa le autorizzazioni di localizzazione come esempio di gruppi –

Problemi correlati