2015-10-10 49 views
12

我有一個應用程序使用藍牙和連接到設備,can'f找到任何設備使用BluetoothAdapter.getDefaultAdapter()。startDiscovery();在發現之前它運行良好。也嘗試過其他應用程序,它也不適用於其他應用程序。但是我嘗試配對的設備(Arduino bt-module)可以在Android設置中找到。任何想法我可以嘗試什麼?我實現了像http://developer.android.com/guide/topics/connectivity/bluetooth.html中描述的一切,並且在更新之前它就工作了。由於棉花糖使用BluetoothAdapter.getDefaultAdapter()更新藍牙發現。startDiscovery();是打破

回答

30

藍牙適配器已經改變的Android 6.0

您需要設置權限ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION許可,並需要使用 BluetoothLeScanner.startScan()方法來開始掃描。

下面是從更改日誌說明:

爲用戶提供更高的數據保護的用戶,這是Android 6.0,Android的刪除程序訪問設備的本地硬件標識符使用Wi-Fi和藍牙的應用蜜蜂。 WifiInfo.getMacAddress()和BluetoothAdapter.getAddress()方法現在返回恆定值02:00:00:00:00:00。

訪問通過藍牙和Wi-Fi掃描附近的外部裝置的硬件識別碼,您的應用程序現在必須有ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION權限:

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

注意:如果運行的是Android 6.0(API級別的設備23)啓動後臺Wi-Fi或藍牙掃描,該操作對於外部設備是可見的,源自隨機MAC地址。

您可以通過以下鏈接瞭解詳情: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html

+3

謝謝你的提示,則我的解決方案是添加ACCESS_FINE_LOCATION權限並在運行時請求權限。 – mikugo

+0

@mikugo你還在使用'BluetoothAdapter.getDefaultAdapter()。startDiscovery();'發起發現?這些更改提到使用LEScanner代替棉花糖,並想知道您是否對更換經典的藍牙設備進行了更改。 – jschlepp

+0

@jschlepp是的我正在使用'BluetoothAdapter.getDefaultAdapter()。startDiscovery();'它只是一個小型的大學項目。但也許LEScanner也可以發現經典設備,因爲它們使用相同的頻率。它使用更少的電力。 – mikugo

5

只啓用位置在設置和它工作得很好!

2

從API級別23,藍牙發現還需要位置訪問權限(ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION)。

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

而作爲許可屬於「危險」保護級別只是添加到許可清單文件是不夠的。 需要用戶同意才能在運行時請求權限。

添加到許可的AndroidManifest.xml:

<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" /> 

請求ACCESS_FINE_LOCATION或ACCESS_COARSE_LOCATION在運行時:

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