【Android】Android Sleep API 시작하기

Sleep API



이하 초역↓
  • Sleep API를 활용하면 앱에서 사용자가 언제 자고 언제 일어나는지 결정할 수 있습니다.
  • 주변 밝기, 장치 움직임 등과 관련된 정보를 수집하여 사용자가 잠들고 깨어나는 시간을 추측합니다.
  • 정보 업데이트를 구독할 수 있습니다.


  • 다양한 기능에 조합하는 것으로 효력을 발휘할 것 같은 API군요.

    실제로 시도해보기



    아래 준비



    1. target sdk를 29 이상으로 설정



    ※29 이하라면 취득을 할 수 없기 때문에, minsSDK는 29로 설정하고 있습니다

    build.gradle
    android {
        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.kt
    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を流す
            }
        }
    }
    
    

    콜백은 어떤 형태라도 OK입니다.
    DataStore + Flow + LiveData 등을 사용하더라도

    2. 데이터 보기



    SleepClassifyEventSleepSegmentEvent 를 취득 가능합니다.
    각각 이하 초역↓
  • SleepClassifyEvent 은 수면 신뢰도와 장치 움직임 및 주변광 레벨과 같은 지원 데이터를 포함하는 수면 분류 이벤트를 나타냅니다. 분류 이벤트는 10분마다 정기적인 간격으로 보고됩니다.
  • SleepSegmentEvent 은 사용자의 수면 시작, 종료 시간 또는 수면 상태인지 여부를 감지한 시간 등을 감지할 수 있습니다.

  • 시도에 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
    없음


    깨달음
  • 10 분 간격은 어디 까지나 대략이며, 실제로는 어느 정도 오차가있다
  • confidence는 기준값 낮게 해 두어도 좋을 것 같다
  • light의 정밀도는 뛰어난

  • 마지막으로



    confidence 이외의 정밀도는 상당히 높은 인상을 받았습니다.
    알림을 부정기적으로 보내는 기능과 조합하여 사용자가 자고 있을 시간에는 보내지 않도록 할 수 있을까 생각합니다.

    신경이 쓰이는 분은 꼭 SleepSegmentEvent 도 계측해 보세요!

    좋은 웹페이지 즐겨찾기