BluetoothAdapter — Android-ning tizim klassi bo'lib, qurilmaning mahalliy Bluetooth adapterini ifodalaydi. BluetoothAdapter Android-da barcha Bluetooth operatsiyalari uchun kirish nuqtasidir: radioni yoqish (enable), qurilmalarni skanerlash, ko'rinishni boshqarish (setScanMode), adapter haqida ma'lumot olish (getName, getAddress, getState). Klass BluetoothManager.getAdapter() (API 18+) yoki BluetoothAdapter.getDefaultAdapter() orqali mavjud. Bluetooth moduli bo'lmagan qurilmalarda getDefaultAdapter() null qaytaradi. Android Developers, 2026 ma'lumotiga ko'ra, BluetoothAdapter API 5 dan boshlab Android-dagi har qanday BLE ilovasi uchun majburiy komponent hisoblanadi.
Asosiy fikrlar
BluetoothAdapter Android qurilmasining jismoniy Bluetooth adapterini ifodalaydi. Har bir qurilma aynan bitta adapterga ega (istisno — bir nechta Bluetooth chipiga ega Android Automotive, bunda BluetoothManager.getAdapterList() ishlatiladi). BluetoothAdapter radioning holatini inkapsulatsiya qiladi: STATE_OFF (0), STATE_TURNING_ON (1), STATE_ON (2), STATE_TURNING_OFF (3). Holat ACTION_STATE_CHANGED bo'yicha BroadcastReceiver orqali kuzatiladi.
BluetoothAdapter namunasini olish Android-dagi har qanday BLE ilovasining birinchi qadamidir. Tavsiya etilgan metod — API 18+ dan BluetoothManager.getAdapter() orqali. Muqobil — API 5 dan ishlaydigan, ammo kamroq moslashuvchan BluetoothAdapter.getDefaultAdapter() statik metodi. Ikkala metod ham qurilmada Bluetooth moduli bo'lmasa null qaytaradi (Wi-Fi-only planshetlar, emulyator). Null tekshiruvi majburiydir: ilova to'g'ri ishini tugatishi yoki BLE funksiyalarini o'chirishi kerak.
// BluetoothAdapter ni olish (tavsiya etiladi)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
class BluetoothHelper(context: Context) {
private val bluetoothAdapter: BluetoothAdapter?
init {
// Metod 1: BluetoothManager orqali (API 18+)
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
as BluetoothManager?
bluetoothAdapter = manager?.adapter
// Metod 2: statik metod orqali (API 5+)
// val adapter = BluetoothAdapter.getDefaultAdapter()
// Null tekshiruvi
if (bluetoothAdapter == null) {
// Qurilma Bluetooth-ni qo'llab-quvvatlamaydi
}
}
// Bluetooth holatini tekshiring
fun isBluetoothEnabled(): Boolean {
return bluetoothAdapter?.isEnabled == true
}
// Adapter haqida ma'lumot oling
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")
)
}
}
BluetoothHelper klassi BluetoothManager orqali BluetoothAdapter olishni va keyingi null tekshiruvini namoyish etadi. isBluetoothEnabled isEnabled ni tekshiradi — har qanday BLE operatsiyasidan oldin majburiy shart. getAdapterInfo qurilma nomini, MAC manzilini, holatini va ko'rinish rejimini qaytaradi. Muhim: Android 10+ da (API 29+) tizim xizmati, agar ilovada BLUETOOTH_ADMIN va ACCESS_FINE_LOCATION ruxsati bo'lmasa, soxta MAC manzilini (02:00:00:00:00:00) qaytaradi.
BluetoothAdapter Bluetooth radiosini boshqarish metodlarini taqdim etadi. enable() va disable() Bluetooth-ni yoqadi va o'chiradi. Ikkala metod BLUETOOTH_ADMIN ruxsatini talab qiladi va asinxron bajariladi: enable() chaqirilgandan so'ng tizim radioni yoqish jarayonini boshlaydi, holat BluetoothAdapter.ACTION_STATE_CHANGED aksiyasi bilan BroadcastReceiver orqali kuzatiladi. Android 10+ dan boshlab enable() va disable() qo'shimcha tizim ruxsatini talab qiladi — oddiy ilovalar foydalanuvchi dialogisiz Bluetooth-ni dasturiy boshqara olmaydi.
getState() adapterning joriy holatini qaytaradi: STATE_OFF (10), STATE_TURNING_ON (11), STATE_ON (12), STATE_TURNING_OFF (13). getAddress() Bluetooth adapterining MAC manzilini qaytaradi. Android 6+ da MAC manzilini so'rash uchun ACCESS_FINE_LOCATION (yoki API 31+ uchun ACCESS_COARSE_LOCATION) talab qilinadi. Android 10+ da getAddress() doimiy 02:00:00:00:00:00 manzilini qaytaradi — haqiqiy manzil umumiy API orqali mavjud emas.
getScanMode() adapterning ko'rinish rejimini aniqlaydi: SCAN_MODE_NONE (ko'rinmas), SCAN_MODE_CONNECTABLE (ulanganlar uchun ko'rinadigan), SCAN_MODE_CONNECTABLE_DISCOVERABLE (hamma uchun ko'rinadigan). Ko'rinish rejimi xavfsizlik uchun vaqt bilan cheklangan (odatda 60–300 soniya). Rejimni setScanMode() orqali o'rnatish BLUETOOTH_ADMIN va Android 10+ da tizim ruxsatini talab qiladi.
| Metod | Tavsif | Talab qilinadigan ruxsat |
|---|---|---|
| enable() | Bluetooth radiosini yoqish | BLUETOOTH_ADMIN |
| disable() | Bluetooth radiosini o'chirish | BLUETOOTH_ADMIN |
| getState() | Adapterning joriy holati | BLUETOOTH |
| getAddress() | Adapterning MAC manzili | BLUETOOTH + ACCESS_FINE_LOCATION (API 23+) |
| getScanMode() | Qurilmaning ko'rinish rejimi | BLUETOOTH |
| setScanMode() | Ko'rinish rejimini o'rnatish | BLUETOOTH_ADMIN |
BluetoothAdapter ikki turdagi skanerlashni qo'llab-quvvatlaydi. Klassik Bluetooth skanerlash (BR/EDR) startDiscovery() orqali ishga tushiriladi — telefonlar va naushniklar hamda barcha turdagi Bluetooth qurilmalarini aniqlaydi. Natijalar BluetoothDevice.ACTION_FOUND aksiyasi bilan BroadcastReceiver orqali qaytariladi. startDiscovery() 12 soniya ishlaydi va cancelDiscovery() chaqiruvi bilan bekor qilinishi mumkin. Bu metod BLE uchun eskirgan — BluetoothLeScanner-dan foydalaning.
BluetoothAdapter orqali BLE skanerlash eskirgan startLeScan(LeScanCallback) metodi bilan amalga oshiriladi. API 21 dan boshlab Google BluetoothAdapter.getBluetoothLeScanner() orqali olinadigan BluetoothLeScanner-dan foydalanishni tavsiya etadi. BluetoothLeScanner yanada moslashuvchan API taqdim etadi: ScanSettings orqali skanerlash sozlamalari (rejim, callback type, match mode), ScanFilter orqali filtrlash (xizmat UUID-si, qurilma nomi, MAC manzili bo'yicha) va fon skanerlashi uchun PendingIntent qo'llab-quvvatlashi.
// Eskirgan va yangi BLE skanerlash API si
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*
class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {
// ESKIRGAN: startLeScan (API 18+, API 21)
@Suppress("DEPRECATION")
fun legacyScan() {
bluetoothAdapter?.startLeScan { device, rssi, scanRecord ->
print("Found (LE Scan): $device.name, RSSI: $rssi")
}
}
// YANGI: BluetoothLeScanner (API 21+)
fun modernScan() {
val scanner = bluetoothAdapter?.bluetoothLeScanner
?: return
// Skanerlash sozlamalari
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.build()
// Xizmat bo'yicha filtrlash (Yurak urishi UUID)
val filters = listOf(
ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
.build()
)
// Skanerlashni boshlash
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")
}
})
}
}
BLEScanner klassi eskirgan startLeScan va zamonaviy BluetoothLeScanner-ni solishtiradi. legacyScan da LeScanCallback BluetoothDevice, RSSI va xom scanRecord oladi. modernScan da LOW_LATENCY rejimi (maksimal aniqlash tezligi) bilan ScanSettings va yurak urishi xizmati UUID-si (Heart Rate Service 0x180D) bo'yicha filtrlash uchun ScanFilter ishlatiladi. ScanCallback kengaytirilgan ma'lumotlarga ega ScanResult obyekti bilan onScanResult ni taqdim etadi: nom, RSSI, reklama ma'lumotlari, ulanish turi.
BluetoothManager — Bluetooth operatsiyalarini boshqarish uchun API 18 da (Android 4.3) joriy etilgan Android tizim xizmati. API 18 gacha BluetoothAdapter olishning yagona usuli getDefaultAdapter() statik metodi edi. BluetoothManager taqdim etadi: adapter — BluetoothAdapter namunasi, getConnectedDevices() — ulangan qurilmalar ro'yxati, getDevicesMatchingConnectionStates() — holat bo'yicha filtrlash. BluetoothManager shuningdek eski API-larda BluetoothLeScanner olish uchun ishlatiladi.
BluetoothManager ning afzalliklari to'g'ridan-to'g'ri BluetoothAdapter.getDefaultAdapter() chaqiruviga nisbatan: ilova statik singletonga bog'liq emas, menejer kontekstni (Activity/Application) hisobga oladi, bu Android Enterprise ko'p hisobli stsenariylari uchun muhimdir. Bir nechta Bluetooth chipiga ega Android Automotive da BluetoothManager.getAdapterList() barcha mavjud adapterlarni qaytaradi — BluetoothAdapter.getDefaultAdapter() faqat birinchisini qaytaradi.
// BLE uchun BluetoothManager dan foydalanish
class BLEConnection(context: Context) {
private val bluetoothManager: BluetoothManager =
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val adapter: BluetoothAdapter? = bluetoothManager.adapter
// Ulangan BLE qurilmalari ro'yxatini oling
fun getConnectedDevices(): List<BluetoothDevice> {
return bluetoothManager.getConnectedDevices(
BluetoothProfile.GATT
)
}
// Qurilmalarni holat bo'yicha filtrlash
fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
return bluetoothManager.getDevicesMatchingConnectionStates(
BluetoothProfile.GATT, states
)
}
// Qurilmada BLE qo'llab-quvvatlashini tekshiring
fun isBLESupported(): Boolean {
return adapter != null && context.packageManager
.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
}
// Tizim dialogi orqali Bluetooth yoqishni so'rang
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
}
}
BLEConnection klassi BluetoothAdapter-ga kirish va ulangan GATT qurilmalari ro'yxatini olish uchun BluetoothManager-dan foydalanadi. isBLESupported BLE radiosining mavjudligini PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) orqali tekshiradi — BLE siz Bluetooth Classic ga ega qurilmalar uchun muhim tekshiruv. requestEnableBluetooth tizim ruxsatisiz Bluetooth-ni yoqish uchun tizim dialogini ko'rsatadi (ACTION_REQUEST_ENABLE) — bu Android 10+ da tizim ilovasisiz Bluetooth-ni yoqishning yagona qonuniy usuli.
Ruxsatlar BluetoothAdapter uchun Android-ning har bir versiyasi bilan rivojlangan. Android 6–11 da (API 23–30) BLE skanerlash uchun BLUETOOTH, BLUETOOTH_ADMIN va ACCESS_FINE_LOCATION majburiydir. Android 12+ da (API 31+) Google ruxsatlarni ajratdi: ACCESS_FINE_LOCATION BLUETOOTH_SCAN (skanerlash), BLUETOOTH_CONNECT (ulanish), BLUETOOTH_ADVERTISE (reklama) bilan almashtirildi. BLE qurilmalarini qidirish uchun BLUETOOTH_SCAN yetarli, joylashuv talab qilinmaydi.
Ruxsatlar jadvali Android versiyalari bo'yicha:
| Operatsiya | API 23–30 | API 31+ |
|---|---|---|
| BLE skanerlash | ACCESS_FINE_LOCATION | BLUETOOTH_SCAN (joylashuvsiz) |
| BLE ga ulanish | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT |
| BLE reklamasi | ACCESS_FINE_LOCATION | BLUETOOTH_ADVERTISE |
| Yoqish/o'chirish | BLUETOOTH_ADMIN | BLUETOOTH_ADMIN (tizim) |
| MAC manzilini olish | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT (soxta manzil) |
Android 12+ da barcha Bluetooth ruxsatlari ish vaqti ruxsatlaridir — ular ActivityResultContracts.RequestMultiplePermissions orqali ish vaqtida so'ralishi kerak. BLUETOOTH_SCAN va BLUETOOTH_ADVERTISE NEARBY_DEVICES guruhiga, BLUETOOTH_CONNECT — xuddi shu guruhga tegishli. BLUETOOTH va BLUETOOTH_ADMIN ruxsatlari API < 31 bilan moslik uchun manifestda qoladi, lekin API 31+ uchun ular e'tiborga olinmaydi — Google yangi ruxsatlarni aniq ko'rsatishni talab qiladi.
// Android 12+ da Bluetooth ruxsatlarini so'rash
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 skanerlash
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_ADVERTISE
)
} else {
// Android 6-11: BLE skanerlash
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN
)
}
}
// Barcha ruxsatlarni tekshiring
fun hasPermissions(context: Context): Boolean {
return getRequiredPermissions().all { permission ->
ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED
}
}
}
PermissionHelper klassi API darajasiga qarab to'g'ri ruxsatlar to'plamini qaytaradi. Android 12+ da joylashuvsiz BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE ishlatiladi. Android 6–11 da BLE skanerlash uchun hali ham ACCESS_FINE_LOCATION talab qilinadi. Dasturchi ActivityResultContracts yoki RxPermissions orqali ruxsat so'rashda ikkala stsenariyni hisobga olishi kerak.
To'liq namuna — BLE qurilmasini skanerlash, ulanish va ma'lumotlarni o'qish uchun BluetoothAdapter dan foydalanadigan Kotlin-dagi BLE ilovasi. Namuna ruxsatlarni tekshirish, adapterni olish, BluetoothLeScanner orqali skanerlash va BluetoothDevice.connectGatt orqali ulanishni o'z ichiga oladi.
// Kotlin-da to'liq BLE menejeri
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. Xizmatlarni aniqlash
fun canScan(): Boolean {
return adapter?.isEnabled == true
&& scanner != null
&& PermissionHelper(context).hasPermissions(context)
}
// 2. Filtr bilan skanerlash
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. Skanerlashni to'xtatish
fun stopScanning() {
scanner?.stopScan(object : ScanCallback() {})
}
// 4. BLE qurilmasiga ulanish
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) {
// Xizmatlar topildi, xarakteristikalarni o'qish mumkin
}
},
BluetoothDevice.TRANSPORT_LE
)
}
// 5. Resurslarni bo'shatish
fun disconnect() {
gatt?.disconnect()
gatt?.close()
gatt = null
}
}
BLEManager menejeri Android-da to'liq BLE siklini birlashtiradi: adapter va ruxsatlarni tekshirish (canScan), ScanSettings bilan BluetoothLeScanner orqali skanerlash (startScanning), TRANSPORT_LE bilan BluetoothDevice.connectGatt orqali ulanish (connectToDevice), resurslarni bo'shatish (disconnect). Barcha BLE operatsiyalari UI oqimida bajariladi — Android BluetoothGattCallback callbacklarini asosiy oqimda chaqiradi. Samarador BLE vazifalari uchun GATT operatsiyalarini fon HandlerThread-ga o'tkazish tavsiya etiladi.
Tez-tez beriladigan savollar
BluetoothAdapter — Android qurilmasining mahalliy Bluetooth adapterini ifodalovchi klass. BluetoothManager.getAdapter() (API 18+) yoki BluetoothAdapter.getDefaultAdapter() orqali olinadi. Bluetooth-ni yoqish/o'chirish, qurilmalarni skanerlash, ko'rinishni boshqarish va adapter haqida ma'lumot olish metodlarini taqdim etadi. Bluetooth moduli bo'lmagan qurilmalarda null qaytaradi.
Sabab — qurilmada Bluetooth radiosining yo'qligi. Wi-Fi-only planshetlar, Android emulyatori va Bluetooth siz Android TV uchun xos. Ilova ishga tushganda getDefaultAdapter() ni null uchun tekshiring va adapter bo'lmasa BLE funksiyalarini o'chiring. Muqobil — aniqroq aniqlash uchun PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) orqali tekshirish.
BluetoothLeScanner (API 21+) — ScanFilter, ScanSettings va PendingIntent qo'llab-quvvatlashi bilan BLE skanerlash uchun zamonaviy API. startLeScan (API 18+) — cheklangan ma'lumotlar to'plami bilan LeScanCallback qabul qiluvchi eskirgan BluetoothAdapter metodi. BluetoothLeScanner Google tomonidan barcha yangi loyihalar uchun tavsiya etiladi, UUID bo'yicha filtrlash, energiya iste'moli rejimini sozlash va PendingIntent orqali fonda ishlash imkonini beradi.
Android 12+ da (API 31) BLE skanerlash uchun BLUETOOTH_SCAN, ulanish uchun — BLUETOOTH_CONNECT, reklama uchun — BLUETOOTH_ADVERTISE talab qilinadi. ACCESS_FINE_LOCATION joylashuv ruxsati endi BLE uchun talab qilinmaydi. Android 6–11 da ACCESS_FINE_LOCATION kerak. Barcha ruxsatlar ActivityResultContracts orqali ish vaqtida so'raladi.
Android 10+ dan boshlab tizim dialogisiz Bluetooth-ni dasturiy yoqish faqat BLUETOOTH_PRIVILEGED ruxsatiga ega tizim ilovalari uchun mumkin. Oddiy ilovalar Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) va startActivityForResult dan foydalanishi kerak — foydalanuvchi tizim dialogida yoqishni tasdiqlaydi. Manifestdagi BLUETOOTH_ADMIN Android 10+ da enable() huquqini bermaydi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.