BluetoothAdapter — o que é, métodos e gerenciamento de Bluetooth no Android

Autor: IT Sectr Publicado: 2026-07-16 Tempo de leitura: 10 min

BluetoothAdapter é uma classe de sistema Android que representa o adaptador Bluetooth local de um dispositivo. BluetoothAdapter é o ponto de entrada para todas as operações Bluetooth no Android: ativar o rádio (enable), escanear dispositivos, gerenciar visibilidade (setScanMode) e obter informações do adaptador (getName, getAddress, getState). A classe está disponível via BluetoothManager.getAdapter() (API 18+) ou BluetoothAdapter.getDefaultAdapter(). Em dispositivos sem módulo Bluetooth, getDefaultAdapter() retorna null. De acordo com Android Developers, 2026, BluetoothAdapter é um componente obrigatório para qualquer aplicação BLE no Android, a partir da API 5.

Principais pontos

  • BluetoothAdapter é uma classe de sistema Android para gerenciar o adaptador Bluetooth local de um dispositivo
  • getDefaultAdapter() é um método estático para obter uma instância; retorna null em dispositivos sem Bluetooth
  • getBluetoothLeScanner() é o método para acessar o scanner BLE moderno (API 21+)
  • enable/disable são métodos para ligar e desligar o rádio Bluetooth (requerem permissão BLUETOOTH_ADMIN)
  • startDiscovery/startLeScan são métodos de varredura clássica e BLE (LE Scan obsoleto, use BluetoothLeScanner)

O que é BluetoothAdapter: essência e obtenção da instância

BluetoothAdapter representa o adaptador Bluetooth físico de um dispositivo Android. Cada dispositivo tem exatamente um adaptador (exceto Android Automotive com múltiplos chips Bluetooth, que usa BluetoothManager.getAdapterList()). BluetoothAdapter encapsula o estado do rádio: STATE_OFF (0), STATE_TURNING_ON (1), STATE_ON (2), STATE_TURNING_OFF (3). O estado é rastreado via BroadcastReceiver em ACTION_STATE_CHANGED.

Obter uma instância do BluetoothAdapter é o primeiro passo de qualquer aplicação BLE no Android. O método recomendado é via BluetoothManager.getAdapter() a partir da API 18+. A alternativa é o método estático BluetoothAdapter.getDefaultAdapter(), que funciona desde a API 5 mas é menos flexível. Ambos os métodos retornam null se o dispositivo não tiver módulo Bluetooth (tablets somente Wi-Fi, emulador). A verificação de null é obrigatória: a aplicação deve encerrar corretamente ou desativar as funcionalidades BLE.

kotlin
// Obter BluetoothAdapter (recomendado)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context

class BluetoothHelper(context: Context) {

    private val bluetoothAdapter: BluetoothAdapter?

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

        // Método 2: via método estático (API 5+)
        // val adapter = BluetoothAdapter.getDefaultAdapter()

        // Verificação de null
        if (bluetoothAdapter == null) {
            // Dispositivo não suporta Bluetooth
        }
    }

    // Verificar estado do Bluetooth
    fun isBluetoothEnabled(): Boolean {
        return bluetoothAdapter?.isEnabled == true
    }

    // Obter informações do adaptador
    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")
        )
    }
}

A classe BluetoothHelper demonstra como obter BluetoothAdapter via BluetoothManager com uma verificação de null posterior. isBluetoothEnabled verifica isEnabled — uma condição obrigatória antes de qualquer operação BLE. getAdapterInfo retorna o nome do dispositivo, endereço MAC, estado e modo de visibilidade. Importante: no Android 10+ (API 29+), o serviço do sistema retorna um endereço MAC fictício (02:00:00:00:00:00) se a aplicação não tiver permissões BLUETOOTH_ADMIN e ACCESS_FINE_LOCATION.

Principais métodos do BluetoothAdapter: enable, disable, getState, getAddress

BluetoothAdapter fornece métodos para controlar o rádio Bluetooth. enable() e disable() ligam e desligam o Bluetooth. Ambos os métodos requerem a permissão BLUETOOTH_ADMIN e são executados de forma assíncrona: após chamar enable(), o sistema inicia o processo de ativação do rádio, e o estado é rastreado via BroadcastReceiver com a ação BluetoothAdapter.ACTION_STATE_CHANGED. No Android 10+, enable() e disable() exigem privilégio adicional do sistema — aplicações comuns não podem controlar o Bluetooth programaticamente sem um diálogo do usuário.

getState() retorna o estado atual do adaptador: STATE_OFF (10), STATE_TURNING_ON (11), STATE_ON (12), STATE_TURNING_OFF (13). getAddress() retorna o endereço MAC do adaptador Bluetooth. No Android 6+, é necessário ACCESS_FINE_LOCATION (ou ACCESS_COARSE_LOCATION para API 31+) para solicitar o endereço MAC. No Android 10+, getAddress() retorna o endereço constante 02:00:00:00:00:00 — o endereço real não está disponível através da API pública.

getScanMode() determina o modo de visibilidade do adaptador: SCAN_MODE_NONE (invisível), SCAN_MODE_CONNECTABLE (visível para dispositivos conectados), SCAN_MODE_CONNECTABLE_DISCOVERABLE (visível para todos). O modo de visibilidade é limitado no tempo (geralmente 60–300 segundos) por segurança. Definir o modo via setScanMode() requer BLUETOOTH_ADMIN e permissão do sistema no Android 10+.

MétodoDescriçãoPermissão necessária
enable()Ligar rádio BluetoothBLUETOOTH_ADMIN
disable()Desligar rádio BluetoothBLUETOOTH_ADMIN
getState()Estado atual do adaptadorBLUETOOTH
getAddress()Endereço MAC do adaptadorBLUETOOTH + ACCESS_FINE_LOCATION (API 23+)
getScanMode()Modo de visibilidade do dispositivoBLUETOOTH
setScanMode()Definir modo de visibilidadeBLUETOOTH_ADMIN

Varredura de dispositivos: startDiscovery e BluetoothLeScanner

BluetoothAdapter suporta dois tipos de varredura. A varredura Bluetooth clássica (BR/EDR) é iniciada via startDiscovery() — descobre dispositivos Bluetooth de todos os tipos, incluindo telefones e fones de ouvido. Os resultados são retornados via BroadcastReceiver com a ação BluetoothDevice.ACTION_FOUND. startDiscovery() funciona por 12 segundos e pode ser cancelado chamando cancelDiscovery(). Este método está obsoleto para BLE — use BluetoothLeScanner.

A varredura BLE via BluetoothAdapter utiliza o método obsoleto startLeScan(LeScanCallback). A partir da API 21, o Google recomenda usar BluetoothLeScanner, obtido via BluetoothAdapter.getBluetoothLeScanner(). BluetoothLeScanner fornece uma API mais flexível: configuração de varredura via ScanSettings (modo, tipo de callback, modo de correspondência), filtragem via ScanFilter (por UUID de serviço, nome do dispositivo, endereço MAC) e suporte a PendingIntent para varredura em segundo plano.

kotlin
// API de varredura BLE antiga (obsoleta) vs nova
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*

class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {

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

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

        // Configurações de varredura
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
            .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
            .build()

        // Filtrar por serviço (UUID de frequência cardíaca)
        val filters = listOf(
            ScanFilter.Builder()
                .setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
                .build()
        )

        // Iniciar varredura
        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")
            }
        })
    }
}

A classe BLEScanner compara o obsoleto startLeScan com o moderno BluetoothLeScanner. No legacyScan, o LeScanCallback recebe BluetoothDevice, RSSI e scanRecord bruto. No modernScan, são usados ScanSettings com modo LOW_LATENCY (máxima velocidade de descoberta) e ScanFilter para filtrar pelo UUID do serviço de frequência cardíaca (0x180D). ScanCallback fornece onScanResult com um objeto ScanResult contendo informações estendidas: nome, RSSI, dados de publicidade, tipo de conexão.

BluetoothManager: API moderna para acessar BluetoothAdapter

BluetoothManager é um serviço de sistema Android, introduzido na API 18 (Android 4.3), para gerenciar operações Bluetooth. Antes da API 18, a única forma de obter BluetoothAdapter era o método estático getDefaultAdapter(). BluetoothManager fornece: adapter — uma instância de BluetoothAdapter, getConnectedDevices() — uma lista de dispositivos conectados, getDevicesMatchingConnectionStates() — filtragem por estado. BluetoothManager também é usado para obter BluetoothLeScanner em APIs antigas.

Vantagens do BluetoothManager sobre chamar diretamente BluetoothAdapter.getDefaultAdapter(): a aplicação não depende de um singleton estático, o gerenciador respeita o contexto (Activity/Application), o que é importante para cenários de múltiplas contas no Android Enterprise. No Android Automotive com vários chips Bluetooth, BluetoothManager.getAdapterList() retorna todos os adaptadores disponíveis — BluetoothAdapter.getDefaultAdapter() retorna apenas o primeiro.

kotlin
// Usar BluetoothManager para BLE
class BLEConnection(context: Context) {

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

    private val adapter: BluetoothAdapter? = bluetoothManager.adapter

    // Obter lista de dispositivos BLE conectados
    fun getConnectedDevices(): List<BluetoothDevice> {
        return bluetoothManager.getConnectedDevices(
            BluetoothProfile.GATT
        )
    }

    // Filtrar dispositivos por estado
    fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
        return bluetoothManager.getDevicesMatchingConnectionStates(
            BluetoothProfile.GATT, states
        )
    }

    // Verificar suporte BLE no dispositivo
    fun isBLESupported(): Boolean {
        return adapter != null && context.packageManager
            .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
    }

    // Solicitar ativação de Bluetooth via diálogo do sistema
    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
    }
}

A classe BLEConnection usa BluetoothManager para acessar BluetoothAdapter e obter a lista de dispositivos GATT conectados. isBLESupported verifica a presença de rádio BLE via PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) — uma verificação importante para dispositivos com Bluetooth Classic sem BLE. requestEnableBluetooth mostra o diálogo do sistema para ativar Bluetooth (ACTION_REQUEST_ENABLE), sem exigir permissão BLUETOOTH_ADMIN — esta é a única forma legal de ativar Bluetooth no Android 10+ sem uma aplicação de sistema.

Permissões do Android para trabalhar com BluetoothAdapter

As permissões para BluetoothAdapter evoluíram com cada versão do Android. No Android 6–11 (API 23–30), BLUETOOTH, BLUETOOTH_ADMIN e ACCESS_FINE_LOCATION são obrigatórias para varredura BLE. No Android 12+ (API 31+), o Google dividiu as permissões: ACCESS_FINE_LOCATION é substituída por BLUETOOTH_SCAN (varredura), BLUETOOTH_CONNECT (conexão), BLUETOOTH_ADVERTISE (publicidade). Para descoberta de dispositivos BLE, BLUETOOTH_SCAN é suficiente, localização não é necessária.

Tabela de permissões por versão do Android:

OperaçãoAPI 23–30API 31+
Varredura BLEACCESS_FINE_LOCATIONBLUETOOTH_SCAN (sem localização)
Conexão BLEACCESS_FINE_LOCATIONBLUETOOTH_CONNECT
Publicidade BLEACCESS_FINE_LOCATIONBLUETOOTH_ADVERTISE
Ativar/desativarBLUETOOTH_ADMINBLUETOOTH_ADMIN (sistema)
Obter endereço MACACCESS_FINE_LOCATIONBLUETOOTH_CONNECT (endereço fictício)

No Android 12+, todas as permissões Bluetooth são permissões de tempo de execução — devem ser solicitadas em tempo de execução via ActivityResultContracts.RequestMultiplePermissions. BLUETOOTH_SCAN e BLUETOOTH_ADVERTISE pertencem ao grupo NEARBY_DEVICES, BLUETOOTH_CONNECT pertence ao mesmo grupo. As permissões BLUETOOTH e BLUETOOTH_ADMIN permanecem no manifesto para compatibilidade com API < 31, mas para API 31+ são ignoradas — o Google exige especificar explicitamente as novas permissões.

kotlin
// Solicitar permissões Bluetooth no 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
            )
        }
    }

    // Verificar todas as permissões
    fun hasPermissions(context: Context): Boolean {
        return getRequiredPermissions().all { permission ->
            ContextCompat.checkSelfPermission(context, permission)
                    == PackageManager.PERMISSION_GRANTED
        }
    }
}

A classe PermissionHelper retorna o conjunto correto de permissões dependendo do nível da API. No Android 12+, são usados BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE sem localização. No Android 6–11, ACCESS_FINE_LOCATION ainda é necessário para varredura BLE. O desenvolvedor deve considerar ambos os cenários ao solicitar permissões via ActivityResultContracts ou RxPermissions.

Exemplo completo de BluetoothAdapter em Kotlin

Exemplo completo de uma aplicação BLE em Kotlin usando BluetoothAdapter para escanear, conectar e ler dados de um dispositivo BLE. O exemplo cobre a verificação de permissões, obtenção do adaptador, varredura via BluetoothLeScanner e conexão via BluetoothDevice.connectGatt.

kotlin
// Gerenciador BLE completo em 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. Descoberta de serviços
    fun canScan(): Boolean {
        return adapter?.isEnabled == true
                && scanner != null
                && PermissionHelper(context).hasPermissions(context)
    }

    // 2. com filtro
    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. Parar varredura
    fun stopScanning() {
        scanner?.stopScan(object : ScanCallback() {})
    }

    // 4. Conectar ao dispositivo 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) {
                    // Serviços encontrados, pode ler características
                }
            },
            BluetoothDevice.TRANSPORT_LE
        )
    }

    // 5. Liberar recursos
    fun disconnect() {
        gatt?.disconnect()
        gatt?.close()
        gatt = null
    }
}

A classe BLEManager unifica o ciclo BLE completo no Android: verificação do adaptador e permissões (canScan), varredura via BluetoothLeScanner com ScanSettings (startScanning), conexão via BluetoothDevice.connectGatt com TRANSPORT_LE (connectToDevice) e liberação de recursos (disconnect). Todas as operações BLE são executadas na thread da interface do usuário — o Android chama os callbacks BluetoothGattCallback na thread principal. Para tarefas BLE intensivas, recomenda-se transferir operações GATT para uma HandlerThread em segundo plano.

Perguntas frequentes

O que é BluetoothAdapter no Android?

BluetoothAdapter é uma classe que representa o adaptador Bluetooth local de um dispositivo Android. É obtida via BluetoothManager.getAdapter() (API 18+) ou BluetoothAdapter.getDefaultAdapter(). Fornece métodos para ativar/desativar Bluetooth, escanear dispositivos, gerenciar visibilidade e obter informações do adaptador. Retorna null em dispositivos sem módulo Bluetooth.

Por que BluetoothAdapter.getDefaultAdapter() retorna null?

A razão é a ausência de rádio Bluetooth no dispositivo. Típico em tablets somente Wi-Fi, emulador Android e Android TV sem Bluetooth. Verifique getDefaultAdapter() como null na inicialização da aplicação e desative funcionalidades BLE se o adaptador estiver ausente. Uma alternativa é verificar via PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) para detecção mais precisa.

Como o BluetoothLeScanner difere do startLeScan?

BluetoothLeScanner (API 21+) é a API moderna para varredura BLE com suporte a ScanFilter, ScanSettings e PendingIntent. startLeScan (API 18+) é um método obsoleto do BluetoothAdapter que aceita LeScanCallback com um conjunto de dados limitado. O Google recomenda BluetoothLeScanner para todos os novos projetos, permite filtrar por UUID, configurar o modo de consumo de energia e operar em segundo plano via PendingIntent.

Quais permissões são necessárias para BLE no Android 12+?

No Android 12+ (API 31), a varredura BLE requer BLUETOOTH_SCAN, a conexão requer BLUETOOTH_CONNECT e a publicidade requer BLUETOOTH_ADVERTISE. A permissão de localização ACCESS_FINE_LOCATION não é mais necessária para BLE. No Android 6–11, ACCESS_FINE_LOCATION é necessário. Todas as permissões são solicitadas em tempo de execução via ActivityResultContracts.

Pode-se ativar Bluetooth programaticamente sem diálogo?

No Android 10+, a ativação programática de Bluetooth sem diálogo do sistema está disponível apenas para aplicações de sistema com permissão BLUETOOTH_PRIVILEGED. Aplicações comuns devem usar Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) e startActivityForResult — o usuário confirma a ativação no diálogo do sistema. BLUETOOTH_ADMIN no manifesto não concede direitos enable() no Android 10+.

Resumo

  • BluetoothAdapter é o ponto de entrada para todas as operações Bluetooth no Android, obtido via BluetoothManager ou getDefaultAdapter()
  • getState() e isEnabled são verificações básicas do estado do rádio Bluetooth antes de qualquer operação BLE
  • BluetoothLeScanner (API 21+) substitui o obsoleto startLeScan com suporte a ScanFilter, ScanSettings e PendingIntent
  • BluetoothManager é a forma moderna de obter BluetoothAdapter com suporte a cenários de múltiplas contas e Automotive
  • As permissões evoluíram: ACCESS_FINE_LOCATION (API 23-30) → BLUETOOTH_SCAN/CONNECT/ADVERTISE (API 31+)
  • enable()/disable() — no Android 10+ apenas através do diálogo do sistema ACTION_REQUEST_ENABLE para aplicações comuns
  • connectGatt é um método BluetoothDevice para estabelecer conexão GATT com periféricos BLE via BluetoothGattCallback

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também