Issue
I am trying to add a "Scan available bluetooth devices" to my app. My app is running on devices with Android 7 or higher.
Till now, what I've found is that I must use the function startDiscovery()
which makes use of the permission BLUETOOTH_SCAN
. But for some reason, I can't get the dialog to show up for that permission and onRequestPermissionsResult()
gives me grantResults = [-1] (i.e. not PackageManager.PERMISSION_GRANTED
). I've been looking for several hours now why could be my issue but still no luck.
What I've tried:
- I've tested other permissions just to see if for some reason none of the permissions worked --> All other permissions (CAMERA, STORAGE,...) show the dialog if they are not already granted
- I've checked if for some reason there is a bluetooth permission denied on my device's settings page --> Apparently there isn't
- I've added a check to the following permissions because I read it might be related -->
BLUETOOTH
,BLUETOOTH_ADMIN
,ACCESS_COARSE_LOCATION
,ACCESS_FINE_LOCATION
(They are all granted on my app as of right now) - I've added a strong assertion that location is never used (yes, even if I added the permission) because I don't need it, I just want to scan available bluetooth devices -->
android:usesPermissionFlags="neverForLocation"
None of the above worked, dialog does not appear and permission is "by default" denied.
Here is an extract of my code: AndroidManifest.xml
...
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.CAMERA" />
...
MainActivity.java
...
private static final int CAMERA_PERMISSION_CODE = 100;
private static final int BT1_PERMISSION_CODE = 1001;
private static final int BT2_PERMISSION_CODE = 1002;
private static final int BT3_PERMISSION_CODE = 1003;
private static final int BT4_PERMISSION_CODE = 1004;
private static final int BT5_PERMISSION_CODE = 1005;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetooth1 = findViewById(R.id.bluetooth1);
bluetooth2 = findViewById(R.id.bluetooth2);
bluetooth3 = findViewById(R.id.bluetooth3);
bluetooth4 = findViewById(R.id.bluetooth4);
bluetooth5 = findViewById(R.id.bluetooth5);
camera = findViewById(R.id.camera);
// Set Buttons on Click Listeners
bluetooth1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.BLUETOOTH, BT1_PERMISSION_CODE);
}
});
bluetooth2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, BT2_PERMISSION_CODE);
}
});
bluetooth3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, BT3_PERMISSION_CODE);
}
});
bluetooth4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.BLUETOOTH_ADMIN, BT4_PERMISSION_CODE);
}
});
bluetooth5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.BLUETOOTH_SCAN, BT5_PERMISSION_CODE);
}
});
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
checkPermission(Manifest.permission.CAMERA, CAMERA_PERMISSION_CODE);
}
});
}
...
public void checkPermission(String permission, int requestCode)
{
if (ContextCompat.checkSelfPermission(MainActivity.this, permission) == PackageManager.PERMISSION_DENIED) {
// Requesting the permission
ActivityCompat.requestPermissions(MainActivity.this, new String[] { permission }, requestCode);
}
else {
Toast.makeText(MainActivity.this, "Permission already granted", Toast.LENGTH_SHORT).show();
}
}
...
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions,
@NonNull int[] grantResults)
{
super.onRequestPermissionsResult(requestCode,
permissions,
grantResults);
if (requestCode == CAMERA_PERMISSION_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "Camera Permission Granted", Toast.LENGTH_SHORT) .show();
}
else {
Toast.makeText(MainActivity.this, "Camera Permission Denied", Toast.LENGTH_SHORT) .show();
}
}
else if (requestCode == BT1_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "BT1 Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "BT1 Permission Denied", Toast.LENGTH_SHORT).show();
}
}
else if (requestCode == BT2_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "BT2 Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "BT2 Permission Denied", Toast.LENGTH_SHORT).show();
}
}
else if (requestCode == BT3_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "BT3 Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "BT3 Permission Denied", Toast.LENGTH_SHORT).show();
}
}
else if (requestCode == BT4_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "BT4 Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "BT4 Permission Denied", Toast.LENGTH_SHORT).show();
}
}
else if (requestCode == BT5_PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MainActivity.this, "BT5 Permission Granted", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "BT5 Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
...
Well, as of right now, when I ask for BLUETOOTH_SCAN
I automatically get a Toast saying "BT5 Permission Denied" but I did not get the opportunity to grant it.
Hope someone is able to give me a hint on what could be my problem
Solution
After several hours of checking, I did not manage to display any dialog box. Strangely enough, I did manage to get startDiscovery()
to work.
For some reason I don't understand, startDiscovery()
makes use of the permission BLUETOOTH_SCAN
which should be granted by the user, and since no dialog box appears, permission is indeed "denied". But just by using the requestPermissions()
method, IDE does not complain and discovery is made.
What is true is that location permissions need to be granted, and both BLUETOOTH
and BLUETOOTH_ADMIN
must be declared in the manifest.
I don't understand it, but it works, so I'm not gonna complain about it ¯\_(ツ)_/¯
Answered By - P. Frau
Answer Checked By - Pedro (JavaFixing Volunteer)