Android 遇坑【8】- Android10 蓝牙扫描失败

前言

最近遇到一个吊诡的问题,开发的APP在 华为荣耀V20 的测试中发现无法扫描到蓝牙设备。而手机系统蓝牙可以扫描得到。打断点调试发现其扫描回调未执行…多次尝试未果。
开始以为是该机型特有的问题,随后偶然看到其为Android10,这也是目前可供测试的唯一一部手机,考虑到安卓日益细分、严格的权限控制。我打开了 Android 10 隐私变更 ,终于解脱了。

Android 遇坑【8】- Android10 蓝牙扫描失败_第1张图片

原因

Android 遇坑【8】- Android10 蓝牙扫描失败_第2张图片
涉及到蓝牙功能如下,可以发现常用的扫描都需要…
Android 遇坑【8】- Android10 蓝牙扫描失败_第3张图片

解决方法

修改目标版本

解决不了问题,就解决提出问题的人。

既然是版本升级带来的权限细分,那么我们直接修改build.gradle,将targetSdkVersion改为27,问题解决。

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.felicitysolar_debug"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 2
        versionName "3.6"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    lintOptions {
        checkReleaseBuilds false
        abortOnError false
    }

}

当然,这明显是剑走偏锋!

申请精确定位权限

正统做法来了:

首先需在AndroidManifest.xml中加上如下权限:

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

除此之外还需动态申请权限,这里参考了华为的例程:

        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
            Log.i(TAG, "sdk < 28 Q");
            if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                String[] strings =
                        {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
                ActivityCompat.requestPermissions(this, strings, 1);
            }
        } else {
            if (ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    || ActivityCompat.checkSelfPermission(this,
                    "android.permission.ACCESS_BACKGROUND_LOCATION") != PackageManager.PERMISSION_GRANTED) {
                String[] strings = {android.Manifest.permission.ACCESS_FINE_LOCATION,
                        android.Manifest.permission.ACCESS_COARSE_LOCATION,
                        "android.permission.ACCESS_BACKGROUND_LOCATION"};
                ActivityCompat.requestPermissions(this, strings, 2);
            }
        }

由于找不到强制开启GPS定位的方法,这里做个软提醒:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P){
            LocationManager alm = (LocationManager)BLEActivity.this.getSystemService(Context.LOCATION_SERVICE);
            if (!alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)){
                Toast.makeText(this, "请开启GPS!", Toast.LENGTH_SHORT).show();
            }
        }

一套组合拳下去,问题解决。

你可能感兴趣的:(Android,遇坑)