项目场景:
项目场景:通过蓝牙芯片(HC-05)或低功耗蓝牙(BLE)与手机 APP 通信,传输传感器数据
问题描述:
无法扫描到周围的蓝牙设备
private ScanCallback scanCallback=new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
BluetoothDevice device=result.getDevice();
//callbackType回调类型,什么类型会触发回调
//result扫描得到的结果,不包含传统蓝牙
Log.i(TAG,"NAME:"+device.getName()+",ADDR:"+device.getAddress());
if(startScanning){
Log.i(TAG,"connect LED:"+device.getName()+"ADDR"+device.getAddress());
startScanning=false;
bluetoothGatt=device.connectGatt(MainActivity.this, false, new MainActivity.BluetoothGattCallback());
}
}
};
private void scanLeDevice(boolean enable){
bluetoothDeviceList.clear();
mBluetoothLeScanner=mBluetoothAdapter.getBluetoothLeScanner();
if(mBluetoothLeScanner==null){
Log.i(TAG,"blescan is null");
}
if(enable){
Log.i(TAG,"start scanning");
//因为蓝牙扫描需要消耗较多电量,所以要定义扫描时间
//handler对象post方法将run中放在当前线程的消息队列,没有创建子线程
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
//延迟后执行该部分,中断扫描
mScanning=false;
Log.i(TAG,"stopScan");
mBluetoothLeScanner.stopScan(scanCallback);
}
},SCAN_PERIOD);
//先打开扫描
mScanning=true;
Log.i(TAG,"startScan");
mBluetoothLeScanner.startScan(scanCallback);
}
else{
//关闭扫描
mScanning=false;
mBluetoothLeScanner.stopScan(scanCallback);
}
}
原因分析:
如果目标运行版本太高需要调用一些权限,否则蓝牙受影响。
总共3种权限注意(打开1、2前两个):
- APP的定位权限,特别注意这个权限是APP应用管理里面的那个位置权限。
- 手机的GPS打开
- APP的精确定位权限(因为未使用太高平台,因此未遇到过动态开启精确定位权限)
解决方案:
我使用的方案:既然是版本升级带来的权限细分,那么我们直接修改build.gradle
,将targetSdkVersion
改为27,问题解决。
另一种方案(未使用,不确定是否可行):参考的地址
//对高版本平台,设置精确定位权限
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();
}
}