问题
I am trying to discover bluetooth devices nearby, but startDiscovery() always returns false, as if it is not working. Therefore it is not able to find devices.
I saw that i have to include Coarse_Location permission apart from Bluetooth and Bluetooth_Admin, but anyway, it doesn´t work.
Here is the code I am trying right now, where there are mainly traces to see how it works:
public class BluetoothActivity extends AppCompatActivity {
RecyclerView recyclerView;
ArrayList<BluetoothDevice> dispositivos;
BTAdapter adaptador;
BluetoothAdapter mBluetoothAdapter;
Button buscar;
final int REQUEST_ACCESS_COARSE_LOCATION = 16;
@Override
public void onCreate(Bundle savedInsanceState){
super.onCreate(savedInsanceState);
setContentView(R.layout.bluetooth_activity);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter != null) {
Toast.makeText(this, "No es nulo", Toast.LENGTH_SHORT).show();
if (!mBluetoothAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, RESULT_OK);
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
}
buscar = findViewById(R.id.buscar);
buscar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(BluetoothActivity.this, "Empezar a buscar", Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
switch (ContextCompat.checkSelfPermission(BluetoothActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
case PackageManager.PERMISSION_DENIED:
ActivityCompat.requestPermissions(BluetoothActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_ACCESS_COARSE_LOCATION);
break;
case PackageManager.PERMISSION_GRANTED:
boolean a = mBluetoothAdapter.startDiscovery();
Toast.makeText(BluetoothActivity.this, "Start discovery es "+a, Toast.LENGTH_SHORT).show();
break;
}
}
}
});
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
Toast.makeText(BluetoothActivity.this, "Encontrado", Toast.LENGTH_SHORT).show();
}
}
};
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_ACCESS_COARSE_LOCATION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean a = mBluetoothAdapter.startDiscovery();
Toast.makeText(BluetoothActivity.this, "Start discovery es "+a, Toast.LENGTH_SHORT).show();
}
else {
//exit application or do the needful
}
return;
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
}
And here the permissions in android manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-feature android:name="android.hardware.bluetooth" />
UPDATE: when I clicked to see the description of the startDiscovery method, I get this, with RequiresPermission and startDiscovery in red, saying "Cannot resolve method" and Manifest.permission.BLUETOOTH_ADMIN underlined and saying "Cannot find method value" :
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean startDiscovery() {
if (getState() != STATE_ON) {
return false;
}
try {
mServiceLock.readLock().lock();
if (mService != null) {
return mService.startDiscovery(getOpPackageName());
}
} catch (RemoteException e) {
Log.e(TAG, "", e);
} finally {
mServiceLock.readLock().unlock();
}
return false;
}
回答1:
Have you checked that the location is activated on your device?
Even if the location permission is granted, when it is disabled, the bluetooth API doesn't work.
So I suggest you to add the following code to be sure that the permission is effective:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!isGpsEnabled) {
startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), MY_REQUEST_CODE);
}
回答2:
It can be targetSdkVersion 29 permissions related problem. A simple workaround solution can be to downgrade target SDK. In file build.gradle (app) change for example:
targetSdkVersion 29 -> targetSdkVersion 28
回答3:
I encountered a similar problem. Later, I found that there was a problem with the location permission. I set the APP to disable the location, which led to false return all the time;
回答4:
The only thing that worked for me was to downgrade targetSdkVersion to 28. Of course Location permission still applies.
来源:https://stackoverflow.com/questions/61984202/android-bluetooth-startdiscovery-always-returns-false