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

时间:2017-07-19 17:23:16

标签: android android-studio bluetooth-lowenergy android-6.0-marshmallow android-permissions

我是Android App开发和BLE的新手,我正在使用示例代码BluetoothLeGatt [我从Android Studio导入的那个]学习这些。该代码在我的平板电脑(Android 5.0)上运行正常,但扫描活动不会返回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)

我查看了帖子Bluetooth Low Energy startScan on Android 6.0 does not find devices和官方网页Requesting Permissions at Run Time,但我仍然不知道如何修改我的代码。

我确实添加了 GPS 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-feature android:name="android.hardware.location.gps" />

但是App仍然无法返回任何BLE设备。然后,当我尝试将以下代码块添加到我的应用程序时(来自 在运行时请求权限 ),checkSelfPermission上始终存在错误[无法解析符号& #39; checkSelfPermission&#39]。但我确实导入了import android.support.v4.content.ContextCompat;

有人可以帮我吗?另外,对于如何使DeviceScanActivity工作的问题有一个更简单的答案吗?我真的不知道在哪里将代码块从 在运行时请求权限 放到我的代码中:(我知道这是一个非常愚蠢的问题,但我对这个领域真的很陌生。请帮助我!

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

2 个答案:

答案 0 :(得分:1)

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

我所做的是除了在 AndroidManifest.xml 中添加权限之外,我还将以下代码添加到 onCreate < DeviceScanActivity 中的/ strong>方法,我使用的引用是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
    }

当我第一次添加上面的代码时,我的平板电脑上会出现一个弹出窗口,要求我提供权限,然后点击“允许”。 然后,我能够扫描我的设备。

顺便说一下,它只要求我一次许可。当我稍后单击“运行应用程序”(稍微修改我的代码后)后,它再次没有请求我的许可。

答案 1 :(得分:0)

您是否添加了所有权限:

<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上运行正常