2015-10-15 159 views
6

我升級到Android 6,我的使用藍牙的應用程序無法使用這個新的API版本。這與Play Store上的應用程序存在同樣的問題:藍牙spp工具專業版(查看藍牙是否有效的良好應用程序),它不會發現設備。Android 6藍牙

這個問題似乎是在藍牙發現:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
mBluetoothAdapter.startDiscovery() 
Log.i("BLUETOOTH", String.valueOf(mBluetoothAdapter.isDiscovering())); // Return false 

我的應用程序與Android 4/5運作良好,我也跟着:http://developer.android.com/guide/topics/connectivity/bluetooth.html

+0

哪些設備遇到此問題?哪個連結?我使用Nexus 5 –

+0

這是一個聯繫5 – eldina

回答

18

與Android 6.0盯着它是不足以包含清單的權限。 您必須明確詢問用戶每個被認爲「危險」的權限。 BluetoothDevice.ACTION_FOUND需要藍牙以及ACCESS_COARSE_LOCATION權限 http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_FOUND

的ACCESS_COARSE_LOCATION http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_COARSE_LOCATION 是一個「危險」的許可,因此,你要問使用做實際的發現之前它requestPermission了。

public void doDiscovery() { 
    int hasPermission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION); 
    if (hasPermission == PackageManager.PERMISSION_GRANTED) { 
     continueDoDiscovery(); 
     return; 
    } 

    ActivityCompat.requestPermissions(MainActivity.this, 
      new String[]{ 
        android.Manifest.permission.ACCESS_COARSE_LOCATION}, 
      REQUEST_COARSE_LOCATION_PERMISSIONS); 
} 

然後你會得到用戶的答案上onRequestPermissionsResult

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case REQUEST_COARSE_LOCATION_PERMISSIONS: { 
      if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       continueDoDiscovery(); 
      } else { 
       Toast.makeText(this, 
         getResources().getString(R.string.permission_failure), 
         Toast.LENGTH_LONG).show(); 
       cancelOperation(); 
      } 
      return; 
     } 
    } 
} 

要使用的機器人,你應該使用兼容庫,並使用ActivityCompat

+0

這是Bluetooth的必要嗎?或只爲acess_coarse_location? –

+0

是的,對於這兩個,根據谷歌文檔,https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_FOUND – Luci

3

我花了一些時間來調查這個問題。
在Android bug跟蹤器上創建bug報告here
問題是系統不會將BluetoothDevice.ACTION_FOUND意向轉發到註冊BroadcastReceiver。 logcat中這樣表示線路:

10-16 07:34:09.147  786-802/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.bluetooth.device.action.FOUND flg=0x10 (has extras) } to ProcessRecord{5ce2d92 21736:com.example.mvl.bluetoothtest/u0a74} (pid=21736, uid=10074) requires android.permission.ACCESS_COARSE_LOCATION due to sender com.android.bluetooth (uid 1002)  

這對我的主題,應用程序需要android.permission.ACCESS_COARSE_LOCATION權限收到此意圖。我個人不明白爲什麼我需要這個許可來獲得藍牙設備。
所以,如果添加此權限您的清單,那麼就應該有一個更加前提工作 - 你必須設定目標SDK,並與SDK不高於編譯,然後22

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> 
+0

ACCESS_COARSE_LOCATION是必需的,因爲藍牙(如Wi-Fi和網絡(嚴格來說不是GPS設備))也可以幫助您指定使用BT信標的位置。因此授予位置權限也是預先要求的。 – dekaru

0

在檢查的來源進行調用以前的版本工作代碼在GattService.java中,你會發現一些代碼評論 in方法onScanResult:

// Do no report if location mode is OFF or the client has no location permission 
// PEERS_MAC_ADDRESS permission holders always get results 
if (hasScanResultPermission(client) && matchesFilters(client, result)) { 
    try { 
     ScanSettings settings = client.settings; 
     if ((settings.getCallbackType() & 
           ScanSettings.CALLBACK_TYPE_ALL_MATCHES) != 0) { 
      app.callback.onScanResult(result); 
     } 
    } catch (RemoteException e) { 
     Log.e(TAG, "Exception: " + e); 
     mClientMap.remove(client.clientIf); 
     mScanManager.stopScan(client); 
    } 
} 

這說明了獲取藍牙LE廣告報告需要什麼。