114

I want to enable/disable bluetooth through the program. I have the following code.

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    
if (!mBluetoothAdapter.isEnabled()) {
        Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

But this code is not working in SDK 1.5. How can I make it work?

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
user458295
  • 1,239
  • 4
  • 12
  • 11

10 Answers10

171

this code worked for me..

//Disable bluetooth
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    
if (mBluetoothAdapter.isEnabled()) {
    mBluetoothAdapter.disable(); 
} 
    

For this to work, you must have the following permissions:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

Update for API 33+

In Android API 33+ (13+) this method is deprecated and enabling/disabling bluetooth without user consent is not more possible. According to documentation, you should use ACTION_REQUEST_ENABLE instead.

Prijin Koshy Alex
  • 1,837
  • 3
  • 14
  • 17
  • it really works for me also. simple method to disconnect the bluetooth in android devices. thanks a lot buddy. – Amit Thaper Jun 14 '11 at 06:39
  • 7
    if you add BLUETOOTH_ADMIN permission it's work but if not you need to use startActivityForResult(enableBtIntent, 0); to enable your bluetooth – Majid Golshadi Jan 11 '14 at 14:17
  • 1
    Thanks for your useful answer +1 . just I want to add for who doesn't know how to enable it: mBluetoothAdapter.enable() – Chris Sim Apr 21 '15 at 13:45
  • 1
    Those manifest permissions do not work for me in 2022. The correct one is `android.permission.BLUETOOTH_CONNECT`. Otherwise it will give permission but will not disable. – Luis A. Florit Jun 26 '22 at 13:13
103

Here is a bit more robust way of doing this, also handling the return values of enable()\disable() methods:

public static boolean setBluetooth(boolean enable) {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    boolean isEnabled = bluetoothAdapter.isEnabled();
    if (enable && !isEnabled) {
        return bluetoothAdapter.enable(); 
    }
    else if(!enable && isEnabled) {
        return bluetoothAdapter.disable();
    }
    // No need to change bluetooth state
    return true;
}

And add the following permissions into your manifest file:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

But remember these important points:

This is an asynchronous call: it will return immediately, and clients should listen for ACTION_STATE_CHANGED to be notified of subsequent adapter state changes. If this call returns true, then the adapter state will immediately transition from STATE_OFF to STATE_TURNING_ON, and some time later transition to either STATE_OFF or STATE_ON. If this call returns false then there was an immediate problem that will prevent the adapter from being turned on - such as Airplane mode, or the adapter is already turned on.

UPDATE:

Ok, so how to implement bluetooth listener?:

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
            final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                                 BluetoothAdapter.ERROR);
            switch (state) {
            case BluetoothAdapter.STATE_OFF:
                // Bluetooth has been turned off;
                break;
            case BluetoothAdapter.STATE_TURNING_OFF:
                // Bluetooth is turning off;
                break;
            case BluetoothAdapter.STATE_ON:
                // Bluetooth is on
                break;
            case BluetoothAdapter.STATE_TURNING_ON:
                // Bluetooth is turning on
                break;
            }
        }
    }
};

And how to register/unregister the receiver? (In your Activity class)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // ...

    // Register for broadcasts on BluetoothAdapter state change
    IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(mReceiver, filter);
}

@Override
public void onStop() {
    super.onStop();

     // ...

    // Unregister broadcast listeners
    unregisterReceiver(mReceiver);
}
Caner
  • 57,267
  • 35
  • 174
  • 180
  • 1
    if you add `BLUETOOTH_ADMIN` permission it's work but if not you need to use `startActivityForResult(enableBtIntent, 0);` to enable your bluetooth – Majid Golshadi Jan 11 '14 at 14:16
  • 1
    the highlighted info is quoted from the BluetoothAdapter docs, specifically for the enable() method. – Kevin Lee Dec 17 '15 at 16:09
  • 1
    hey, the docs say that `Bluetooth should never be enabled without direct user consent. If you want to turn on Bluetooth in order to create a wireless connection, you should use the ACTION_REQUEST_ENABLE Intent, which will raise a dialog that requests user permission to turn on Bluetooth. The enable() method is provided only for applications that include a user interface for changing system settings, such as a "power manager" app.` What does it mean? For ex. I made a little app from your code and it worked. But if I want to upload to Play Store, it won't work? – Hilal Jun 08 '19 at 02:10
  • @Hilal it will work. But users need to give consent before installation. They will see a dialog like this: https://www.pewinternet.org/2015/11/10/apps-permissions-in-the-google-play-store/pi_2015-11-10_apps-permissions_0-01/ – Caner Jun 10 '19 at 11:58
31

Android BluetoothAdapter docs say it has been available since API Level 5. API Level 5 is Android 2.0.

You can try using a backport of the Bluetooth API (have not tried it personally): http://code.google.com/p/backport-android-bluetooth/

James Schek
  • 17,844
  • 7
  • 51
  • 64
28

To Enable the Bluetooth you could use either of the following functions:

 public void enableBT(){
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (!mBluetoothAdapter.isEnabled()){
        Intent intentBtEnabled = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
        // The REQUEST_ENABLE_BT constant passed to startActivityForResult() is a locally defined integer (which must be greater than 0), that the system passes back to you in your onActivityResult() 
        // implementation as the requestCode parameter. 
        int REQUEST_ENABLE_BT = 1;
        startActivityForResult(intentBtEnabled, REQUEST_ENABLE_BT);
        }
  }

The second function is:

public void enableBT(){
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (!mBluetoothAdapter.isEnabled()){
        mBluetoothAdapter.enable();
    }
}

The difference is that the first function makes the app ask the user a permission to turn on the Bluetooth or to deny. The second function makes the app turn on the Bluetooth directly.

To Disable the Bluetooth use the following function:

public void disableBT(){
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter.isEnabled()){
        mBluetoothAdapter.disable();
    }
}

NOTE/ The first function needs only the following permission to be defined in the AndroidManifest.xml file:

<uses-permission android:name="android.permission.BLUETOOTH"/>

While, the second and third functions need the following permissions:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Syed Afeef
  • 140
  • 1
  • 9
Ahmed Alnabhan
  • 608
  • 1
  • 9
  • 13
6

The solution of prijin worked perfectly for me. It is just fair to mention that two additional permissions are needed:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

When these are added, enabling and disabling works flawless with the default bluetooth adapter.

Caner
  • 57,267
  • 35
  • 174
  • 180
Peter Osburg
  • 276
  • 1
  • 4
  • 10
3

I used the below code to disable BT when my app launches and works fine. Not sure if this the correct way to implement this as google recommends not using "bluetooth.disable();" without explicit user action to turn off Bluetooth.

    BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
    bluetooth.disable();

I only used the below permission.

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
nik
  • 151
  • 3
  • 12
  • One may have problems with this method if the app is dependent on Bluetooth being off because there is a race condition since bluetooth.disable() is asynchronous... – David Aug 22 '21 at 09:28
3

I have made a class to handle almost all this in Kotlin using Coroutines


class ActivityResultHandler(
    private val registry: ActivityResultRegistry
) {

    private val handlers = mutableListOf<ActivityResultLauncher<*>>()

    fun unregisterHandlers() {
        handlers.forEach {
            it.unregister()
        }
    }

    suspend fun requestLocationPermission(): Boolean {
        return suspendCoroutine<Boolean> { continuation ->
            val launcher = registry.register(
                LOCATION_PERMISSION_REQUEST,
//                lifecycleOwner,
                ActivityResultContracts.RequestPermission()
            ) {
                continuation.resumeWith(Result.success(it))
            }
            handlers.add(launcher)
            launcher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
        }
    }

    suspend fun requestBluetoothActivation(): Boolean {
        return suspendCoroutine<Boolean> { continuation ->
            val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)

            val launcher = registry.register(
                BLUETOOTH_ON_REQUEST,
//                lifecycleOwner,
                ActivityResultContracts.StartActivityForResult()
            ) { result ->
                continuation.resume(
                    result.resultCode == Activity.RESULT_OK
                )
            }
            handlers.add(launcher)
            launcher.launch(enableBtIntent)
        }
    }

    fun checkLocationPermission(context: Context): Boolean {
        return ContextCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    }

    private suspend fun requestLocationActivation(
        intentSenderRequest: IntentSenderRequest,
    ): Boolean {
        return suspendCoroutine { continuation ->
            val launcher = registry.register(
                LOCATION_ACTIVATION_REQUEST,
//                lifecycleOwner,
                ActivityResultContracts.StartIntentSenderForResult()
            ) {
                continuation.resume(it.resultCode == Activity.RESULT_OK)
            }
            handlers.add(launcher)
            launcher.launch(intentSenderRequest)
        }
    }


    suspend fun enableLocation(context: Context): Boolean =
        suspendCoroutine { continuation ->

            val locationSettingsRequest = LocationSettingsRequest.Builder()
//        .setNeedBle(true)
                .addLocationRequest(
                    LocationRequest.create().apply {
                        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
                    }
                )
                .build()

            val client: SettingsClient = LocationServices.getSettingsClient(context)
            val task: Task<LocationSettingsResponse> =
                client.checkLocationSettings(locationSettingsRequest)

            task.addOnSuccessListener {
                continuation.resume(true)
            }
            task.addOnFailureListener { exception ->
                if (exception is ResolvableApiException &&
                    exception.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED
                ) {
                    val intentSenderRequest =
                        IntentSenderRequest.Builder(exception.resolution).build()

                    CoroutineScope(continuation.context).launch {
                        val result = requestLocationActivation(intentSenderRequest)
                        continuation.resume(result)
                    }
                } else {
                    continuation.resume(false)
                }
            }
        }


    companion object {
        private const val LOCATION_PERMISSION_REQUEST = "LOCATION_REQUEST"
        private const val BLUETOOTH_ON_REQUEST = "LOCATION_REQUEST"
        private const val LOCATION_ACTIVATION_REQUEST = "LOCATION_REQUEST"
    }
}

Use it like this:

// make sure you extend AppCompatActivity
class MainActivity : AppCompatActivity() {

    private val permissionRequests = ActivityResultHandler(activityResultRegistry)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // use viewmodels and fragments instead of GlobalScope
        GlobalScope.launch {
            // turn on bluetooth
            permissionRequests.requestBluetoothActivation()
            // to be able to scan for devices you also need location permission
            // also show pop up to let users know why you need location
            // https://support.google.com/googleplay/android-developer/answer/9799150?hl=en
            permissionRequests.requestLocationPermission()
            // also you need navigation to be enabled
            permissionRequests.enableLocation(this@MainActivity)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        permissionRequests.unregisterHandlers()
    }
}

coroutines dependency in gradle

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'

also add this permissions to manifest

    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
George Shalvashvili
  • 1,263
  • 13
  • 21
3

Updated for Android 12:

AndroidManifest.xml -

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>

You must perform the standard permission request for BLUETOOTH_CONNECT as you would when requesting permission for storage or other "prompted" items.

Usage (Kotlin) -

val bluetoothAdapter = (getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter
if (bluetoothAdapter.isEnabled)
    bluetoothAdapter.disable()

For Android 12 and above, BLUETOOTH and BLUETOOTH_ADMIN permissions are not necessary to retrieve the current state or toggle it, unless targeting lower APIs.

Abandoned Cart
  • 4,512
  • 1
  • 34
  • 41
  • This doesn't seem to work, are you sure it's supported on Android 12+? I tested on a Pixel 5 running Android 13 – behelit Feb 14 '23 at 22:59
  • 2
    @behelit Android 13 removed the ability to enable and disable the adapter. No alternative, just stripped it from the developers. – Abandoned Cart Feb 15 '23 at 02:29
  • BluetoothAdapter is deprecated from Android OS13. Is there any alternate to enable the bluetooth programatically on OS13? – tklanilkumar Jul 05 '23 at 11:29
  • @tklanilkumar Google specifically removed that option. It appears you are stuck with using the intents now. Google is creating the illusion of safety through poorly designed and excessive popups. The more it has to look like malware, the less likely you are to bother at all or something like that. – Abandoned Cart Jul 06 '23 at 11:48
1

Add the following permissions into your manifest file:

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

Enable bluetooth use this

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    
if (!mBluetoothAdapter.isEnabled()) {
    mBluetoothAdapter.enable(); 
}else{Toast.makeText(getApplicationContext(), "Bluetooth Al-Ready Enable", Toast.LENGTH_LONG).show();}

Disable bluetooth use this

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();    
if (mBluetoothAdapter.isEnabled()) {
    mBluetoothAdapter.disable(); 
}
Selim Raza
  • 497
  • 7
  • 16
0

try this:

//this method to check bluetooth is enable or not: true if enable, false is not enable
public static boolean isBluetoothEnabled()
    {
        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBluetoothAdapter.isEnabled()) {
            // Bluetooth is not enable :)
            return false;
        }
        else{
            return true;
        }

    }

//method to enable bluetooth
    public static void enableBluetooth(){
        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (!mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.enable();
        }
    }

//method to disable bluetooth
    public static void disableBluetooth(){
        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.disable();
        }
    }

Add these permissions in manifest

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Bapusaheb Shinde
  • 839
  • 2
  • 13
  • 16