BluetoothAdapter, bir cihazın yerel Bluetooth adaptörünü temsil eden bir sistem Android sınıfıdır. BluetoothAdapter, Android'deki tüm Bluetooth işlemleri için giriş noktasıdır: radyoyu etkinleştirme (enable), cihazları tarama, görünürlüğü yönetme (setScanMode), adaptör bilgilerini alma (getName, getAddress, getState). Sınıf, BluetoothManager.getAdapter() (API 18+) veya BluetoothAdapter.getDefaultAdapter() aracılığıyla kullanılabilir. Bluetooth modülü olmayan cihazlarda, getDefaultAdapter() null döndürür. Android Developers, 2026'ya göre BluetoothAdapter, API 5'ten başlayarak Android'deki herhangi bir BLE uygulaması için zorunlu bir bileşendir.
Ana Noktalar
BluetoothAdapter, bir Android cihazının fiziksel Bluetooth adaptörünü temsil eder. Her cihazın tam olarak bir adaptörü vardır (birden fazla Bluetooth çipine sahip Android Automotive hariç, BluetoothManager.getAdapterList() kullanır). BluetoothAdapter, radyo durumunu kapsüller: STATE_OFF (0), STATE_TURNING_ON (1), STATE_ON (2), STATE_TURNING_OFF (3). Durum, ACTION_STATE_CHANGED üzerindeki BroadcastReceiver aracılığıyla izlenir.
BluetoothAdapter örneği almak, Android'deki herhangi bir BLE uygulamasının ilk adımıdır. Önerilen yöntem, API 18+'dan itibaren BluetoothManager.getAdapter() aracılığıyladır. Alternatif, statik yöntem BluetoothAdapter.getDefaultAdapter()'dır, API 5'ten itibaren çalışır ancak daha az esnektir. Her iki yöntem de cihazda Bluetooth modülü yoksa (yalnızca Wi-Fi tabletler, emülatör) null döndürür. Null kontrolü zorunludur: uygulama düzgün bir şekilde sonlanmalı veya BLE özelliklerini devre dışı bırakmalıdır.
// BluetoothAdapter alma (önerilen)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
class BluetoothHelper(context: Context) {
private val bluetoothAdapter: BluetoothAdapter?
init {
// Yöntem 1: BluetoothManager aracılığıyla (API 18+)
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
as BluetoothManager?
bluetoothAdapter = manager?.adapter
// Yöntem 2: statik yöntem aracılığıyla (API 5+)
// val adapter = BluetoothAdapter.getDefaultAdapter()
// Null kontrolü
if (bluetoothAdapter == null) {
// Cihaz Bluetooth'u desteklemiyor
}
}
// Bluetooth durumunu kontrol et
fun isBluetoothEnabled(): Boolean {
return bluetoothAdapter?.isEnabled == true
}
// Adaptör bilgilerini al
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 sınıfı, BluetoothManager aracılığıyla BluetoothAdapter almayı ve ardından null kontrolü yapmayı gösterir. isBluetoothEnabled, isEnabled'i kontrol eder — herhangi bir BLE işleminden önce zorunlu bir koşuldur. getAdapterInfo, cihaz adını, MAC adresini, durumu ve görünürlük modunu döndürür. Önemli: Android 10+'da (API 29+), uygulamanın BLUETOOTH_ADMIN ve ACCESS_FINE_LOCATION izinleri yoksa sistem hizmeti sahte bir MAC adresi (02:00:00:00:00:00) döndürür.
BluetoothAdapter, Bluetooth radyosunu kontrol etmek için yöntemler sağlar. enable() ve disable(), Bluetooth'u açar ve kapatır. Her iki yöntem de BLUETOOTH_ADMIN izni gerektirir ve asenkron olarak yürütülür: enable() çağrıldıktan sonra, sistem radyoyu etkinleştirme sürecini başlatır ve durum, BluetoothAdapter.ACTION_STATE_CHANGED eylemiyle BroadcastReceiver aracılığıyla izlenir. Android 10+'da, enable() ve disable() ek sistem ayrıcalığı gerektirir — normal uygulamalar, kullanıcı diyaloğu olmadan programlı olarak Bluetooth'u kontrol edemez.
getState(), geçerli adaptör durumunu döndürür: STATE_OFF (10), STATE_TURNING_ON (11), STATE_ON (12), STATE_TURNING_OFF (13). getAddress(), Bluetooth adaptörünün MAC adresini döndürür. Android 6+'da, MAC adresini istemek için ACCESS_FINE_LOCATION (veya API 31+ için ACCESS_COARSE_LOCATION) gereklidir. Android 10+'da, getAddress() sabit adres 02:00:00:00:00:00'ı döndürür — gerçek adres genel API aracılığıyla kullanılamaz.
getScanMode(), adaptörün görünürlük modunu belirler: SCAN_MODE_NONE (görünmez), SCAN_MODE_CONNECTABLE (bağlı cihazlara görünür), SCAN_MODE_CONNECTABLE_DISCOVERABLE (herkese görünür). Görünürlük modu, güvenlik için zamanla sınırlıdır (genellikle 60–300 saniye). setScanMode() aracılığıyla modu ayarlamak, Android 10+'da BLUETOOTH_ADMIN ve sistem izni gerektirir.
| Yöntem | Açıklama | Gerekli İzin |
|---|---|---|
| enable() | Bluetooth radyosunu açma | BLUETOOTH_ADMIN |
| disable() | Bluetooth radyosunu kapama | BLUETOOTH_ADMIN |
| getState() | Geçerli adaptör durumu | BLUETOOTH |
| getAddress() | Adaptör MAC adresi | BLUETOOTH + ACCESS_FINE_LOCATION (API 23+) |
| getScanMode() | Cihaz görünürlük modu | BLUETOOTH |
| setScanMode() | Görünürlük modunu ayarlama | BLUETOOTH_ADMIN |
BluetoothAdapter iki tür taramayı destekler. Klasik Bluetooth taraması (BR/EDR), startDiscovery() aracılığıyla başlatılır — telefonlar ve kulaklıklar dahil her tür Bluetooth cihazını keşfeder. Sonuçlar, BluetoothDevice.ACTION_FOUND eylemiyle BroadcastReceiver aracılığıyla döndürülür. startDiscovery() 12 saniye çalışır ve cancelDiscovery() çağrılarak iptal edilebilir. Bu yöntem BLE için kullanımdan kaldırılmıştır — BluetoothLeScanner kullanın.
BluetoothAdapter aracılığıyla BLE taraması, kullanımdan kaldırılan startLeScan(LeScanCallback) yöntemini kullanır. API 21'den itibaren Google, BluetoothAdapter.getBluetoothLeScanner() aracılığıyla elde edilen BluetoothLeScanner'ın kullanılmasını önerir. BluetoothLeScanner daha esnek bir API sağlar: ScanSettings aracılığıyla tarama yapılandırması (mod, geri arama türü, eşleşme modu), ScanFilter aracılığıyla filtreleme (hizmet UUID'sine, cihaz adına, MAC adresine göre) ve arka plan taraması için PendingIntent desteği.
// Eski (kullanımdan kaldırılmış) ve yeni BLE tarama API'si
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*
class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {
// KULLANIMDAN KALDIRILDI: startLeScan (API 18+, API 21)
@Suppress("DEPRECATION")
fun legacyScan() {
bluetoothAdapter?.startLeScan { device, rssi, scanRecord ->
print("Found (LE Scan): $device.name, RSSI: $rssi")
}
}
// YENİ: BluetoothLeScanner (API 21+)
fun modernScan() {
val scanner = bluetoothAdapter?.bluetoothLeScanner
?: return
// Tarama ayarları
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.build()
// Hizmete göre filtrele (Kalp Atış Hızı UUID)
val filters = listOf(
ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
.build()
)
// Taramayı başlat
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 sınıfı, kullanımdan kaldırılan startLeScan ile modern BluetoothLeScanner'ı karşılaştırır. legacyScan'de, LeScanCallback BluetoothDevice, RSSI ve ham scanRecord alır. modernScan'de, LOW_LATENCY modu (maksimum keşif hızı) ile ScanSettings ve kalp atış hızı hizmeti UUID'sine (0x180D) göre filtrelemek için ScanFilter kullanılır. ScanCallback, genişletilmiş bilgi içeren bir ScanResult nesnesi sağlar: ad, RSSI, reklam verileri, bağlantı türü.
BluetoothManager, Bluetooth işlemlerini yönetmek için API 18'de (Android 4.3) tanıtılan bir sistem Android hizmetidir. API 18'den önce, BluetoothAdapter almanın tek yolu statik yöntem getDefaultAdapter() idi. BluetoothManager şunları sağlar: adapter — bir BluetoothAdapter örneği, getConnectedDevices() — bağlı cihazların listesi, getDevicesMatchingConnectionStates() — duruma göre filtreleme. BluetoothManager, eski API'lerde BluetoothLeScanner almak için de kullanılır.
BluetoothManager'ın avantajları doğrudan BluetoothAdapter.getDefaultAdapter() çağırmaya kıyasla: uygulama statik bir singleton'a bağlı değildir, yönetici bağlamı (Activity/Application) dikkate alır, bu Android Enterprise çoklu hesap senaryoları için önemlidir. Birden fazla Bluetooth çipine sahip Android Automotive'de, BluetoothManager.getAdapterList() mevcut tüm adaptörleri döndürür — BluetoothAdapter.getDefaultAdapter() yalnızca ilkini döndürür.
// BLE için BluetoothManager kullanma
class BLEConnection(context: Context) {
private val bluetoothManager: BluetoothManager =
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val adapter: BluetoothAdapter? = bluetoothManager.adapter
// Bağlı BLE cihazları listesini al
fun getConnectedDevices(): List<BluetoothDevice> {
return bluetoothManager.getConnectedDevices(
BluetoothProfile.GATT
)
}
// Cihazları duruma göre filtrele
fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
return bluetoothManager.getDevicesMatchingConnectionStates(
BluetoothProfile.GATT, states
)
}
// Cihazda BLE desteğini kontrol et
fun isBLESupported(): Boolean {
return adapter != null && context.packageManager
.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
}
// Sistem diyaloğu aracılığıyla Bluetooth etkinleştirme iste
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 sınıfı, BluetoothAdapter'a erişmek ve bağlı GATT cihazlarının listesini almak için BluetoothManager'ı kullanır. isBLESupported, PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) aracılığıyla BLE radyosunun varlığını kontrol eder — BLE'siz Bluetooth Classic cihazları için önemli bir kontroldür. requestEnableBluetooth, BLUETOOTH_ADMIN izni gerektirmeden Bluetooth'u etkinleştirmek için sistem diyaloğunu (ACTION_REQUEST_ENABLE) gösterir — bu, sistem uygulaması olmadan Android 10+'da Bluetooth'u etkinleştirmenin tek yasal yoludur.
İzinler BluetoothAdapter için her Android sürümüyle birlikte gelişmiştir. Android 6–11'de (API 23–30), BLE taraması için BLUETOOTH, BLUETOOTH_ADMIN ve ACCESS_FINE_LOCATION zorunludur. Android 12+'da (API 31+), Google izinleri bölmüştür: ACCESS_FINE_LOCATION, BLUETOOTH_SCAN (tarama), BLUETOOTH_CONNECT (bağlantı), BLUETOOTH_ADVERTISE (reklam) ile değiştirilmiştir. BLE cihazlarını keşfetmek için BLUETOOTH_SCAN yeterlidir, konum gerekli değildir.
İzin tablosu Android sürümüne göre:
| İşlem | API 23–30 | API 31+ |
|---|---|---|
| BLE tarama | ACCESS_FINE_LOCATION | BLUETOOTH_SCAN (konumsuz) |
| BLE bağlantı | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT |
| BLE reklam | ACCESS_FINE_LOCATION | BLUETOOTH_ADVERTISE |
| Açma/kapama | BLUETOOTH_ADMIN | BLUETOOTH_ADMIN (sistem) |
| MAC adresi alma | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT (sahte adres) |
Android 12+'da, tüm Bluetooth izinleri çalışma zamanı izinleridir — ActivityResultContracts.RequestMultiplePermissions aracılığıyla çalışma zamanında istenmelidir. BLUETOOTH_SCAN ve BLUETOOTH_ADVERTISE, NEARBY_DEVICES grubuna aittir, BLUETOOTH_CONNECT aynı gruba aittir. BLUETOOTH ve BLUETOOTH_ADMIN izinleri, API < 31 ile uyumluluk için manifestte kalır, ancak API 31+ için yok sayılır — Google, yeni izinlerin açıkça belirtilmesini gerektirir.
// Android 12+'da Bluetooth izinleri iste
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
)
}
}
// Tüm izinleri kontrol et
fun hasPermissions(context: Context): Boolean {
return getRequiredPermissions().all { permission ->
ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED
}
}
}
PermissionHelper sınıfı, API düzeyine bağlı olarak doğru izin kümesini döndürür. Android 12+'da, konumsuz BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE kullanılır. Android 6–11'de, BLE taraması için hala ACCESS_FINE_LOCATION gereklidir. Geliştirici, ActivityResultContracts veya RxPermissions aracılığıyla izin isterken her iki senaryoyu da dikkate almalıdır.
Tam örnek, BluetoothAdapter kullanarak BLE cihazlarını taramak, bağlanmak ve veri okumak için Kotlin'de bir BLE uygulamasıdır. Örnek, izin kontrolü, adaptör alma, BluetoothLeScanner aracılığıyla tarama ve BluetoothDevice.connectGatt aracılığıyla bağlanmayı kapsar.
// Kotlin'de tam BLE yöneticisi
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. Hizmet keşfi
fun canScan(): Boolean {
return adapter?.isEnabled == true
&& scanner != null
&& PermissionHelper(context).hasPermissions(context)
}
// 2. filtreli
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. Taramayı durdur
fun stopScanning() {
scanner?.stopScan(object : ScanCallback() {})
}
// 4. BLE cihazına bağlan
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) {
// Hizmetler bulundu, özellikler okunabilir
}
},
BluetoothDevice.TRANSPORT_LE
)
}
// 5. Kaynakları serbest bırak
fun disconnect() {
gatt?.disconnect()
gatt?.close()
gatt = null
}
}
BLEManager sınıfı, Android'de tam BLE döngüsünü birleştirir: adaptör ve izin kontrolü (canScan), ScanSettings ile BluetoothLeScanner aracılığıyla tarama (startScanning), TRANSPORT_LE ile BluetoothDevice.connectGatt aracılığıyla bağlanma (connectToDevice) ve kaynakları serbest bırakma (disconnect). Tüm BLE işlemleri UI iş parçacığında yürütülür — Android, BluetoothGattCallback geri çağırmalarını ana iş parçacığında çağırır. Performans açısından kritik BLE görevleri için GATT işlemlerinin bir arka plan HandlerThread'ine taşınması önerilir.
Sıkça Sorulan Sorular
BluetoothAdapter, bir Android cihazının yerel Bluetooth adaptörünü temsil eden bir sınıftır. BluetoothManager.getAdapter() (API 18+) veya BluetoothAdapter.getDefaultAdapter() aracılığıyla alınır. Bluetooth'u açma/kapama, cihazları tarama, görünürlüğü yönetme ve adaptör bilgilerini alma yöntemleri sağlar. Bluetooth modülü olmayan cihazlarda null döndürür.
Sebep, cihazda Bluetooth radyosunun olmamasıdır. Yalnızca Wi-Fi tabletler, Android emülatörü ve Bluetooth'suz Android TV için tipiktir. Uygulama başlangıcında getDefaultAdapter()'ı null için kontrol edin ve adaptör yoksa BLE özelliklerini devre dışı bırakın. Daha hassas tespit için PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) aracılığıyla kontrol bir alternatiftir.
BluetoothLeScanner (API 21+), ScanFilter, ScanSettings ve PendingIntent desteği ile BLE taraması için modern API'dir. startLeScan (API 18+), sınırlı bir veri kümesiyle LeScanCallback kabul eden kullanımdan kaldırılmış bir BluetoothAdapter yöntemidir. Google, tüm yeni projeler için BluetoothLeScanner'ı önerir, UUID'ye göre filtrelemeye, güç tüketimi modunu yapılandırmaya ve PendingIntent aracılığıyla arka planda çalışmaya olanak tanır.
Android 12+'da (API 31), BLE taraması BLUETOOTH_SCAN, bağlantı BLUETOOTH_CONNECT ve reklam BLUETOOTH_ADVERTISE gerektirir. Konum izni ACCESS_FINE_LOCATION artık BLE için gerekli değildir. Android 6–11'de ACCESS_FINE_LOCATION gereklidir. Tüm izinler ActivityResultContracts aracılığıyla çalışma zamanında istenir.
Android 10+'da, sistem diyaloğu olmadan programlı Bluetooth etkinleştirme yalnızca BLUETOOTH_PRIVILEGED iznine sahip sistem uygulamaları için kullanılabilir. Normal uygulamalar Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) ve startActivityForResult kullanmalıdır — kullanıcı sistem diyaloğunda etkinleştirmeyi onaylar. Manifestteki BLUETOOTH_ADMIN, Android 10+'da enable() hakları vermez.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun