2015-10-10 16 views
12

私は、Bluetoothアダプタとデバイスに接続しているアプリケーションを持っています。BluetoothAdapter.getDefaultAdapter()を使ってデバイスを見つけることはできません。startDiscovery();それは発見の直前にうまくいった。他のアプリも試してみましたが、他のアプリでもうまくいきません。しかし、私がペア設定しようとするデバイス(Arduino bt-module)は、Androidの設定で見つけることができます。どのようなアイデアを試すことができますか?私はhttp://developer.android.com/guide/topics/connectivity/bluetooth.htmlに記載されているようなものを実装し、アップデート前に動作しました。marshmallowはBluetoothAdapter.getDefaultAdapter()。startDiscovery();を使用してBluetooth検出を更新しています。

答えて

30

Bluetoothアダプタは、あなたが許可ACCESS_FINE_LOCATIONまたはACCESS_COARSE_LOCATION許可を設定する必要があり、スキャンを開始する BluetoothLeScanner.startScan()メソッドを使用する必要があるのAndroid 6.0

に変更されています。以下は

変更ログからの説明です:

のAndroid 6.0で、より大きなデータ保護をユーザーに提供するために、Androidのは、Wi-FiやBluetoothを使用してアプリをデバイスのローカルハードウェア識別子へのプログラムによるアクセスを削除しますAPI。 WifiInfo.getMacAddress()およびBluetoothAdapter.getAddress()メソッドは、02:00:00:00:00:00の定数値を返すようになりました。

のBluetoothとWi-Fiのスキャンを経由して近くの外部デバイスのハードウェア識別子にアクセスするには、あなたのアプリが今ACCESS_FINE_LOCATIONまたはACCESS_COARSE_LOCATION権限を持っている必要があります。

WifiManager.getScanResults() 
BluetoothDevice.ACTION_FOUND 
BluetoothLeScanner.startScan() 

注:デバイスは、Android 6.0(APIレベルを実行しています23)がバックグラウンドのWi-FiまたはBluetoothスキャンを開始すると、操作はランダム化されたMACアドレスから発信された外部デバイスに見えます。

あなたは、このリンクから詳細を取得することができます:ちょうど設定で場所を有効にし、それがうまく機能 http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html

+3

おかげで、解決策は、ACCESS_FINE_LOCATION権限を追加し、実行時に権限を要求することでした。 – mikugo

+0

@mikugoあなたはまだ 'BluetoothAdapter.getDefaultAdapter()を使っていますか?発見を開始するためのstartDiscovery();この変更には、Marshmallowの代わりにLEScannerを使用し、古典的なBluetoothデバイスをスキャンするために変更したかどうか疑問に思う。 – jschlepp

+0

@jschleppはい私は 'BluetoothAdapter.getDefaultAdapter()。startDiscovery();を使用しています。これはほんの小さな大学プロジェクトでした。しかし、LEScannerは同じ周波数を使用するため、古典的なデバイスを発見することもできます。そしてそれはより少ない電力を使用します。 – mikugo

5

!!

2

APIレベル23から、ロケーションのアクセス許可(ACCESS_FINE_LOCATIONまたはACCESS_COARSE_LOCATION)も、Bluetoothの検出に必要です。

https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id

そして、ちょうどマニフェストファイルにアクセス権を追加する権限が「危険な」保護レベルに属しているとして十分ではありません。 実行時にアクセス許可を要求するには、ユーザーの同意が必要です。

のAndroidManifest.xmlに追加の許可:実行時にACCESS_FINE_LOCATIONまたはACCESS_COARSE_LOCATIONため

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> 
<uses-permission android:name="android.permission.BLUETOOTH" /> 

リクエスト:許可に関する

private void accessLocationPermission() { 
    int accessCoarseLocation = checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION); 
    int accessFineLocation = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION); 

    List<String> listRequestPermission = new ArrayList<String>(); 

    if (accessCoarseLocation != PackageManager.PERMISSION_GRANTED) { 
     listRequestPermission.add(android.Manifest.permission.ACCESS_COARSE_LOCATION); 
    } 
    if (accessFineLocation != PackageManager.PERMISSION_GRANTED) { 
     listRequestPermission.add(android.Manifest.permission.ACCESS_FINE_LOCATION); 
    } 

    if (!listRequestPermission.isEmpty()) { 
     String[] strRequestPermission = listRequestPermission.toArray(new String[listRequestPermission.size()]); 
     requestPermissions(strRequestPermission, REQUEST_CODE_LOC); 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case REQUEST_CODE_LOC: 
      if (grantResults.length > 0) { 
       for (int gr : grantResults) { 
        // Check if request is granted or not 
        if (gr != PackageManager.PERMISSION_GRANTED) { 
         return; 
        } 
       } 

       //TODO - Add your code here to start Discovery 

      } 
      break; 
     default: 
      return; 
    } 
} 

詳細:ヒントの https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

関連する問題