BluetoothAdapter — Android-systemklassen som representerar enhetens lokala Bluetooth-adapter. BluetoothAdapter är ingångspunkten för alla Bluetooth-operationer i Android: påslagning av radio (enable), skanning av enheter, hantering av synlighet (setScanMode), hämtning av information om adaptern (getName, getAddress, getState). Klassen är tillgänglig via BluetoothManager.getAdapter() (API 18+) eller BluetoothAdapter.getDefaultAdapter(). På enheter utan Bluetooth-modul returnerar getDefaultAdapter() null. Enligt Android Developers, 2026 är BluetoothAdapter en obligatorisk komponent för alla BLE-applikationer på Android, från och med API 5.
Huvudpunkter
BluetoothAdapter representerar den fysiska Bluetooth-adaptern för Android-enheten. Varje enhet har exakt en adapter (undantag — Android Automotive med flera Bluetooth-chips, där BluetoothManager.getAdapterList() används). BluetoothAdapter kapslar in radions status: STATE_OFF (0), STATE_TURNING_ON (1), STATE_ON (2), STATE_TURNING_OFF (3). Statusen spåras via BroadcastReceiver på ACTION_STATE_CHANGED.
Att hämta en BluetoothAdapter-instans är det första steget för varje BLE-applikation på Android. Den rekommenderade metoden — via BluetoothManager.getAdapter() från API 18+. Alternativ — den statiska metoden BluetoothAdapter.getDefaultAdapter(), som fungerar från API 5 men är mindre flexibel. Båda metoderna returnerar null om enheten inte har någon Bluetooth-modul (Wi-Fi-only surfplattor, emulator). Null-kontroll är obligatorisk: applikationen måste avslutas korrekt eller inaktivera BLE-funktioner.
// Hämta BluetoothAdapter (rekommenderas)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
class BluetoothHelper(context: Context) {
private val bluetoothAdapter: BluetoothAdapter?
init {
// Metod 1: via BluetoothManager (API 18+)
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
as BluetoothManager?
bluetoothAdapter = manager?.adapter
// Metod 2: via statisk metod (API 5+)
// val adapter = BluetoothAdapter.getDefaultAdapter()
// Null-kontroll
if (bluetoothAdapter == null) {
// Enheten stöder inte Bluetooth
}
}
// Kontrollera Bluetooth-status
fun isBluetoothEnabled(): Boolean {
return bluetoothAdapter?.isEnabled == true
}
// Hämta adapterinformation
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")
)
}
}
Klassen BluetoothHelper demonstrerar hämtning av BluetoothAdapter via BluetoothManager med efterföljande null-kontroll. isBluetoothEnabled kontrollerar isEnabled — obligatoriskt villkor före alla BLE-operationer. getAdapterInfo returnerar enhetens namn, MAC-adress, status och synlighetsläge. Viktigt: på Android 10+ (API 29+) returnerar systemtjänsten en falsk MAC-adress (02:00:00:00:00:00) om applikationen inte har behörigheten BLUETOOTH_ADMIN och ACCESS_FINE_LOCATION.
BluetoothAdapter tillhandahåller metoder för hantering av Bluetooth-radio. enable() och disable() slår på och stänger av Bluetooth. Båda metoderna kräver behörigheten BLUETOOTH_ADMIN och utförs asynkront: efter anrop av enable() startar systemet processen för påslagning av radio, statusen spåras via BroadcastReceiver med åtgärden BluetoothAdapter.ACTION_STATE_CHANGED. Från Android 10+ kräver enable() och disable() ytterligare systembehörighet — vanliga applikationer kan inte programmatiskt hantera Bluetooth utan användardialog.
getState() returnerar adapterns aktuella status: STATE_OFF (10), STATE_TURNING_ON (11), STATE_ON (12), STATE_TURNING_OFF (13). getAddress() returnerar Bluetooth-adapterns MAC-adress. På Android 6+ krävs ACCESS_FINE_LOCATION (eller ACCESS_COARSE_LOCATION för API 31+) för att begära MAC-adress. På Android 10+ returnerar getAddress() den konstanta adressen 02:00:00:00:00:00 — den verkliga adressen är inte tillgänglig via det offentliga API:et.
getScanMode() bestämmer adapterns synlighetsläge: SCAN_MODE_NONE (osynlig), SCAN_MODE_CONNECTABLE (synlig för anslutna), SCAN_MODE_CONNECTABLE_DISCOVERABLE (synlig för alla). Synlighetsläget är tidsbegränsat (vanligtvis 60–300 sekunder) av säkerhetsskäl. Inställning av läge via setScanMode() kräver BLUETOOTH_ADMIN och systembehörighet på Android 10+.
| Metod | Beskrivning | Krävd behörighet |
|---|---|---|
| enable() | Påslagning av Bluetooth-radio | BLUETOOTH_ADMIN |
| disable() | Avstängning av Bluetooth-radio | BLUETOOTH_ADMIN |
| getState() | Aktuell status för adaptern | BLUETOOTH |
| getAddress() | MAC-adress för adaptern | BLUETOOTH + ACCESS_FINE_LOCATION (API 23+) |
| getScanMode() | Synlighetsläge för enheten | BLUETOOTH |
| setScanMode() | Inställning av synlighetsläge | BLUETOOTH_ADMIN |
BluetoothAdapter stöder två typer av skanning. Klassisk Bluetooth-skanning (BR/EDR) startas via startDiscovery() — upptäcker Bluetooth-enheter av alla typer, inklusive telefoner och headsets. Resultaten returneras via BroadcastReceiver med åtgärden BluetoothDevice.ACTION_FOUND. startDiscovery() fungerar i 12 sekunder och kan avbrytas genom anrop av cancelDiscovery(). Denna metod är föråldrad för BLE — använd BluetoothLeScanner.
BLE-skanning via BluetoothAdapter utförs med den föråldrade metoden startLeScan(LeScanCallback). Från API 21 rekommenderar Google användning av BluetoothLeScanner, som erhålls via BluetoothAdapter.getBluetoothLeScanner(). BluetoothLeScanner tillhandahåller ett mer flexibelt API: skanningskonfiguration via ScanSettings (läge, callback type, match mode), filtrering via ScanFilter (efter tjänste-UUID, enhetsnamn, MAC-adress) och stöd för PendingIntent för bakgrundsskanning.
// Gammalt (föråldrat) vs nytt BLE-skannings-API
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*
class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {
// FÖRÅLDRAT: startLeScan (API 18+, API 21)
@Suppress("DEPRECATION")
fun legacyScan() {
bluetoothAdapter?.startLeScan { device, rssi, scanRecord ->
print("Found (LE Scan): $device.name, RSSI: $rssi")
}
}
// NYTT: BluetoothLeScanner (API 21+)
fun modernScan() {
val scanner = bluetoothAdapter?.bluetoothLeScanner
?: return
// Skanningsinställningar
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.build()
// Filtrera efter tjänst (Puls-UUID)
val filters = listOf(
ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
.build()
)
// Starta skanning
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")
}
})
}
}
Klassen BLEScanner jämför den föråldrade startLeScan och den moderna BluetoothLeScanner. I legacyScan tar callbacken LeScanCallback emot BluetoothDevice, RSSI och rå scanRecord. I modernScan används ScanSettings med läget LOW_LATENCY (maximal detektionshastighet) och ScanFilter för filtrering efter UUID för pulstjänsten (Heart Rate Service 0x180D). ScanCallback tillhandahåller onScanResult med ett ScanResult-objekt som innehåller utökad information: namn, RSSI, annonsdata, anslutningstyp.
BluetoothManager — systemtjänsten i Android, introducerad i API 18 (Android 4.3), för hantering av Bluetooth-operationer. Före API 18 var det enda sättet att få BluetoothAdapter den statiska metoden getDefaultAdapter(). BluetoothManager tillhandahåller: adapter — BluetoothAdapter-instansen, getConnectedDevices() — lista över anslutna enheter, getDevicesMatchingConnectionStates() — filtrering efter status. BluetoothManager används också för att hämta BluetoothLeScanner på äldre API:er.
Fördelar med BluetoothManager jämfört med direkt anrop av BluetoothAdapter.getDefaultAdapter(): applikationen är inte beroende av en statisk singleton, hanteraren tar hänsyn till kontexten (Activity/Application), vilket är viktigt för flerkontos-scenarier i Android Enterprise. På Android Automotive med flera Bluetooth-chips returnerar BluetoothManager.getAdapterList() alla tillgängliga adaptrar — BluetoothAdapter.getDefaultAdapter() returnerar bara den första.
// Använda BluetoothManager för BLE
class BLEConnection(context: Context) {
private val bluetoothManager: BluetoothManager =
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val adapter: BluetoothAdapter? = bluetoothManager.adapter
// Hämta lista över anslutna BLE-enheter
fun getConnectedDevices(): List<BluetoothDevice> {
return bluetoothManager.getConnectedDevices(
BluetoothProfile.GATT
)
}
// Filtrera enheter efter status
fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
return bluetoothManager.getDevicesMatchingConnectionStates(
BluetoothProfile.GATT, states
)
}
// Kontrollera BLE-stöd på enheten
fun isBLESupported(): Boolean {
return adapter != null && context.packageManager
.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
}
// Begär påslagning av Bluetooth via systemdialog
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
}
}
Klassen BLEConnection använder BluetoothManager för åtkomst till BluetoothAdapter och hämtning av lista över anslutna GATT-enheter. isBLESupported kontrollerar förekomsten av BLE-radio via PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) — viktig kontroll för enheter med Bluetooth Classic utan BLE. requestEnableBluetooth visar systemdialogen för påslagning av Bluetooth (ACTION_REQUEST_ENABLE), utan att kräva behörigheten BLUETOOTH_ADMIN — detta är det enda lagliga sättet att slå på Bluetooth på Android 10+ utan systemapplikation.
Behörigheter för BluetoothAdapter har utvecklats med varje Android-version. På Android 6–11 (API 23–30) är BLUETOOTH, BLUETOOTH_ADMIN och ACCESS_FINE_LOCATION obligatoriska för BLE-skanning. På Android 12+ (API 31+) har Google delat upp behörigheterna: ACCESS_FINE_LOCATION har ersatts av BLUETOOTH_SCAN (skanning), BLUETOOTH_CONNECT (anslutning), BLUETOOTH_ADVERTISE (annonsering). För att söka efter BLE-enheter räcker BLUETOOTH_SCAN, plats krävs inte.
Behörighetstabell efter Android-version:
| Operation | API 23–30 | API 31+ |
|---|---|---|
| BLE-skanning | ACCESS_FINE_LOCATION | BLUETOOTH_SCAN (utan plats) |
| Anslutning till BLE | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT |
| BLE-annonsering | ACCESS_FINE_LOCATION | BLUETOOTH_ADVERTISE |
| På/avslagning | BLUETOOTH_ADMIN | BLUETOOTH_ADMIN (system) |
| Hämtning av MAC-adress | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT (falsk adress) |
På Android 12+ är alla Bluetooth-behörigheter körningsbehörigheter — de måste begäras under körning via ActivityResultContracts.RequestMultiplePermissions. BLUETOOTH_SCAN och BLUETOOTH_ADVERTISE tillhör gruppen NEARBY_DEVICES, BLUETOOTH_CONNECT — samma grupp. Behörigheterna BLUETOOTH och BLUETOOTH_ADMIN finns kvar i manifestet för kompatibilitet med API < 31, men för API 31+ ignoreras de — Google kräver explicit angivelse av de nya behörigheterna.
// Begära Bluetooth-behörigheter på 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-skanning
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_ADVERTISE
)
} else {
// Android 6-11: BLE-skanning
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN
)
}
}
// Kontrollera alla behörigheter
fun hasPermissions(context: Context): Boolean {
return getRequiredPermissions().all { permission ->
ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED
}
}
}
Klassen PermissionHelper returnerar rätt uppsättning behörigheter beroende på API-nivå. På Android 12+ används BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE utan plats. På Android 6–11 krävs fortfarande ACCESS_FINE_LOCATION för BLE-skanning. Utvecklaren måste ta hänsyn till båda scenarierna vid begäran av behörigheter via ActivityResultContracts eller RxPermissions.
Fullständigt exempel på en BLE-applikation i Kotlin som använder BluetoothAdapter för skanning, anslutning och läsning av data från en BLE-enhet. Exemplet omfattar kontroll av behörigheter, hämtning av adaptern, skanning via BluetoothLeScanner och anslutning via BluetoothDevice.connectGatt.
// Fullständig BLE-hanterare i 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. Tjänsteupptäckt
fun canScan(): Boolean {
return adapter?.isEnabled == true
&& scanner != null
&& PermissionHelper(context).hasPermissions(context)
}
// 2. Skanning med filter
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. Stoppa skanning
fun stopScanning() {
scanner?.stopScan(object : ScanCallback() {})
}
// 4. Anslut till BLE-enhet
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) {
// Tjänster hittade, kan läsa egenskaper
}
},
BluetoothDevice.TRANSPORT_LE
)
}
// 5. Frigör resurser
fun disconnect() {
gatt?.disconnect()
gatt?.close()
gatt = null
}
}
Hanteraren BLEManager kombinerar den fullständiga BLE-cykeln på Android: kontroll av adapter och behörigheter (canScan), skanning via BluetoothLeScanner med ScanSettings (startScanning), anslutning via BluetoothDevice.connectGatt med TRANSPORT_LE (connectToDevice), frigöring av resurser (disconnect). Alla BLE-operationer utförs på UI-tråden — Android anropar BluetoothGattCallback-återanrop på huvudtråden. För produktiva BLE-uppgifter rekommenderas att flytta GATT-operationer till en bakgrunds-HandlerThread.
Vanliga frågor
BluetoothAdapter — klass som representerar den lokala Bluetooth-adaptern för Android-enheten. Erhålls via BluetoothManager.getAdapter() (API 18+) eller BluetoothAdapter.getDefaultAdapter(). Tillhandahåller metoder för på/avslagning av Bluetooth, skanning av enheter, hantering av synlighet och hämtning av information om adaptern. Returnerar null på enheter utan Bluetooth-modul.
Orsaken — avsaknad av Bluetooth-radio på enheten. Karakteristiskt för Wi-Fi-only surfplattor, Android-emulator och Android TV utan Bluetooth. Kontrollera getDefaultAdapter() för null vid start av applikationen och inaktivera BLE-funktioner om adaptern saknas. Alternativ — kontroll via PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) för mer exakt bestämning.
BluetoothLeScanner (API 21+) — modernt API för BLE-skanning med stöd för ScanFilter, ScanSettings och PendingIntent. startLeScan (API 18+) — föråldrad metod för BluetoothAdapter som accepterar LeScanCallback med begränsad datamängd. BluetoothLeScanner rekommenderas av Google för alla nya projekt, möjliggör filtrering efter UUID, konfigurering av energiförbrukningsläge och arbete i bakgrunden via PendingIntent.
På Android 12+ (API 31) krävs BLUETOOTH_SCAN för BLE-skanning, BLUETOOTH_CONNECT för anslutning, BLUETOOTH_ADVERTISE för annonsering. Platsbehörigheten ACCESS_FINE_LOCATION krävs inte längre för BLE. På Android 6–11 krävs ACCESS_FINE_LOCATION. Alla behörigheter begärs under körning via ActivityResultContracts.
Från Android 10+ är programmatisk påslagning av Bluetooth utan systemdialog endast tillgänglig för systemapplikationer med behörigheten BLUETOOTH_PRIVILEGED. Vanliga applikationer måste använda Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) och startActivityForResult — användaren bekräftar påslagningen i systemdialogen. BLUETOOTH_ADMIN i manifestet ger inte rätt till enable() på Android 10+.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också