How to programmatically set Discoverable time without user confirmation?
Solution 1
After some research I concluded that setting discoverable timeout without user interaction it's only possible with root access (as already suggested in the previous answer). However for someone who need that here is the necessary solution:
private void ensureBluetoothDiscoverability() {
try {
IBluetooth mBtService = getIBluetooth();
Log.d("TESTE", "Ensuring bluetoot is discoverable");
if(mBtService.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Log.e("TESTE", "Device was not in discoverable mode");
try {
mBtService.setDiscoverableTimeout(100);
// mBtService.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, 1000);
} catch(Exception e) {
Log.e("TESTE", "Error setting bt discoverable",e);
}
Log.i("TESTE", "Device must be discoverable");
} else {
Log.e("TESTE", "Device already discoverable");
}
} catch(Exception e) {
Log.e("TESTE", "Error ensuring BT discoverability", e);
}
}
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
And then create a new package android.bluetooth, place two files inside IBluetooth.aidl and IBluetoothCallback.aidl and put inside the code as shown here.
This will allow to access functions that are not available on the standard API, but for some of them you will need permission to "write secure settings" (the comment line above is where you will get that exception for lack of permissions of the process/user).
Solution 2
That's what I did and it works fine for me :
Method :
public void makeDiscoverable (int timeOut){
Class <?> baClass = BluetoothAdapter.class;
Method [] methods = baClass.getDeclaredMethods();
Method mSetScanMode = methods[44];
try {
mSetScanMode.invoke(Util.mBluetoothAdapter, BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeOut);
} catch (Exception e) {
Log.e("discoverable", e.getMessage());
}
}
Add permission :
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
Solution 3
Nothing - It still needs user confirmation.
BEing always discoverable is a drain on battery - so there is no easy solution Also it is a privacy issue. Its better to ask the user.
Tiago
Updated on June 13, 2022Comments
-
Tiago almost 2 years
I usually use this
private void ensureDiscoverable() { if(D) Log.d(TAG, "ensure discoverable"); if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); } }
But that prompts a user confirmation. Is there a way to bypass this programmatically?
Also, I suppose there are no "news" on the "always discoverable mode" ?
-
Tiago over 12 yearsI believe there is a workaround, I will check it, if found something usefull will share ;)
-
Tiago over 12 yearsI eventually found this devdaily.com/java/jwarehouse/android/core/java/android/… unfortunately the setDiscoverableTimout doesnt work :(
-
Glenn Maynard about 11 yearsThis isn't a privacy or battery issue--you cah always trigger discovery over and over, which doesn't ask anything.
-
kalpana c over 10 yearsHi, I tried with this code. But I am not getting success. I tested in LG 2.3.4. Can you tell me where I am doing wrong?
-
gumuruh almost 10 yearswhere do you get IBluetooth class @Tiago? @AnasAzeem?
-
gumuruh almost 10 years@Tiago, have you solved your case? Why i didnt see in my sdk for setting the time out...? (android 2.3)
-
stidiovip almost 9 years<uses-permission android:name="android.permission.WRITE_SETTINGS" />
-
nonsensei almost 8 yearssetScanMode is no more method number 44