[Android 8.0(Oreo)]PendingIntent에서 BLE 스캔 결과 받기
머리
Android 8.0(Oreo)에서 BLE 스캔을 위한 새로운 메소드가 추가되었습니다.
Nougat까지는 콜백으로 스캔 결과를 받는 스타일이었지만, 추가된 메소드에서는 PendingIntent로 결과를 받을 수 있게 됩니다.
바로 움직여 어떤 느낌인지 느낌을 잡아 보았습니다.
환경
Android 7.1.2(Nougat)까지의 BLE 스캔
Nougat까지 스캔 결과는 콜백으로받는 스타일이었습니다.
이것이 앱의 프로세스가 살아있는 동안에만받을 수 있기 때문에,
BLE의 스캔을 상시 계속하는 타입의 앱에서는, 조금 작은 세공을 넣어 줄 필요가 있었습니다.
예를 들어 포그라운드 서비스를 사용하여 상주하거나 JobScheduler나 AlarmManager에서 주기적으로 서비스를 시작하여 BLE 스캔을 해야 했습니다.
덧붙여서 여기가 Nougat 이전의 BLE 스캔용의 메소드입니다.
Android 8.0 (Oreo) 이상에서 BLE 스캔
그리고 Oreo에서 추가된 BLE 스캔을 위한 방법이 여기에 있습니다.
콜백을 설정하는 대신 PendingIntet에서 스캔 결과를 받을 수 있습니다.
스캔 시작 성공 및 실패는 메소드의 반환 값으로 반환되도록 변경되었습니다.
1. PendingIntent 생성
먼저 PendingIntent를 생성합니다.
이번에는 BLE 스캔 결과를 받기위한 BroadcastReceiver를 지정하려고했습니다.
requestCode는 임의의 고유한 값을 지정해 두면 OK입니다(0을 지정하면 Intent가 통지되지 않으므로 주의)
fun createBleScanPendingIntent(context: Context): PendingIntent {
val requestCode = 222
val intent = Intent(context, BleScanReceiver::class.java)
return PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
2. BLE 스캔 시작
BLE 스캔 설정, 스캔 필터에 대해서는 Nougat 이전의 지정 방법과 같습니다. null 지정도 가능.
스캔 시작 메소드에 콜백 대신 PendingIntent를 지정하면 스캔이 시작됩니다.
fun startBleScan(context: Context) {
// BLE Scan設定
val scanSettings = ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_BALANCED)
.build()
// BLE Scanフィルタ
val scanFilters = listOf(ScanFilter.Builder().setDeviceAddress("XX:XX:XX:XX:XX:XX").build())
// PendingIntent
val pendingIntent = createBleScanPendingIntent(context)
// BLEスキャン開始
bluetoothAdapter?.bluetoothLeScanner?.startScan(scanFilters, scanSettings, pendingIntent).let {
if(it != 0) {
// BLEスキャン失敗
}
}
}
조금 신경이 쓰이는 것이 BLE 스캔 실패의 경우입니다. 역시 Bluetooth를 OFF/ON 할 수밖에 없는지 신경이 쓰이는 곳입니다.
3. BLE 스캔 결과 수신
BroadcastReceiver는 오류 코드, 콜백 유형 및 BLE 스캔 결과를 알립니다.
Oreo에서는 암시적 Intent를 받는 BroadcastReceiver를 AndroidManifest.xml에 지정할 수 없다는 제한이 있습니다.
이것은 명시적인 Intent이므로 AndroidManifest.xml에 지정할 수 있습니다.
class BleScanReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// Error code
val error = intent.getIntExtra(BluetoothLeScanner.EXTRA_ERROR_CODE, -1)
if (error != -1) {
// BLEスキャン失敗
Log.d(TAG, "BLE Scan error : $error")
return
}
// Callback type
val callbackType = intent.getIntExtra(BluetoothLeScanner.EXTRA_CALLBACK_TYPE, -1)
Log.d(TAG, "Callback type : $callbackType")
// Scan results
val scanResults: ArrayList<ScanResult> = intent.getParcelableArrayListExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT)
for (scanResult in scanResults) {
// ゴニョゴニョ
scanResult.device.name?.let {
Log.d(TAG, "Scan reuslt : $it")
}
}
// BLEスキャン停止
stopBleScan(context)
}
}
4. BLE 스캔 중지
스캔을 정지할 때는 스캔을 시작했을 때와 같은 내용의 PendingIntent를 지정해 줍니다.
fun stopBleScan(context: Context) {
// BLEスキャン開始した時と同じ内容のPendingIntentを使う
val pendingIntent = createBleScanPendingIntent(context)
// BLEスキャン停止
bluetoothAdapter?.bluetoothLeScanner?.stopScan(pendingIntent)
}
요약
Nougat 이전과 Oreo에서 그다지 큰 차이는 없었고, PendingIntent에서 BLE 스캔 결과를 받을 수 있다는 점이 바뀌었다.
다만, PendingIntent가 된 것에 의해 앱이 상주해 BLE 스캔을 계속할 필요가 없어진 것이 큰 차이입니다.
참고
htps : //로 ゔぇぺぺr. 안 d로이 d. 코 m/레후오렌세/안 d로이 d/bぅ에오 th/ぇ/Bぅ에토 thぇS칸에 r. HTML
htps : //에서 ゔぇぺぺr. 안 d로이 d. 코 m/아보 t/ゔぇr 시온 s/오레오/바 ckg 로우 d. HTML
Reference
이 문제에 관하여([Android 8.0(Oreo)]PendingIntent에서 BLE 스캔 결과 받기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/KentaHarada/items/4a9072379113c311d27d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)