【Android】Android Sleep API 시작하기
Sleep API
이하 초역↓
다양한 기능에 조합하는 것으로 효력을 발휘할 것 같은 API군요.
실제로 시도해보기
아래 준비
1. target sdk를 29 이상으로 설정
※29 이하라면 취득을 할 수 없기 때문에, minsSDK는 29로 설정하고 있습니다
build.gradleandroid {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "xxx"
minSdkVersion 29
targetSdkVersion 30
~~~
}
~~~~
}
2. 사용할 module의 Manifest에 ACTIVITY_RECOGNITION의 permission 추가
AndroidManifest.xml<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
3. 수면 행동 업데이트 요청
permission의 check를 실시해 requestSleepSegmentUpdates
MainActivity.kt
private val sleepPendingIntent: PendingIntent by lazy {
SleepDataReceiver.sleepReceiverPendingIntent(context = requireContext())
}
private val requestPermissionLauncher: ActivityResultLauncher<String> =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
// granted
} else {
// not granted
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
subscribeBtn.setOnClickListener {
if (checkActivityRecognitionPermission()) {
// request
subscribeToSleepSegmentUpdates(sleepPendingIntent)
} else {
requestPermissionLauncher.launch(Manifest.permission.ACTIVITY_RECOGNITION)
}
}
}
private fun subscribeToSleepSegmentUpdates(pendingIntent: PendingIntent) {
val task = ActivityRecognition.getClient(
requireContext()).requestSleepSegmentUpdates(
pendingIntent,
SleepSegmentRequest.getDefaultSleepSegmentRequest()
)
task.addOnSuccessListener {
Log.d(TAG, "Successfully")
}
}
실제로 이용해 본다
1. 수면 정보를 받을 수 있도록 Receiver를 준비
xml.AndroidManifest.xml
<receiver
android:name=".SleepDataReceiver"
android:enabled="true"
android:exported="true" />
SleepDataReceiver.ktclass SleepDataReceiver: BroadcastReceiver() {
companion object {
private const val REQUEST_CODE = 100
fun sleepReceiverPendingIntent(context: Context): PendingIntent {
return PendingIntent.getBroadcast(
context,
REQUEST_CODE,
Intent(context, SleepDataReceiver::class.java),
PendingIntent.FLAG_CANCEL_CURRENT
)
}
}
override fun onReceive(context: Context?, intent: Intent?) {
if (SleepSegmentEvent.hasEvents(intent)) {
val sleepSegmentEvents: List<SleepSegmentEvent> =
SleepSegmentEvent.extractEvents(intent)
// コールバックを用意してSleepSegmentEventsを流す
} else if (SleepClassifyEvent.hasEvents(intent)) {
val sleepClassifyEvents: List<SleepClassifyEvent> =
SleepClassifyEvent.extractEvents(intent)
// コールバックを用意してSleepClassifyEventを流す
}
}
}
콜백은 어떤 형태라도 OK입니다.
DataStore + Flow + LiveData 등을 사용하더라도
2. 데이터 보기
SleepClassifyEvent 과 SleepSegmentEvent 를 취득 가능합니다.
각각 이하 초역↓
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "xxx"
minSdkVersion 29
targetSdkVersion 30
~~~
}
~~~~
}
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
private val sleepPendingIntent: PendingIntent by lazy {
SleepDataReceiver.sleepReceiverPendingIntent(context = requireContext())
}
private val requestPermissionLauncher: ActivityResultLauncher<String> =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
// granted
} else {
// not granted
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
subscribeBtn.setOnClickListener {
if (checkActivityRecognitionPermission()) {
// request
subscribeToSleepSegmentUpdates(sleepPendingIntent)
} else {
requestPermissionLauncher.launch(Manifest.permission.ACTIVITY_RECOGNITION)
}
}
}
private fun subscribeToSleepSegmentUpdates(pendingIntent: PendingIntent) {
val task = ActivityRecognition.getClient(
requireContext()).requestSleepSegmentUpdates(
pendingIntent,
SleepSegmentRequest.getDefaultSleepSegmentRequest()
)
task.addOnSuccessListener {
Log.d(TAG, "Successfully")
}
}
<receiver
android:name=".SleepDataReceiver"
android:enabled="true"
android:exported="true" />
class SleepDataReceiver: BroadcastReceiver() {
companion object {
private const val REQUEST_CODE = 100
fun sleepReceiverPendingIntent(context: Context): PendingIntent {
return PendingIntent.getBroadcast(
context,
REQUEST_CODE,
Intent(context, SleepDataReceiver::class.java),
PendingIntent.FLAG_CANCEL_CURRENT
)
}
}
override fun onReceive(context: Context?, intent: Intent?) {
if (SleepSegmentEvent.hasEvents(intent)) {
val sleepSegmentEvents: List<SleepSegmentEvent> =
SleepSegmentEvent.extractEvents(intent)
// コールバックを用意してSleepSegmentEventsを流す
} else if (SleepClassifyEvent.hasEvents(intent)) {
val sleepClassifyEvents: List<SleepClassifyEvent> =
SleepClassifyEvent.extractEvents(intent)
// コールバックを用意してSleepClassifyEventを流す
}
}
}
시도에 10분 간격으로 수신하는 SleepClassifyEvent의 로그를 내 보았습니다.
SleepClasify의 getTimestampMillis을 측정해 보았습니다.
timestampMillis(UNIX time)
timestampMillis(날짜 표기)
confidence
빛
motion
단말 조작의 유무
1616651011
2021-03-25 14:43:31
3
5
6
예
1616651370
2021-03-25 14:49:30
1
5
6
예
1616651858
2021-03-25 14:57:38
2
5
4
예
1616652348
2021-03-25 15:05:48
4
5
6
예
1616652836
2021-03-25 15:13:56
1
5
5
예
1616653325
2021-03-25 15:22:05
22
5
4
없음
깨달음
마지막으로
confidence 이외의 정밀도는 상당히 높은 인상을 받았습니다.
알림을 부정기적으로 보내는 기능과 조합하여 사용자가 자고 있을 시간에는 보내지 않도록 할 수 있을까 생각합니다.
신경이 쓰이는 분은 꼭
SleepSegmentEvent
도 계측해 보세요!
Reference
이 문제에 관하여(【Android】Android Sleep API 시작하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/HaSuzuki/items/0d430f06ebecf8b6536c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)