如何修改 BluetoothleGatt 以在 Android 6.0 上启用 BLE 设备扫描?

How can I modify BluetoothleGatt to enable BLE device scanning on Android 6.0?

我是 Android 应用程序开发和 BLE 的新手,我正在使用示例代码 BluetoothLeGatt [我从 Android Studio 导入的代码] 学习这些。该代码在我的平板电脑 (Android 5.0) 上运行良好,但扫描 activity 不会 return Android 6.0 上的任何 BLE 设备。我收到的错误消息如下所示。

07-19 12:41:39.615 7617-7642/? W/Binder: Caught a RuntimeException from the binder stub implementation.
                                     java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
                                         at android.os.Parcel.readException(Parcel.java:1599)
                                         at android.os.Parcel.readException(Parcel.java:1552)
                                         at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:772)
                                         at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:331)
                                         at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
                                         at android.os.Binder.execTransact(Binder.java:458)

我看了post Bluetooth Low Energy startScan on Android 6.0 does not find devices and the official page Requesting Permissions at Run Time,但我还是不知道如何修改我的代码。

我确实添加了GPSACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION[的权限,然后我在平板电脑上打开了 定位服务

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-feature android:name="android.hardware.location.gps" />

但是应用程序仍然不能return任何BLE设备。然后,当我尝试将以下代码块添加到我的应用程序时(来自 Requesting Permissions at 运行 Time ),有checkSelfPermission [无法解析符号 'checkSelfPermission'] 总是出错。但是我确实导入了 import android.support.v4.content.ContextCompat;

有人可以帮我解决这个问题吗?此外,对于如何使 DeviceScanActivity 工作的问题是否有更简单的答案?我真的不知道把代码块从 Requesting Permissions at 运行 Time 放到我的代码中:( 我知道这是一个非常愚蠢的问题,但我真的是这个领域的新手。请帮助我!

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
    != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.READ_CONTACTS)) {

    // Show an explanation to the user *asynchronously* -- don't block
    // this thread waiting for the user's response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant. The callback method gets the
    // result of the request.
}
}

编辑 以下是我的依赖块。

dependencies {
compile "com.android.support:support-v4:25.3.1"
compile "com.android.support:support-v13:25.3.1"
compile "com.android.support:cardview-v7:25.3.1"
compile "com.android.support:appcompat-v7:25.3.1"
}

你是否添加了所有这些权限:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

它在 android 6.0

上工作正常

感谢大家的回复和帮助!我刚刚解决了我的案子!

我所做的是除了在AndroidManifest.xml中添加权限外,我在[= DeviceScanActivity中的23=]onCreate方法,我参考的是Requesting Permissions at Run Time。另外,我只是随机分配了一个数字给 MY_PERMISSIONS_REQUEST_LOCATION.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getActionBar().setTitle(R.string.title_devices);
        mHandler = new Handler();
    //Check for permissions
        int permissionCheck = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_CALENDAR);
        Log.e(TAG, "Permission Status: " +permissionCheck );

    //***********************************************************
    // 
        if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED)
        {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_COARSE_LOCATION))
            {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

            } 
            else
            {

            // No explanation needed, we can request the permission.

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

    ......//The rest of code
    }

当我第一次添加上面的代码时,我的平板电脑上出现一个弹出窗口 window 询问我的权限,我点击了 "allow." 然后,我就可以扫描我的 ble 设备了。

顺便说一句,它只征求我一次许可。当我稍后点击 "Run Application" 时(在我的代码稍作修改之后),它没有再次请求我的许可。