BluetoothAdapter — ang system class ng Android na kumakatawan sa lokal na Bluetooth adapter ng device. Ang BluetoothAdapter ay entry point para sa lahat ng Bluetooth operations sa Android: pag-on ng radio (enable), pag-scan ng mga device, pamamahala ng visibility (setScanMode), pagkuha ng impormasyon tungkol sa adapter (getName, getAddress, getState). Ang class ay available sa pamamagitan ng BluetoothManager.getAdapter() (API 18+) o BluetoothAdapter.getDefaultAdapter(). Sa mga device na walang Bluetooth module, ang getDefaultAdapter() ay nagbabalik ng null. Ayon sa Android Developers, 2026, ang BluetoothAdapter ay mandatoryong component para sa anumang BLE application sa Android, simula sa API 5.
Mga pangunahing punto
BluetoothAdapter ay kumakatawan sa pisikal na Bluetooth adapter ng Android device. Bawat device ay may eksaktong isang adapter (exception — Android Automotive na may maraming Bluetooth chips, kung saan ginagamit ang BluetoothManager.getAdapterList()). Ine-encapsulate ng BluetoothAdapter ang estado ng radio: STATE_OFF (0), STATE_TURNING_ON (1), STATE_ON (2), STATE_TURNING_OFF (3). Ang estado ay sinusubaybayan sa pamamagitan ng BroadcastReceiver sa ACTION_STATE_CHANGED.
Ang pagkuha ng instance ng BluetoothAdapter ay unang hakbang ng anumang BLE application sa Android. Ang inirerekomendang pamamaraan — sa pamamagitan ng BluetoothManager.getAdapter() mula API 18+. Alternatibo — static na pamamaraan na BluetoothAdapter.getDefaultAdapter(), na gumagana mula API 5 ngunit hindi gaanong flexible. Parehong pamamaraan ay nagbabalik ng null kung ang device ay walang Bluetooth module (Wi-Fi-only tablets, emulator). Ang pagsusuri ng null ay sapilitan: ang application ay dapat na maayos na magtapos o hindi paganahin ang mga BLE function.
// Pagkuha ng BluetoothAdapter (inirerekomenda)
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothManager
import android.content.Context
class BluetoothHelper(context: Context) {
private val bluetoothAdapter: BluetoothAdapter?
init {
// Paraan 1: sa pamamagitan ng BluetoothManager (API 18+)
val manager = context.getSystemService(Context.BLUETOOTH_SERVICE)
as BluetoothManager?
bluetoothAdapter = manager?.adapter
// Paraan 2: sa pamamagitan ng static na pamamaraan (API 5+)
// val adapter = BluetoothAdapter.getDefaultAdapter()
// Pagsusuri ng null
if (bluetoothAdapter == null) {
// Hindi sinusuportahan ng device ang Bluetooth
}
}
// Suriin ang estado ng Bluetooth
fun isBluetoothEnabled(): Boolean {
return bluetoothAdapter?.isEnabled == true
}
// Kunin ang impormasyon ng adapter
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")
)
}
}
Ang class na BluetoothHelper ay nagpapakita ng pagkuha ng BluetoothAdapter sa pamamagitan ng BluetoothManager na may kasunod na pagsusuri ng null. Sinusuri ng isBluetoothEnabled ang isEnabled — sapilitang kondisyon bago ang anumang BLE operations. Ang getAdapterInfo ay nagbabalik ng pangalan ng device, MAC address, estado at visibility mode. Mahalaga: sa Android 10+ (API 29+) ang system service ay nagbabalik ng pekeng MAC address (02:00:00:00:00:00) kung ang application ay walang pahintulot na BLUETOOTH_ADMIN at ACCESS_FINE_LOCATION.
BluetoothAdapter ay nagbibigay ng mga pamamaraan ng pamamahala ng Bluetooth radio. Ang enable() at disable() ay nag-o-on at nag-o-off ng Bluetooth. Parehong pamamaraan ay nangangailangan ng pahintulot na BLUETOOTH_ADMIN at isinasagawa nang asynchronous: pagkatapos ng tawag sa enable(), sinisimulan ng system ang proseso ng pag-on ng radio, ang estado ay sinusubaybayan sa pamamagitan ng BroadcastReceiver na may action na BluetoothAdapter.ACTION_STATE_CHANGED. Mula Android 10+, ang enable() at disable() ay nangangailangan ng karagdagang sistema ng pahintulot — ang mga ordinaryong application ay hindi maaaring programang pamahalaan ang Bluetooth nang walang dialog ng user.
getState() ay nagbabalik ng kasalukuyang estado ng adapter: STATE_OFF (10), STATE_TURNING_ON (11), STATE_ON (12), STATE_TURNING_OFF (13). getAddress() ay nagbabalik ng MAC address ng Bluetooth adapter. Sa Android 6+, para sa paghingi ng MAC address ay kinakailangan ang ACCESS_FINE_LOCATION (o ACCESS_COARSE_LOCATION para sa API 31+). Sa Android 10+, ang getAddress() ay nagbabalik ng constant address na 02:00:00:00:00:00 — ang tunay na address ay hindi available sa pamamagitan ng pampublikong API.
getScanMode() ay tumutukoy sa visibility mode ng adapter: SCAN_MODE_NONE (hindi nakikita), SCAN_MODE_CONNECTABLE (nakikita para sa mga naka-konekta), SCAN_MODE_CONNECTABLE_DISCOVERABLE (nakikita para sa lahat). Ang visibility mode ay limitado sa oras (karaniwang 60–300 segundo) para sa seguridad. Ang pagtatakda ng mode sa pamamagitan ng setScanMode() ay nangangailangan ng BLUETOOTH_ADMIN at system permission sa Android 10+.
| Pamamaraan | Paglalarawan | Kinakailangang pahintulot |
|---|---|---|
| enable() | Pag-on ng Bluetooth radio | BLUETOOTH_ADMIN |
| disable() | Pag-off ng Bluetooth radio | BLUETOOTH_ADMIN |
| getState() | Kasalukuyang estado ng adapter | BLUETOOTH |
| getAddress() | MAC address ng adapter | BLUETOOTH + ACCESS_FINE_LOCATION (API 23+) |
| getScanMode() | Visibility mode ng device | BLUETOOTH |
| setScanMode() | Pagtatakda ng visibility mode | BLUETOOTH_ADMIN |
BluetoothAdapter ay sumusuporta sa dalawang uri ng pag-scan. Ang classic na Bluetooth scanning (BR/EDR) ay sinisimulan sa pamamagitan ng startDiscovery() — natutukoy ang mga Bluetooth device ng lahat ng uri, kabilang ang mga telepono at headset. Ang mga resulta ay ibinabalik sa pamamagitan ng BroadcastReceiver na may action na BluetoothDevice.ACTION_FOUND. Ang startDiscovery() ay gumagana ng 12 segundo at maaaring kanselahin sa pamamagitan ng pagtawag sa cancelDiscovery(). Ang pamamaraang ito ay hindi na ginagamit para sa BLE — gamitin ang BluetoothLeScanner.
Ang BLE scanning sa pamamagitan ng BluetoothAdapter ay isinasagawa gamit ang hindi na ginagamit na pamamaraang startLeScan(LeScanCallback). Simula API 21, inirerekomenda ng Google ang paggamit ng BluetoothLeScanner, na nakuha sa pamamagitan ng BluetoothAdapter.getBluetoothLeScanner(). Ang BluetoothLeScanner ay nagbibigay ng mas flexible na API: configuration ng pag-scan sa pamamagitan ng ScanSettings (mode, callback type, match mode), pag-filter sa pamamagitan ng ScanFilter (ayon sa UUID ng serbisyo, pangalan ng device, MAC address) at suporta para sa PendingIntent para sa background scanning.
// Luma (hindi na ginagamit) vs bagong BLE scanning API
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.*
class BLEScanner(private val bluetoothAdapter: BluetoothAdapter?) {
// HINDI NA GINAGAMIT: startLeScan (API 18+, API 21)
@Suppress("DEPRECATION")
fun legacyScan() {
bluetoothAdapter?.startLeScan { device, rssi, scanRecord ->
print("Found (LE Scan): $device.name, RSSI: $rssi")
}
}
// BAGO: BluetoothLeScanner (API 21+)
fun modernScan() {
val scanner = bluetoothAdapter?.bluetoothLeScanner
?: return
// Mga setting ng pag-scan
val settings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.build()
// Filter ayon sa serbisyo (UUID ng tibok ng puso)
val filters = listOf(
ScanFilter.Builder()
.setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805F9B34FB"))
.build()
)
// Simulan ang pag-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")
}
})
}
}
Ang class na BLEScanner ay nagkukumpara ng hindi na ginagamit na startLeScan at modernong BluetoothLeScanner. Sa legacyScan, ang callback na LeScanCallback ay tumatanggap ng BluetoothDevice, RSSI at raw scanRecord. Sa modernScan, ginagamit ang ScanSettings na may mode na LOW_LATENCY (maximum detection speed) at ScanFilter para sa pag-filter ayon sa UUID ng serbisyo ng tibok ng puso (Heart Rate Service 0x180D). Ang ScanCallback ay nagbibigay ng onScanResult na may ScanResult object na naglalaman ng malawak na impormasyon: pangalan, RSSI, data ng advertisement, uri ng koneksyon.
BluetoothManager — system service ng Android, ipinakilala sa API 18 (Android 4.3), para sa pamamahala ng Bluetooth operations. Bago ang API 18, ang tanging paraan upang makuha ang BluetoothAdapter ay ang static na pamamaraang getDefaultAdapter(). Ang BluetoothManager ay nagbibigay ng: adapter — instance ng BluetoothAdapter, getConnectedDevices() — listahan ng mga naka-konektang device, getDevicesMatchingConnectionStates() — pag-filter ayon sa estado. Ang BluetoothManager ay ginagamit din para makuha ang BluetoothLeScanner sa mga lumang API.
Mga bentahe ng BluetoothManager kumpara sa direktang pagtawag sa BluetoothAdapter.getDefaultAdapter(): ang application ay hindi nakadepende sa static na singleton, isinasaalang-alang ng manager ang konteksto (Activity/Application), na mahalaga para sa multi-account na scenario ng Android Enterprise. Sa Android Automotive na may maraming Bluetooth chips, ang BluetoothManager.getAdapterList() ay nagbabalik ng lahat ng available na adapter — ang BluetoothAdapter.getDefaultAdapter() ay nagbabalik lamang ng una.
// Paggamit ng BluetoothManager para sa BLE
class BLEConnection(context: Context) {
private val bluetoothManager: BluetoothManager =
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val adapter: BluetoothAdapter? = bluetoothManager.adapter
// Kunin ang listahan ng mga naka-konektang BLE device
fun getConnectedDevices(): List<BluetoothDevice> {
return bluetoothManager.getConnectedDevices(
BluetoothProfile.GATT
)
}
// I-filter ang mga device ayon sa estado
fun getDevicesByState(states: IntArray): List<BluetoothDevice> {
return bluetoothManager.getDevicesMatchingConnectionStates(
BluetoothProfile.GATT, states
)
}
// Suriin ang suporta ng BLE sa device
fun isBLESupported(): Boolean {
return adapter != null && context.packageManager
.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)
}
// Hilingin ang pag-on ng Bluetooth sa pamamagitan ng system dialog
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
}
}
Ang class na BLEConnection ay gumagamit ng BluetoothManager para sa pag-access sa BluetoothAdapter at pagkuha ng listahan ng mga naka-konektang GATT device. Sinusuri ng isBLESupported ang pagkakaroon ng BLE radio sa pamamagitan ng PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) — mahalagang pagsusuri para sa mga device na may Bluetooth Classic na walang BLE. Ang requestEnableBluetooth ay nagpapakita ng system dialog para sa pag-on ng Bluetooth (ACTION_REQUEST_ENABLE), nang hindi nangangailangan ng pahintulot na BLUETOOTH_ADMIN — ito ang tanging legal na paraan ng pag-on ng Bluetooth sa Android 10+ nang walang system application.
Mga pahintulot para sa BluetoothAdapter ay nag-evolve sa bawat bersyon ng Android. Sa Android 6–11 (API 23–30) para sa BLE scanning, ang BLUETOOTH, BLUETOOTH_ADMIN at ACCESS_FINE_LOCATION ay sapilitan. Sa Android 12+ (API 31+) hinati ng Google ang mga pahintulot: ang ACCESS_FINE_LOCATION ay pinalitan ng BLUETOOTH_SCAN (pag-scan), BLUETOOTH_CONNECT (koneksyon), BLUETOOTH_ADVERTISE (advertisement). Para sa paghahanap ng BLE device, sapat na ang BLUETOOTH_SCAN, hindi kinakailangan ang lokasyon.
Talahanayan ng mga pahintulot ayon sa bersyon ng Android:
| Operasyon | API 23–30 | API 31+ |
|---|---|---|
| BLE scanning | ACCESS_FINE_LOCATION | BLUETOOTH_SCAN (walang lokasyon) |
| Koneksyon sa BLE | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT |
| BLE advertisement | ACCESS_FINE_LOCATION | BLUETOOTH_ADVERTISE |
| Pag-on/off | BLUETOOTH_ADMIN | BLUETOOTH_ADMIN (system) |
| Pagkuha ng MAC address | ACCESS_FINE_LOCATION | BLUETOOTH_CONNECT (pekeng address) |
Sa Android 12+, lahat ng Bluetooth pahintulot ay runtime pahintulot — dapat hilingin sa runtime sa pamamagitan ng ActivityResultContracts.RequestMultiplePermissions. Ang BLUETOOTH_SCAN at BLUETOOTH_ADVERTISE ay kabilang sa grupong NEARBY_DEVICES, ang BLUETOOTH_CONNECT — sa parehong grupo. Ang mga pahintulot na BLUETOOTH at BLUETOOTH_ADMIN ay nananatili sa manifest para sa compatibility sa API < 31, ngunit para sa API 31+ sila ay hindi pinapansin — hinihingi ng Google ang malinaw na pagbanggit ng mga bagong pahintulot.
// Paghiling ng mga pahintulot ng Bluetooth sa 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 scanning
arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.BLUETOOTH_ADVERTISE
)
} else {
// Android 6-11: BLE scanning
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN
)
}
}
// Suriin ang lahat ng pahintulot
fun hasPermissions(context: Context): Boolean {
return getRequiredPermissions().all { permission ->
ContextCompat.checkSelfPermission(context, permission)
== PackageManager.PERMISSION_GRANTED
}
}
}
Ang class na PermissionHelper ay nagbabalik ng tamang set ng mga pahintulot depende sa API level. Sa Android 12+, ginagamit ang BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE nang walang lokasyon. Sa Android 6–11 para sa BLE scanning ay kinakailangan pa rin ang ACCESS_FINE_LOCATION. Dapat isaalang-alang ng developer ang parehong scenario kapag humihingi ng mga pahintulot sa pamamagitan ng ActivityResultContracts o RxPermissions.
Kumpletong halimbawa ng BLE application sa Kotlin na gumagamit ng BluetoothAdapter para sa pag-scan, pagkonekta at pagbasa ng data ng BLE device. Ang halimbawa ay sumasaklaw sa pagsusuri ng mga pahintulot, pagkuha ng adapter, pag-scan sa pamamagitan ng BluetoothLeScanner at koneksyon sa pamamagitan ng BluetoothDevice.connectGatt.
// Kumpletong BLE manager sa 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. Pagtuklas ng serbisyo
fun canScan(): Boolean {
return adapter?.isEnabled == true
&& scanner != null
&& PermissionHelper(context).hasPermissions(context)
}
// 2. Pag-scan na may 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. Itigil ang pag-scan
fun stopScanning() {
scanner?.stopScan(object : ScanCallback() {})
}
// 4. Kumonekta sa BLE device
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) {
// Natagpuan ang mga serbisyo, maaaring basahin ang mga katangian
}
},
BluetoothDevice.TRANSPORT_LE
)
}
// 5. Palayain ang mga resources
fun disconnect() {
gatt?.disconnect()
gatt?.close()
gatt = null
}
}
Ang manager na BLEManager ay pinagsasama ang kumpletong BLE cycle sa Android: pagsusuri ng adapter at mga pahintulot (canScan), pag-scan sa pamamagitan ng BluetoothLeScanner na may ScanSettings (startScanning), koneksyon sa pamamagitan ng BluetoothDevice.connectGatt na may TRANSPORT_LE (connectToDevice), pagpapalaya ng mga resources (disconnect). Lahat ng BLE operations ay isinasagawa sa UI thread — tinatawag ng Android ang mga callback ng BluetoothGattCallback sa pangunahing thread. Para sa produktibong BLE tasks, inirerekomenda na ilipat ang GATT operations sa background HandlerThread.
Mga madalas itanong
BluetoothAdapter — class na kumakatawan sa lokal na Bluetooth adapter ng Android device. Nakukuha sa pamamagitan ng BluetoothManager.getAdapter() (API 18+) o BluetoothAdapter.getDefaultAdapter(). Nagbibigay ng mga pamamaraan ng pag-on/off ng Bluetooth, pag-scan ng mga device, pamamahala ng visibility at pagkuha ng impormasyon tungkol sa adapter. Nagbabalik ng null sa mga device na walang Bluetooth module.
Ang dahilan — kawalan ng Bluetooth radio sa device. Karaniwan para sa Wi-Fi-only tablets, Android emulator at Android TV na walang Bluetooth. Suriin ang getDefaultAdapter() para sa null sa pagsisimula ng application at huwag paganahin ang BLE functions kung wala ang adapter. Alternatibo — pagsusuri sa pamamagitan ng PackageManager.hasSystemFeature(FEATURE_BLUETOOTH_LE) para sa mas tumpak na pagtukoy.
BluetoothLeScanner (API 21+) — modernong API para sa BLE scanning na may suporta para sa ScanFilter, ScanSettings at PendingIntent. startLeScan (API 18+) — hindi na ginagamit na pamamaraan ng BluetoothAdapter na tumatanggap ng LeScanCallback na may limitadong set ng data. Ang BluetoothLeScanner ay inirerekomenda ng Google para sa lahat ng bagong proyekto, pinapayagan ang pag-filter ayon sa UUID, pag-configure ng mode ng pagkonsumo ng enerhiya at pagtatrabaho sa background sa pamamagitan ng PendingIntent.
Sa Android 12+ (API 31) para sa BLE scanning ay kinakailangan ang BLUETOOTH_SCAN, para sa koneksyon — BLUETOOTH_CONNECT, para sa advertisement — BLUETOOTH_ADVERTISE. Ang pahintulot sa lokasyon na ACCESS_FINE_LOCATION ay hindi na kinakailangan para sa BLE. Sa Android 6–11 kinakailangan ang ACCESS_FINE_LOCATION. Lahat ng pahintulot ay hinihingi sa runtime sa pamamagitan ng ActivityResultContracts.
Mula Android 10+, ang programmatic na pag-on ng Bluetooth nang walang system dialog ay available lamang sa mga system application na may pahintulot na BLUETOOTH_PRIVILEGED. Ang mga ordinaryong application ay dapat gumamit ng Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) at startActivityForResult — kinukumpirma ng user ang pag-on sa system dialog. Ang BLUETOOTH_ADMIN sa manifest ay hindi nagbibigay ng karapatan sa enable() sa Android 10+.
Konklusyon
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din