8

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" ?

Community
  • 1
  • 1
Tiago
  • 1,116
  • 5
  • 25
  • 39

4 Answers4

6

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).

Ziem
  • 6,579
  • 8
  • 53
  • 86
Tiago
  • 1,116
  • 5
  • 25
  • 39
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" />  
Eduardo Briguenti Vieira
  • 4,351
  • 3
  • 37
  • 49
stidiovip
  • 110
  • 5
1

After testing and searching for various options, I have created these lines that don't require an user interaction. I hope it helps:

In method:

try{
   Method metodo = BluetoothAdapter.class.getMethod("setScanMode", int.class);
   try {
      metodo.invoke(bluetoothAdaptador, SCAN_MODE_CONNECTABLE_DISCOVERABLE);
   }catch (InvocationTargetException e) {
       e.printStackTrace();
   }
}catch (NoSuchMethodException | IllegalArgumentException | IllegalAccessException e) {
            Log.e(TAG, "Fallo al hacer visibile el dispositivo.", e);}
Pepe
  • 11
  • 2
1

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.

Dennis Mathews
  • 6,897
  • 2
  • 26
  • 39
  • I believe there is a workaround, I will check it, if found something usefull will share ;) – Tiago Jan 06 '12 at 18:10
  • I eventually found this http://www.devdaily.com/java/jwarehouse/android/core/java/android/bluetooth/BluetoothAdapter.java.shtml unfortunately the setDiscoverableTimout doesnt work :( – Tiago Jan 10 '12 at 15:58
  • 1
    This isn't a privacy or battery issue--you cah always trigger discovery over and over, which doesn't ask anything. – Glenn Maynard May 16 '13 at 14:59
  • @Tiago, have you solved your case? Why i didnt see in my sdk for setting the time out...? (android 2.3) – gumuruh Jul 07 '14 at 08:54