BluetoothLeScanner.startScan 和 Android 6.0 未发现设备
BluetoothLeScanner.startScan with Android 6.0 does not discover devices
我正在尝试使用函数 BluatoothLeScanner.startScan 而不是已弃用的函数 BluetoothAdapter.startLeScan。
昨天我将我的 Nexus 5 更新为 Android 6.0,从那一刻起我的应用程序就不能再工作了。
我首先添加所需的首选项 ACCESS_COARSE_LOCATION,如此处所见,https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id。
然后我按照此处所述添加了权限:https://developer.android.com/training/permissions/requesting.html。
但最后它似乎不起作用,它不发送回 ble 设备。
这是我的代码:
清单
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stm.sensitronapp">
<uses-sdk android:maxSdkVersion="23"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>`
DeviceScanActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE);
}
}
// Device scan callback.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
mLeDeviceListAdapter.addDevice(result.getDevice());
mLeDeviceListAdapter.notifyDataSetChanged();
}
};
}
}
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
mSwipeRefreshLayout.setRefreshing(true);
mLeDeviceListAdapter.clear();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED) {
mBluetoothLeScanner.startScan(mScanCallback);
}
}
编辑:为了解决这个问题,我只打开了 GPS。在 this way.
中以编程方式很容易做到这一点
您的应用是否在启动时提示位置权限?如果不是,请在其他地方处理代码,以便得到提示。
你也可以检查这个来测试你的应用程序是否正常工作:
打开设置 > 应用 > YourApplication > 权限
并启用位置,然后尝试扫描结果。
仅当您在清单上提供 ACCESS_COARSE_LOCATION 时,位置才会列在权限下。
一个 - 不完美的答案是,一旦启用了新的运行时位置权限,您仍然可以使用相同的旧方法 BT 扫描方法。
mBluetoothAdapter.startDiscovery();
.......
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
}
}
};
使用上面提供的解决方案可行,但副作用是您必须为不需要的东西打开定位服务。一个丑陋且不令人满意的解决方法是将清单中的目标版本指定为
android:targetSdkVersion="21"
它允许在我的 Nexus 7 上进行扫描,即使安装的版本是 6.0.1。我不知道针对低于已安装版本的版本有什么副作用,但至少扫描有效。可能是 GPS-less 设备的唯一解决方案(如果存在此类设备)。
Google 应该为此被钉在十字架上。
如果获得权限,请尝试:打开 GPS。
这是一个老问题,但我会回答以帮助别人。
不幸的是,ACCESS_COARSE_LOCATION和targetSdkVersion 22的组合在某些设备上不起作用。
这不是一个好方法,但我在不使用运行时权限的情况下通过以下方式解决了(ACCESS_COARSE_LOCATION 或 ACCESS_FINE_LOCATION)
- 将你的 'targetSdkVersion' 设置为 19(我想也许 api19 ~ api22 是可以的)
将以下权限添加到您的清单文件
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
测试 Android 4.4 ~ 7.1.1
将你的 'minSdkVersion' 设置为 18
targetSdkVersion 22
我正在尝试使用函数 BluatoothLeScanner.startScan 而不是已弃用的函数 BluetoothAdapter.startLeScan。 昨天我将我的 Nexus 5 更新为 Android 6.0,从那一刻起我的应用程序就不能再工作了。 我首先添加所需的首选项 ACCESS_COARSE_LOCATION,如此处所见,https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id。 然后我按照此处所述添加了权限:https://developer.android.com/training/permissions/requesting.html。 但最后它似乎不起作用,它不发送回 ble 设备。
这是我的代码:
清单
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.stm.sensitronapp">
<uses-sdk android:maxSdkVersion="23"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>`
DeviceScanActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED){
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_COARSE);
}
}
// Device scan callback.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
mLeDeviceListAdapter.addDevice(result.getDevice());
mLeDeviceListAdapter.notifyDataSetChanged();
}
};
}
}
}
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
mSwipeRefreshLayout.setRefreshing(true);
mLeDeviceListAdapter.clear();
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED) {
mBluetoothLeScanner.startScan(mScanCallback);
}
}
编辑:为了解决这个问题,我只打开了 GPS。在 this way.
中以编程方式很容易做到这一点您的应用是否在启动时提示位置权限?如果不是,请在其他地方处理代码,以便得到提示。
你也可以检查这个来测试你的应用程序是否正常工作:
打开设置 > 应用 > YourApplication > 权限 并启用位置,然后尝试扫描结果。
仅当您在清单上提供 ACCESS_COARSE_LOCATION 时,位置才会列在权限下。
一个 - 不完美的答案是,一旦启用了新的运行时位置权限,您仍然可以使用相同的旧方法 BT 扫描方法。
mBluetoothAdapter.startDiscovery();
.......
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device);
}
}
};
使用上面提供的解决方案可行,但副作用是您必须为不需要的东西打开定位服务。一个丑陋且不令人满意的解决方法是将清单中的目标版本指定为
android:targetSdkVersion="21"
它允许在我的 Nexus 7 上进行扫描,即使安装的版本是 6.0.1。我不知道针对低于已安装版本的版本有什么副作用,但至少扫描有效。可能是 GPS-less 设备的唯一解决方案(如果存在此类设备)。
Google 应该为此被钉在十字架上。
如果获得权限,请尝试:打开 GPS。
这是一个老问题,但我会回答以帮助别人。
不幸的是,ACCESS_COARSE_LOCATION和targetSdkVersion 22的组合在某些设备上不起作用。
这不是一个好方法,但我在不使用运行时权限的情况下通过以下方式解决了(ACCESS_COARSE_LOCATION 或 ACCESS_FINE_LOCATION)
- 将你的 'targetSdkVersion' 设置为 19(我想也许 api19 ~ api22 是可以的)
将以下权限添加到您的清单文件
<uses-permission android:name="android.permission.READ_OWNER_DATA" /> <uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
测试 Android 4.4 ~ 7.1.1
将你的 'minSdkVersion' 设置为 18 targetSdkVersion 22