I'm making an Android app for BLE communication with a physical device.
Target SDK version is 32 - Min SDK version is 23
The first phase is obviously scanning for advertising devices.
In short, the problem is that the result returned in ScanResult never contains the deviceName in Android 8, but it is always null. It works fine with Android 6, 10, and 12.
I checked the official documentation and various examples and I seem to be doing everything in the right way. I'm stuck in this situation and I hope someone notices something strange in my code.
I have a BluetoothLeScanner
object on which I perform the scan method inside an Activity.
The following method is called when a Button is pressed:
@SuppressLint("MissingPermission")
private void doBleScan() {
ScanSettings scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
ArrayList<ScanFilter> filters = new ArrayList<>();
mDiscoveredDevices = new HashSet<>();
mBluetoothLeScanner.startScan(filters, scanSettings, scanCallback);
}
The instantiated ScanCallback
object has its own onScanResult method:
@Override
@SuppressLint("MissingPermission")
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
//always null with Android 8
String deviceName = result.getDevice().getName();
if(deviceName != null) {
txtLog.append("\nDN" + deviceName);
mDiscoveredDevices.add(result.getDevice());
}
}
The manifest file contains many declarations. The project is quite complex and also requires access to Wi-Fi networks, GPS location and tablet memory:
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Of course, before scanning, I perform a runtime permission check.
With Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
I check Manifest.permission.BLUETOOTH_SCAN
and Manifest.permission.BLUETOOTH_CONNECT
permissions.
Otherwise I check only Manifest.permission.ACCESS_FINE_LOCATION
permission.
private void requestRelevantRuntimePermissions() {
String title;
String message;
String[] permissions;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
title = "Bluetooth permissions required";
message = "Starting from Android 12, the system requires apps to be granted " +
"Bluetooth access in order to scan for and connect to BLE devices.";
permissions = new String[]{Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT};
} else {
title = "Location permission required";
message = "Starting from Android M (6.0), the system requires apps to be granted " +
"location access in order to scan for BLE devices.";
permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
}
requestPermissions(title, message, permissions);
}
private void requestPermissions(final String title, final String message, final String[] permissions) {
final Activity activity = this;
mPermissionToCheck = permissions;
runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
alertDialogBuilder
.setTitle(title)
.setMessage(message)
.setCancelable(false)
.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ActivityCompat.requestPermissions(
activity,
permissions,
RUNTIME_PERMISSION_REQUEST
);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
}
I have the impression that there is some permission not requested or badly requested but honestly I can not identify the problem.
Any suggestions?
Thanks in advance to those who will try to help me
I'm making an Android app for BLE communication with a physical device.
Target SDK version is 32 - Min SDK version is 23
The first phase is obviously scanning for advertising devices.
In short, the problem is that the result returned in ScanResult never contains the deviceName in Android 8, but it is always null. It works fine with Android 6, 10, and 12.
I checked the official documentation and various examples and I seem to be doing everything in the right way. I'm stuck in this situation and I hope someone notices something strange in my code.
I have a BluetoothLeScanner
object on which I perform the scan method inside an Activity.
The following method is called when a Button is pressed:
@SuppressLint("MissingPermission")
private void doBleScan() {
ScanSettings scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
ArrayList<ScanFilter> filters = new ArrayList<>();
mDiscoveredDevices = new HashSet<>();
mBluetoothLeScanner.startScan(filters, scanSettings, scanCallback);
}
The instantiated ScanCallback
object has its own onScanResult method:
@Override
@SuppressLint("MissingPermission")
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
//always null with Android 8
String deviceName = result.getDevice().getName();
if(deviceName != null) {
txtLog.append("\nDN" + deviceName);
mDiscoveredDevices.add(result.getDevice());
}
}
The manifest file contains many declarations. The project is quite complex and also requires access to Wi-Fi networks, GPS location and tablet memory:
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Of course, before scanning, I perform a runtime permission check.
With Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
I check Manifest.permission.BLUETOOTH_SCAN
and Manifest.permission.BLUETOOTH_CONNECT
permissions.
Otherwise I check only Manifest.permission.ACCESS_FINE_LOCATION
permission.
private void requestRelevantRuntimePermissions() {
String title;
String message;
String[] permissions;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
title = "Bluetooth permissions required";
message = "Starting from Android 12, the system requires apps to be granted " +
"Bluetooth access in order to scan for and connect to BLE devices.";
permissions = new String[]{Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT};
} else {
title = "Location permission required";
message = "Starting from Android M (6.0), the system requires apps to be granted " +
"location access in order to scan for BLE devices.";
permissions = new String[]{Manifest.permission.ACCESS_FINE_LOCATION};
}
requestPermissions(title, message, permissions);
}
private void requestPermissions(final String title, final String message, final String[] permissions) {
final Activity activity = this;
mPermissionToCheck = permissions;
runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
alertDialogBuilder
.setTitle(title)
.setMessage(message)
.setCancelable(false)
.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
ActivityCompat.requestPermissions(
activity,
permissions,
RUNTIME_PERMISSION_REQUEST
);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
}
I have the impression that there is some permission not requested or badly requested but honestly I can not identify the problem.
Any suggestions?
Thanks in advance to those who will try to help me
Share Improve this question asked Mar 4 at 11:21 LipsyorLipsyor 4481 gold badge7 silver badges21 bronze badges 2 |1 Answer
Reset to default 0If you are only interested in the name that is present in the advertisement message, you should not use the getDevice()
method since that returns the system's device object which is a representation of the remote device, whose device name might or might not be the same value as in the advertisement packet.
Instead, you should use getScanRecord()
. If this is non-null, you can inspect the name in the scan record using the getDeviceName()
method. If the name was not present in the scan record, it will be null.
You can inspect the HCI log or use a BLE sniffer to see the raw advertisement. You can also use the getBytes()
method to see the raw packet. If you don't get the name, I suggest you to inspect those bytes to see what's wrong. You could also use the app nRF Connect to inspect the bytes.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745047243a4608174.html
result.getScanRecord().getDeviceName()
also returnnull
? – Michael Commented Mar 5 at 9:57