[Android][Compose] Bluetooth Scan 하기

2023. 6. 22. 16:44·Android/Bluetooth
반응형

안드로이드에서 제공하는 BluetoothLeScanner를 사용해서 Bluetooth 주변기기를 Scan 하는 방법을 정리했다.


권한 처리하기

Bluetooth Scan을 하기에 앞서 블루투스와 위치 정보에 대한 권한을 처리해줘야 한다.

 

Manifiest에 아래와 같이 블루투스와 위치 정보에 대한 권한을 추가한다.

    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

 

MainActivity에서는 권한을 체크하는 코드를 작성한다. permissionArray에 누락된 권한이 있을 경우 Scan이 정상적으로 되지 않을 수 있다.

class MainActivity : ComponentActivity() {
    private val permissionArray = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        arrayOf(
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    } else {
        arrayOf(
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION
        )
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // ...

        if(Build.VERSION.SDK_INT >= 31){
            if(permissionArray.all{ ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED}){
                Toast.makeText(this, "권한 확인", Toast.LENGTH_SHORT).show()
            }
            else{
                requestPermissionLauncher.launch(permissionArray)
            }
        }
    }

    private val requestPermissionLauncher = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        permissions.entries.forEach {
            Log.d("DEBUG", "${it.key} = ${it.value}")
        }
    }
}

주변기기 Scan 하기

안드로이드에서 Bluetooth를 다루기 위해서는 BluetoothManager가 필요하다. BluetoothManager는 안드로이드 시스템 서비스 중 하나로 Bluetooth와의 상호 작용을 관리하는 클래스이다.

 

BluetoothManager로부터 BluetoothAdapter 인스턴스를 얻을 수 있는데, 이것으로 주변기기를 Scan 하거나 앱과 기기가 상호작용을 하게 한다.  BluetoothAdapter의 BluetoothLeScanner를 사용해서 Ble Scan을 해보자.

val context = LocalContext.current
val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
val bluetoothAdapter = bluetoothManager.adapter
val bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner

val scanSettings = ScanSettings.Builder()
	.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
	.build()

bluetoothLeScanner.startScan(null, scanSettings, scanCallback)

 

BluetoothLeScanner의 '~Scan' 메서드를 사용할 때 ScanCallback을 전달하여 Scan 결과 이벤트를 처리해야 한다.

val scanCallback: ScanCallback = object : ScanCallback() {
    override fun onScanResult(callbackType: Int, result: ScanResult) {
        Log.d("onScanResult", result.toString())
        if(result.device.name != null) {
            var uuid = "null"

            if(result.scanRecord?.serviceUuids != null) {
                uuid = result.scanRecord!!.serviceUuids.toString()
            }

            val scanItem = DeviceData(
                result.device.name?: "null",
                uuid,
                result.device.address?: "null"
            )
            if(!scanList.contains(scanItem)) {
                scanList.add(scanItem)
            }
        }
    }

    override fun onScanFailed(errorCode: Int) {
        println("onScanFailed  $errorCode")
    }
}

 

Scan을 멈추고 싶다면 BluetoothLeScanner의 stopScan 메서드에 startScan의 ScanCallback을 전달하면 된다.

bluetoothLeScanner.stopScan(scanCallback)

ScanFilter 사용하기

BluetoothLeScanner의 startScan 메서드를 보면 ScanFilter 값이 있다. ScanFilter는 특정 기준을 가진 기기만 Scan을 할 수 있게 한다. 기기의 Name이나 Address 등을 필터링할 수 있다.

ScanFilter scanFilter = new ScanFilter.Builder()
        .setDeviceName("DeviceName")
        .setDeviceAddress("DeviceAddress")
        .setServiceUuid(ParcelUuid(serviceUuid))
        .setManufacturerData(manufacturerId, manufacturerData, manufacturerDataMask)
        .setServiceData(serviceUuid, serviceData)
        .build();

 

 

 

전체 코드

 

Android_Study/Ble Sample at master · OhGyong/Android_Study

안드로이드 개발 공부. Contribute to OhGyong/Android_Study development by creating an account on GitHub.

github.com

 

반응형

'Android > Bluetooth' 카테고리의 다른 글

[Android][Compose] Bluetooth Connect 하기  (0) 2023.07.10
'Android/Bluetooth' 카테고리의 다른 글
  • [Android][Compose] Bluetooth Connect 하기
O_Gyong
O_Gyong
안드로이드 기술 정리
  • O_Gyong
    O_Gyong's TECH
    O_Gyong
    • 분류 전체보기 (79)
      • Android (56)
        • ADB (4)
        • AddView (1)
        • Architecture (1)
        • Bluetooth (2)
        • BuildConfig (1)
        • Calendar (3)
        • Camera (2)
        • Cipher (1)
        • Compose (1)
        • ConstraintSet (1)
        • DataStore (1)
        • Dialog (1)
        • DrawerLayout (1)
        • Flow (1)
        • Glide (1)
        • MQTT (2)
        • Paging3 (4)
        • Permission (1)
        • SharedPreferences (3)
        • RecyclerView (5)
        • Room (1)
        • Splash (1)
        • TabLayout (2)
        • TextWatcher (1)
        • Update (1)
        • 이슈 처리 (13)
      • Android Studio (5)
      • Firebase (1)
      • Git (3)
      • 작업 일지 (13)
  • 최근 글

  • 인기 글

  • 태그

    TabLayout
    Andoird
    CameraX
    Bluetooth
    paging
    firebase
    BLE
    github
    SharedPreferences
    Android Studio
    hilt
    Navigation
    ADB
    in-app update
    Paging3
    loading
    GIT
    MQTT
    Room
    recyclerview
    Android
    kizitonwose
    CalendarView
    해상도
    Kotlin
    issue
    flow
    webview
    compose
    Pagination
  • 링크

    • GitHub
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • hELLO· Designed By정상우.v4.10.4
O_Gyong
[Android][Compose] Bluetooth Scan 하기
상단으로

티스토리툴바