How to programmatically set Discoverable time without user confirmation?

12,388

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.

Share:
12,388
Tiago
Author by

Tiago

Updated on June 13, 2022

Comments

  • Tiago
    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
    Tiago over 12 years
    I believe there is a workaround, I will check it, if found something usefull will share ;)
  • Tiago
    Tiago over 12 years
    I eventually found this devdaily.com/java/jwarehouse/android/core/java/android/… unfortunately the setDiscoverableTimout doesnt work :(
  • Glenn Maynard
    Glenn Maynard about 11 years
    This isn't a privacy or battery issue--you cah always trigger discovery over and over, which doesn't ask anything.
  • kalpana c
    kalpana c over 10 years
    Hi, 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
    gumuruh almost 10 years
    where do you get IBluetooth class @Tiago? @AnasAzeem?
  • gumuruh
    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
    stidiovip almost 9 years
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
  • nonsensei
    nonsensei almost 8 years
    setScanMode is no more method number 44