2015-11-11 8 views
6

を取得私はこのようなリモートBluetoothデバイスからのUUIDを取得しようとしている:アンドロイド6.0の要求リモートデバイスとのペアリングのUUID

 device.fetchUuidsWithSdp(); 

これは黙って仕事ととものを除くすべてのデバイス上のユーザとの対話なしになりますAndroid 6.0は、UUIDを取得するためにリモートデバイスと接続するためのペア設定ダイアログを表示しています。それは期待された行動ですか?これはどこに文書化されていますか?明示的にもう一方の側から許可する必要なくUUIDの検出を開始する方法はありますか?

+0

機能しないhttps://android.googlesource.com /platform/frameworks/base/+/lollipop-release/core/java/android/bluetooth/BluetoothDevice.java#1013)、[marshmallow](https://android.googlesource.com/platform/frameworks/base/+/) marshmallow-release/core/java/android/bluetooth/BluetoothDevice.java#1081)、実行時パーミッションアノテーションだけが追加されました。だから私はなぜ "ペアリングダイアログ"がポップアップするのか説明できません。デバイスと通信していることをユーザーに知らせるには? –

+0

@jmolsかもしれません。しかし、そういうわけで私はGoogleからの正式な回答が欲しい。 UUIDを取得しても、必ずしも個人データにアクセスする必要はありません。セキュリティで保護されたソケット接続が確立されていないときにダイアログを表示する方が好きです。 –

+0

UUIDを取得する@dustedrobは、場所のアクセス許可を使用することを意味します。 –

答えて

3

は、 fetchUuidsWithSdp。これには少しの反射が必要です。これは、アンドロイド6.0と5.1.1で、ペアにしようとしているデバイスなしで私のために働いた。 これが役立ちますので、やや劣悪な例外処理を改善することができます。

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); 
} 
} 

編集: sdpSearchは、Android 6.0で追加されたので、それは([ロリポップ]をBluetoothDeviceのソースコードを見て、以前のバージョン

+0

非常に興味深い!私はそれを試して、できるだけ早く報告します。 –

+2

テストの数週間後、それは素晴らしい作品です。この隠されたメソッドは、Android 6.0からのみ存在することを他の誰かのために明確にするためです。ありがとう! –

2

更新

Google's official response to your question

こんにちは、 私たちは、あなたがstackoverflowの中で、ここで調べることができ、特定の用途にクエリを持って理解しています。アンドロイド6.0で

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

おかげ


権限の変更があります。アプリケーションのインストール時に必要なすべてのアプリケーションのグローバルな承認ではなく、実行時のアクセス許可を紹介します。

簡単に言えば、アクセス許可の種類は、通常の種類と危険な種類の2種類に大別できます。ユーザーのプライバシーを侵害するすべての許可は危険とみなされます。

パーミッションは、同様のパーミッションのグループに配置されます(例:細かい場所へのアクセスと粗い場所)。

ユーザーは、危険であるとみなされる特定のグループの許可を受け入れるためにアプリを使用している間に選択肢が与えられます。特定のグループに対するアクセス権がそのアプリケーションの実行に与えられると、同じグループ内からのアクセス許可はもう尋ねられませんが、必要に応じて他のグループからのアクセス許可を求められます。

Runtime permisssions

は、以下の詳細を参照してください。

このリリースでは、新しいアクセス許可モデルが導入されました。ここで、ユーザーは実行時にアプリケーションのアクセス許可を直接管理できるようになりました。このモデルは、ユーザーに、アプリケーション開発者のインストールプロセスと自動更新プロセスを合理化しながら、アクセス許可の可視性とコントロールを向上させます。ユーザーは、インストールされているアプリに対して個別に権限を付与または取り消すことができます。

Android 6.0(APIレベル23)以上をターゲットとするアプリでは、実行時にアクセス許可を確認してリクエストしてください。あなたのアプリケーションに許可が与えられているかどうかを調べるには、新しいcheckSelfPermission()メソッドを呼び出します。パーミッションを要求するには、新しいrequestPermissions()メソッドを呼び出します。アプリがAndroid 6.0(APIレベル23)をターゲットにしていない場合でも、新しいアクセス許可モデルでアプリをテストする必要があります。

.../

Beginning with Android 6.0 (API level 23)、ユーザーが許可し、彼らはアプリをインストールするときに代わりにそうすることで、実行時にアプリの権限を取り消します。その結果、より広い範囲の条件でアプリをテストする必要があります。 Android 6.0より前のバージョンでは、アプリがまったく実行されていれば、アプリマニフェストで宣言しているすべての権限を持っていると考えることができます。新しい権限モデルでは、もはやその前提を作ることはできません。

権限がnormal or dangerous

ブルートゥース・アクセスは、通常の許可とみなさペアリングや危険とみなされているアプリの詳細を読みながらされるとして分類されています。

危険なアクセス許可には、ユーザーの個人情報を含むデータやリソースが必要な領域や、ユーザーの格納されたデータや他のアプリケーションの操作に影響を及ぼす可能性のある領域が含まれます。たとえば、ユーザーの連絡先を読み取る機能は危険な許可です。アプリが危険なアクセス権を必要とすると宣言した場合、ユーザーは明示的にアクセス許可をアプリに与えなければなりません。

デバイスからの情報を要求するときに:

アプリは、そのマニフェストに記載されている危険な許可を要求し、アプリが現在許可グループ内のすべての権限を持っていない場合は、システムはAを示しますアプリケーションがアクセスしたいアクセス権グループを説明するユーザーにダイアログボックスを表示します。このダイアログボックスには、そのグループ内の特定の権限は示されていません。たとえば、アプリがREAD_CONTACTS権限を要求した場合、システムダイアログボックスでは、アプリがデバイスの連絡先にアクセスする必要があると表示されます。ユーザーが承認した場合、システムはアプリに要求したアクセス権のみを与えます。

実装の詳細については、Working With System Permissionsを参照してください。


編集 your-コメントに応えて

enter image description here

bluetooth bugsとAndroid 6.0のリリースでmultiple issuesがあります。 5.0と同じように、これらは次のパッチで修正される予定です。しかし、私はバグとしてあなたの問題は表示されません。

your post here on googleを見てから、私の答えはあなたがバグとして知覚しているものに直接答えます。

あなたのスクリーンショット:

enter image description here

そして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" 
    } 

からマシュマロデバイスは、それらが実行時の権限ですることが意図されているとおりに動作しているが、私はGoogleがこれを確認します確信していますあなたのために。このCheesefactoryブログはうまく細部に入る未満23

targetSdkVersion 22 

としてターゲットSDKを使用して、この段階で切り替えに対処することを防止するために

Everything every Android Developer must know about new Android's Runtime Permission

編集2

フェッチUUIDが場所の許可を必要とし、より詳細になりますここにポストがあります:私は隠されたsdpSearchメソッドの代わりを使用してこの回避策を見つけたhttps://stackoverflow.com/a/33045489/3956566

+0

申し訳ありませんが、これは手元の問題とは関係ありません。 Bluetoothスキャンでは場所のアクセス権が必要ですが、既に追加しています。 –

+1

@dustedrob私は100%あなたの問題に対処するので、私の答えを読むことを強くお勧めします。私の答えは、 'BluetoothのスキャンにはLocation Permissionsが必要です.'ランタイムの許可を扱い、グループの例としてロケーション許可を使用しています。 –

関連する問題