BluetoothAdapter — ce que c'est, méthodes et gestion du Bluetooth dans Android

Auteur : IT Sectr Publié le : 2026-07-16 Temps de lecture : 10 min

BluetoothAdapter est une classe système Android qui représente l'adaptateur Bluetooth local d'un appareil. BluetoothAdapter est le point d'entrée pour toutes les opérations Bluetooth sur Android : activation de la radio (enable), scan des appareils, gestion de la visibilité (setScanMode), récupération des informations de l'adaptateur (getName, getAddress, getState). La classe est disponible via BluetoothManager.getAdapter() (API 18+) ou BluetoothAdapter.getDefaultAdapter(). Sur les appareils sans module Bluetooth, getDefaultAdapter() retourne null. Selon Android Developers, 2026, BluetoothAdapter est un composant obligatoire pour toute application BLE sur Android, à partir de l'API 5.

Points clés

  • BluetoothAdapter est une classe système Android pour gérer l'adaptateur Bluetooth local d'un appareil
  • getDefaultAdapter() est une méthode statique pour obtenir une instance ; retourne null sur les appareils sans Bluetooth
  • getBluetoothLeScanner() est la méthode pour accéder au scanner BLE moderne (API 21+)
  • enable/disable sont des méthodes pour activer et désactiver la radio Bluetooth (nécessitent l'autorisation BLUETOOTH_ADMIN)
  • startDiscovery/startLeScan sont des méthodes de scan classique et BLE (LE Scan obsolète, utilisez BluetoothLeScanner)

Qu'est-ce que BluetoothAdapter : essence et obtention de l'instance

BluetoothAdapter représente l'adaptateur Bluetooth physique d'un appareil Android. Chaque appareil possède exactement un adaptateur (exception : Android Automotive avec plusieurs puces Bluetooth, qui utilise BluetoothManager.getAdapterList()). BluetoothAdapter encapsule l'état de la radio : STATE_OFF (0), STATE_TURNING_ON (1), STATE_ON (2), STATE_TURNING_OFF (3). L'état est suivi via BroadcastReceiver sur ACTION_STATE_CHANGED.

Obtenir une instance de BluetoothAdapter est la première étape de toute application BLE sur Android. La méthode recommandée est via BluetoothManager.getAdapter() à partir de l'API 18+. L'alternative est la méthode statique BluetoothAdapter.getDefaultAdapter(), qui fonctionne depuis l'API 5 mais est moins flexible. Les deux méthodes retournent null si l'appareil n'a pas de module Bluetooth (tablettes Wi-Fi uniquement, émulateur). La vérification de null est obligatoire : l'application doit se terminer correctement ou désactiver les fonctionnalités BLE.

kotlin
// Obtenir BluetoothAdapter (recommandé)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context

class BluetoothHelper(context: Context) {

    private val bluetoothAdapter: BluetoothAdapter?

    init {
        // Méthode 1 : via BluetoothManager (API 18+)
        val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
                as BluetoothManager?
        bluetoothAdapter = manager?.adapter

        // Méthode 2 : via méthode statique (API 5+)
        // val adapter = BluetoothAdapter.getDefaultAdapter()

        // Vérification de null
        if (bluetoothAdapter == null) {
            // L'appareil ne prend pas en charge Bluetooth
        }
    }

    // Vérifier l'état Bluetooth
    fun isBluetoothEnabled(): Boolean {
        return bluetoothAdapter?.isEnabled == true
    }

    // Obtenir les informations de l'adaptateur
    fun getAdapterInfo(): Map<String, String> {
        return mapOf(
            "name" to (bluetoothAdapter?.name ?: "N/A"),
            "address" to (bluetoothAdapter?.address ?: "N/A"),
            "state" to (bluetoothAdapter?.state?.toString() ?: "N/A"),
            "scanMode" to (bluetoothAdapter?.scanMode?.toString() ?: "N/A")
        )
    }
}

La classe BluetoothHelper démontre l'obtention de BluetoothAdapter via BluetoothManager avec une vérification de null ultérieure. isBluetoothEnabled vérifie isEnabled — une condition obligatoire avant toute opération BLE. getAdapterInfo retourne le nom de l'appareil, l'adresse MAC, l'état et le mode de visibilité. Important : sur Android 10+ (API 29+), le service système retourne une adresse MAC fictive (02:00:00:00:00:00) si l'application n'a pas les autorisations BLUETOOTH_ADMIN et ACCESS_FINE_LOCATION.

Méthodes principales de BluetoothAdapter : enable, disable, getState, getAddress

BluetoothAdapter fournit des méthodes pour contrôler la radio Bluetooth. enable() et disable() activent et désactivent le Bluetooth. Les deux méthodes nécessitent l'autorisation BLUETOOTH_ADMIN et s'exécutent de manière asynchrone : après avoir appelé enable(), le système lance le processus d'activation de la radio, et l'état est suivi via BroadcastReceiver avec l'action BluetoothAdapter.ACTION_STATE_CHANGED. Sur Android 10+, enable() et disable() nécessitent un privilège système supplémentaire — les applications normales ne peuvent pas contrôler Bluetooth par programmation sans dialogue utilisateur.

getState() retourne l'état actuel de l'adaptateur : STATE_OFF (10), STATE_TURNING_ON (11), STATE_ON (12), STATE_TURNING_OFF (13). getAddress() retourne l'adresse MAC de l'adaptateur Bluetooth. Sur Android 6+, ACCESS_FINE_LOCATION (ou ACCESS_COARSE_LOCATION pour API 31+) est requis pour demander l'adresse MAC. Sur Android 10+, getAddress() retourne l'adresse constante 02:00:00:00:00:00 — l'adresse réelle n'est pas disponible via l'API publique.

getScanMode() détermine le mode de visibilité de l'adaptateur : SCAN_MODE_NONE (invisible), SCAN_MODE_CONNECTABLE (visible pour les appareils connectés), SCAN_MODE_CONNECTABLE_DISCOVERABLE (visible pour tous). Le mode de visibilité est limité dans le temps (généralement 60 à 300 secondes) pour des raisons de sécurité. Définir le mode via setScanMode() nécessite BLUETOOTH_ADMIN et une autorisation système sur Android 10+.

MéthodeDescriptionAutorisation requise
enable()Activer la radio BluetoothBLUETOOTH_ADMIN
disable()Désactiver la radio BluetoothBLUETOOTH_ADMIN
getState()État actuel de l'adaptateurBLUETOOTH
getAddress()Adresse MAC de l'adaptateurBLUETOOTH + ACCESS_FINE_LOCATION (API 23+)
getScanMode()Mode de visibilité de l'appareilBLUETOOTH
setScanMode()Définir le mode de visibilitéBLUETOOTH_ADMIN

Scan des appareils : startDiscovery et BluetoothLeScanner

BluetoothAdapter prend en charge deux types de scan. Le scan Bluetooth classique (BR/EDR) est lancé via startDiscovery() — il détecte les appareils Bluetooth de tous types, y compris les téléphones et les casques. Les résultats sont retournés via BroadcastReceiver avec l'action BluetoothDevice.ACTION_FOUND. startDiscovery() fonctionne pendant 12 secondes et peut être annulé en appelant cancelDiscovery(). Cette méthode est obsolète pour le BLE — utilisez BluetoothLeScanner.

Le scan BLE via BluetoothAdapter utilise la méthode obsolète startLeScan(LeScanCallback). À partir de l'API 21, Google recommande d'utiliser BluetoothLeScanner, obtenu via BluetoothAdapter.getBluetoothLeScanner(). BluetoothLeScanner fournit une API plus flexible : configuration du scan via ScanSettings (mode, type de callback, mode de correspondance), filtrage via ScanFilter (par UUID de service, nom d'appareil, adresse MAC) et prise en charge de PendingIntent pour le scan en arrière-plan.

kotlin
// API de scan BLE ancienne (obsolète) vs nouvelle
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*

class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {

    // OBSOLÈTE : startLeScan (API 18+, API 21)
    @Suppress("DEPRECATION")
    fun legacyScan() {
        bluetoothAdapter?.startLeScan { device, rssi, scanRecord ->
            print("Found (LE Scan): $device.name, RSSI: $rssi")
        }
    }

    // NOUVEAU : BluetoothLeScanner (API 21+)
    fun modernScan() {
        val scanner = bluetoothAdapter?.bluetoothLeScanner
            ?: return

        // Paramètres de scan
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
            .build()

        // Filtrer par service (UUID fréquence cardiaque)
        val filters = listOf(
            ScanFilter.Builder()
                .setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
                .build()
        )

        // Démarrer le scan
        scanner.startScan(filters, settings, object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                val device = result.device
                val rssi = result.rssi
                print("Found (BLE Scanner): ${device.name}, RSSI: $rssi, address: ${device.address}")
            }

            override fun onScanFailed(errorCode: Int) {
                print("Scan error: $errorCode")
            }
        })
    }
}

La classe BLEScanner compare l'obsolète startLeScan avec le moderne BluetoothLeScanner. Dans legacyScan, LeScanCallback reçoit BluetoothDevice, RSSI et scanRecord brut. Dans modernScan, ScanSettings avec le mode LOW_LATENCY (vitesse de détection maximale) et ScanFilter pour filtrer par UUID du service de fréquence cardiaque (0x180D) sont utilisés. ScanCallback fournit onScanResult avec un objet ScanResult contenant des informations étendues : nom, RSSI, données publicitaires, type de connexion.

BluetoothManager : API moderne pour accéder à BluetoothAdapter

BluetoothManager est un service système Android, introduit dans l'API 18 (Android 4.3), pour gérer les opérations Bluetooth. Avant l'API 18, la seule façon d'obtenir BluetoothAdapter était la méthode statique getDefaultAdapter(). BluetoothManager fournit : adapter — une instance de BluetoothAdapter, getConnectedDevices() — une liste des appareils connectés, getDevicesMatchingConnectionStates() — filtrage par état. BluetoothManager est également utilisé pour obtenir BluetoothLeScanner sur les anciennes API.

Avantages de BluetoothManager par rapport à l'appel direct de BluetoothAdapter.getDefaultAdapter() : l'application ne dépend pas d'un singleton statique, le gestionnaire respecte le contexte (Activity/Application), ce qui est important pour les scénarios multi-comptes d'Android Enterprise. Sur Android Automotive avec plusieurs puces Bluetooth, BluetoothManager.getAdapterList() retourne tous les adaptateurs disponibles — BluetoothAdapter.getDefaultAdapter() retourne uniquement le premier.

kotlin
// Utiliser BluetoothManager pour BLE
class BLEConnection(context: Context) {

    private val bluetoothManager: BluetoothManager =
        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager

    private val adapter: BluetoothAdapter? = bluetoothManager.adapter

    // Obtenir la liste des appareils BLE connectés
    fun getConnectedDevices(): List<BluetoothDevice> {
        return bluetoothManager.getConnectedDevices(
            BluetoothProfile.GATT
        )
    }

    // Filtrer les appareils par état
    fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
        return bluetoothManager.getDevicesMatchingConnectionStates(
            BluetoothProfile.GATT, states
        )
    }

    // Vérifier la prise en charge BLE sur l'appareil
    fun isBLESupported(): Boolean {
        return adapter != null && context.packageManager
            .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
    }

    // Demander l'activation Bluetooth via la boîte de dialogue système
    fun requestEnableBluetooth(activity: MainActivity) {
        if (adapter?.isEnabled == false) {
            val intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
            activity.startActivityForResult(intent, REQUEST_ENABLE_BT)
        }
    }

    companion object {
        const val REQUEST_ENABLE_BT = 1001
    }
}

La classe BLEConnection utilise BluetoothManager pour accéder à BluetoothAdapter et obtenir la liste des appareils GATT connectés. isBLESupported vérifie la présence de radio BLE via PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) — une vérification importante pour les appareils avec Bluetooth Classic sans BLE. requestEnableBluetooth affiche la boîte de dialogue système d'activation du Bluetooth (ACTION_REQUEST_ENABLE), sans nécessiter l'autorisation BLUETOOTH_ADMIN — c'est la seule façon légale d'activer Bluetooth sur Android 10+ sans application système.

Autorisations Android pour travailler avec BluetoothAdapter

Les autorisations pour BluetoothAdapter ont évolué avec chaque version d'Android. Sur Android 6–11 (API 23–30), BLUETOOTH, BLUETOOTH_ADMIN et ACCESS_FINE_LOCATION sont obligatoires pour le scan BLE. Sur Android 12+ (API 31+), Google a divisé les autorisations : ACCESS_FINE_LOCATION est remplacé par BLUETOOTH_SCAN (scan), BLUETOOTH_CONNECT (connexion), BLUETOOTH_ADVERTISE (publicité). Pour la détection des appareils BLE, BLUETOOTH_SCAN suffit, la localisation n'est pas requise.

Tableau des autorisations par version d'Android :

OpérationAPI 23–30API 31+
Scan BLEACCESS_FINE_LOCATIONBLUETOOTH_SCAN (sans localisation)
Connexion BLEACCESS_FINE_LOCATIONBLUETOOTH_CONNECT
Publicité BLEACCESS_FINE_LOCATIONBLUETOOTH_ADVERTISE
Activation/désactivationBLUETOOTH_ADMINBLUETOOTH_ADMIN (système)
Obtention adresse MACACCESS_FINE_LOCATIONBLUETOOTH_CONNECT (adresse fictive)

Sur Android 12+, toutes les autorisations Bluetooth sont des autorisations d'exécution — elles doivent être demandées au moment de l'exécution via ActivityResultContracts.RequestMultiplePermissions. BLUETOOTH_SCAN et BLUETOOTH_ADVERTISE appartiennent au groupe NEARBY_DEVICES, BLUETOOTH_CONNECT appartient au même groupe. Les autorisations BLUETOOTH et BLUETOOTH_ADMIN restent dans le manifeste pour la compatibilité avec API < 31, mais pour API 31+ elles sont ignorées — Google exige de spécifier explicitement les nouvelles autorisations.

kotlin
// Demander les autorisations Bluetooth sur Android 12+
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.content.ContextCompat

class PermissionHelper(context: Context) {

    fun getRequiredPermissions(): Array<String> {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            // Android 12+ : BLE-
            arrayOf(
                Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.BLUETOOTH_ADVERTISE
            )
        } else {
            // Android 6-11 : BLE
            arrayOf(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN
            )
        }
    }

    // Vérifier toutes les autorisations
    fun hasPermissions(context: Context): Boolean {
        return getRequiredPermissions().all { permission ->
            ContextCompat.checkSelfPermission(context, permission)
                    == PackageManager.PERMISSION_GRANTED
        }
    }
}

La classe PermissionHelper retourne l'ensemble correct d'autorisations en fonction du niveau d'API. Sur Android 12+, BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE sans localisation sont utilisés. Sur Android 6–11, ACCESS_FINE_LOCATION est toujours requis pour le scan BLE. Le développeur doit prendre en compte les deux scénarios lors de la demande d'autorisations via ActivityResultContracts ou RxPermissions.

Exemple complet de BluetoothAdapter en Kotlin

Exemple complet d'une application BLE en Kotlin utilisant BluetoothAdapter pour scanner, connecter et lire les données d'un appareil BLE. L'exemple couvre la vérification des autorisations, l'obtention de l'adaptateur, le scan via BluetoothLeScanner et la connexion via BluetoothDevice.connectGatt.

kotlin
// Gestionnaire BLE complet en Kotlin
class BLEManager(private val context: Context) {

    private val bluetoothManager: BluetoothManager =
        context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
    private val adapter: BluetoothAdapter? = bluetoothManager.adapter
    private var scanner: BluetoothLeScanner? = adapter?.bluetoothLeScanner
    private var gatt: BluetoothGatt? = null

    // 1. Découverte de services
    fun canScan(): Boolean {
        return adapter?.isEnabled == true
                && scanner != null
                && PermissionHelper(context).hasPermissions(context)
    }

    // 2. avec filtre
    fun startScanning(callback: (BluetoothDevice, Int) -> Unit) {
        if (!canScan()) return

        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setReportDelay(0)
            .build()

        scanner?.startScan(null, settings, object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                callback(result.device, result.rssi)
            }
        })
    }

    // 3. Arrêter le scan
    fun stopScanning() {
        scanner?.stopScan(object : ScanCallback() {})
    }

    // 4. Se connecter à l'appareil BLE
    fun connectToDevice(device: BluetoothDevice) {
        if (adapter?.isEnabled != true) return

        gatt = device.connectGatt(
            context,
            false,
            object : BluetoothGattCallback() {
                override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        gatt.discoverServices()
                    }
                }

                override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
                    // Services trouvés, peut lire les caractéristiques
                }
            },
            BluetoothDevice.TRANSPORT_LE
        )
    }

    // 5. Libérer les ressources
    fun disconnect() {
        gatt?.disconnect()
        gatt?.close()
        gatt = null
    }
}

La classe BLEManager unifie le cycle BLE complet sur Android : vérification de l'adaptateur et des autorisations (canScan), scan via BluetoothLeScanner avec ScanSettings (startScanning), connexion via BluetoothDevice.connectGatt avec TRANSPORT_LE (connectToDevice) et libération des ressources (disconnect). Toutes les opérations BLE s'exécutent sur le thread de l'interface utilisateur — Android appelle les callbacks BluetoothGattCallback sur le thread principal. Pour les tâches BLE intensives, il est recommandé de déporter les opérations GATT vers un HandlerThread en arrière-plan.

Foire aux questions

Qu'est-ce que BluetoothAdapter dans Android ?

BluetoothAdapter est une classe représentant l'adaptateur Bluetooth local d'un appareil Android. Elle est obtenue via BluetoothManager.getAdapter() (API 18+) ou BluetoothAdapter.getDefaultAdapter(). Elle fournit des méthodes pour activer/désactiver le Bluetooth, scanner des appareils, gérer la visibilité et obtenir des informations sur l'adaptateur. Retourne null sur les appareils sans module Bluetooth.

Pourquoi BluetoothAdapter.getDefaultAdapter() retourne-t-il null ?

La raison est l'absence de radio Bluetooth sur l'appareil. Typique pour les tablettes Wi-Fi uniquement, l'émulateur Android et Android TV sans Bluetooth. Vérifiez getDefaultAdapter() à null au démarrage de l'application et désactivez les fonctions BLE si l'adaptateur est absent. Une alternative est la vérification via PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) pour une détection plus précise.

En quoi BluetoothLeScanner diffère-t-il de startLeScan ?

BluetoothLeScanner (API 21+) est l'API moderne pour le scan BLE avec prise en charge de ScanFilter, ScanSettings et PendingIntent. startLeScan (API 18+) est une méthode obsolète de BluetoothAdapter qui accepte LeScanCallback avec un ensemble de données limité. Google recommande BluetoothLeScanner pour tous les nouveaux projets, permet de filtrer par UUID, de configurer le mode de consommation d'énergie et de fonctionner en arrière-plan via PendingIntent.

Quelles autorisations sont nécessaires pour le BLE sur Android 12+ ?

Sur Android 12+ (API 31), le scan BLE nécessite BLUETOOTH_SCAN, la connexion nécessite BLUETOOTH_CONNECT et la publicité nécessite BLUETOOTH_ADVERTISE. L'autorisation de localisation ACCESS_FINE_LOCATION n'est plus requise pour le BLE. Sur Android 6–11, ACCESS_FINE_LOCATION est requis. Toutes les autorisations sont demandées au moment de l'exécution via ActivityResultContracts.

Peut-on activer Bluetooth par programmation sans dialogue ?

Sur Android 10+, l'activation programmatique du Bluetooth sans dialogue système est disponible uniquement pour les applications système avec l'autorisation BLUETOOTH_PRIVILEGED. Les applications normales doivent utiliser Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) et startActivityForResult — l'utilisateur confirme l'activation dans la boîte de dialogue système. BLUETOOTH_ADMIN dans le manifeste n'accorde pas les droits enable() sur Android 10+.

Résumé

  • BluetoothAdapter est le point d'entrée pour toutes les opérations Bluetooth sur Android, obtenu via BluetoothManager ou getDefaultAdapter()
  • getState() et isEnabled sont des vérifications de base de l'état de la radio Bluetooth avant toute opération BLE
  • BluetoothLeScanner (API 21+) remplace l'obsolète startLeScan avec la prise en charge de ScanFilter, ScanSettings et PendingIntent
  • BluetoothManager est la façon moderne d'obtenir BluetoothAdapter avec la prise en charge des scénarios multi-comptes et Automotive
  • Les autorisations ont évolué : ACCESS_FINE_LOCATION (API 23-30) → BLUETOOTH_SCAN/CONNECT/ADVERTISE (API 31+)
  • enable()/disable() — sur Android 10+ uniquement via le dialogue système ACTION_REQUEST_ENABLE pour les applications normales
  • connectGatt est une méthode de BluetoothDevice pour établir une connexion GATT avec des périphériques BLE via BluetoothGattCallback

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi