Проблемы со сканированием Android 10 Bluetooth LE
Я пытаюсь установить простое приложение для сканирования Bluetooth LE, работающее под Android 10.
Сканирование запускается, но устройства не обнаруживаются.
Существует много сообщений о правильных разрешениях, необходимых для Android 10, и я думаю, что они у меня правильные. В настоящее время я требую и прошу пользователя:
BLUETOOTHBLUETOOTH_ADMINACCESS_FINE_LOCATIONFOREGROUND_SERVICEACCESS_BACKGROUND_LOCATION
Приложение простое, всего одна форма, кнопка запуска сканирования, кнопка остановки сканирования и текстовое представление для отображения результатов.
Может кто-нибудь указать, что я пропустил?
Большое спасибо
public class MainActivity extends AppCompatActivity {
BluetoothAdapter btAdapter;
BluetoothLeScanner btScanner;
Button startScanningButton;
Button stopScanningButton;
TextView peripheralTextView;
private static final int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
private static final int PERMISSION_REQUEST_BACKGROUND_LOCATION = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
peripheralTextView.setMovementMethod(new ScrollingMovementMethod());
startScanningButton = (Button) findViewById(R.id.StartScanButton);
startScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startScanning();
}
});
stopScanningButton = (Button) findViewById(R.id.StopScanButton);
stopScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
stopScanning();
}
});
stopScanningButton.setVisibility(View.INVISIBLE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
if (this.checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
if (this.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs background location access");
builder.setMessage("Please grant location access so this app can detect beacons in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@TargetApi(23)
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
PERMISSION_REQUEST_BACKGROUND_LOCATION);
}
});
builder.show();
}
else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since background location access has not been granted, this app will not be able to discover beacons in the background. Please go to Settings -> Applications -> Permissions and grant background location access to this app.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
}
} else {
if (!this.shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION},
PERMISSION_REQUEST_FINE_LOCATION);
}
else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons. Please go to Settings -> Applications -> Permissions and grant location access to this app.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
}
}
final BluetoothManager btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
if (btAdapter == null || !btAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
}
btScanner = btAdapter.getBluetoothLeScanner();
}
// Device scan callback.
private ScanCallback leScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
peripheralTextView.append("Device Name: " + result.getDevice().getName() + " rssi: " + result.getRssi() + "\n");
}
};
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_FINE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("fine location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover devices when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
public void startScanning() {
peripheralTextView.setText("");
peripheralTextView.append("Start Scanning");
startScanningButton.setVisibility(View.INVISIBLE);
stopScanningButton.setVisibility(View.VISIBLE);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
}
public void stopScanning() {
peripheralTextView.append("Stopped Scanning");
startScanningButton.setVisibility(View.VISIBLE);
stopScanningButton.setVisibility(View.INVISIBLE);
AsyncTask.execute(new Runnable() {
@Override
public void run() {
btScanner.stopScan(leScanCallback);
}
});
}
}
3 ответа
Похоже, сканирование Bluetooth отключено. Пожалуйста, найдите скриншот ниже. Только включение определения местоположения не будет работать вместе с местоположением, которое необходимо для включения сканирования Bluetooth.
Я знаю, что немного опоздал, но я надеюсь, что это кому-то поможет.
Эти разрешения верны. Вы не включаете службы определения местоположения, и это ваша проблема.
Взгляни на это. Как видите, ведется много дискуссий о том, почему Google делает все именно так. В самом конце выпуска есть ссылка на видео на Youtube (см. Здесь), где Чет объяснил, что даже Google не знает, что это такое, поэтому они добавили новое разрешение в A12.
Также
Разрешения Android 10:
на Android 10 обычно необходимо получить ACCESS_BACKGROUND_LOCATION, чтобы обнаружение маяка работало, когда ваше приложение не отображается. Однако можно сканировать только с предоставленным разрешением на размещение на переднем плане и службой переднего плана, если вы добавите android: foregroundServiceType="location" в объявление службы переднего плана в манифесте. Подробности смотрите здесь.
Итак, включения служб определения местоположения будет достаточно, чтобы получить результаты с
bluetoothMangaer.adapter.startScan(scanCallback)
В случае, если вы не хотите, чтобы пользователь включал свое местоположение, вы можете сделать
bluetoothMangaer.adapter.startDiscovery()
Похоже, это было связано с самим адаптером, вызывающим проблему, глядя на logcat, я получал статус =133 при вызове startcanning, сброс физического адаптера устранил проблему, и начали появляться результаты сканирования