Codelab da API Android Sleep

O que você criará

Neste codelab, você criará um app Android para detectar a tempo de sono do usuário. O app irá:

  • solicitar permissões;
  • registrar-se na API Android Sleep;
  • recuperar os eventos da API e exibi-los na IU;
  • cancelar o registro quando ele não for mais necessário.

Pré-requisitos

  • Uma versão recente do Android Studio com o Android Build Tools v21 ou mais recente
  • Dispositivos com o Android 10 (API de nível 29) ou mais recente

Clonar o repositório inicial do projeto

Para começar o mais rápido possível, preparamos um projeto inicial para você desenvolver. Verifique se você tem o git instalado digitando git --version na linha de comando / terminal. Se ele não estiver instalado, siga estas instruções para instalá-lo. Depois, basta executar o seguinte comando para clonar o projeto.

 git clone https://github.com/googlecodelabs/android-sleep/

Importar o projeto

Inicie o Android Studio, selecione "Open an existing Android Studio project" na tela de boas-vindas e abra o diretório do projeto.

Após o carregamento do projeto, você verá um alerta informando que o Git não está rastreando todas as mudanças locais. Clique em Ignore ou no X no canto superior direito. Você não enviará mudanças ao repositório Git.

No canto superior esquerdo da janela do projeto, você verá algo semelhante à imagem a seguir se estiver na visualização Android. Se você estiver na visualização Project, precisará expandi-la para ver a mesma coisa.

1401a11c10711a60.png

Há dois ícones de pasta (start e complete). Cada um deles é conhecido como "módulo".

O Android Studio pode levar vários segundos para compilar o projeto em segundo plano pela primeira vez. Durante esse período, você verá um ícone de carregamento na barra de status, na parte inferior do Android Studio:

4bc64eb3b99eb0ae.png

Recomendamos aguardar até que isso termine antes de fazer mudanças no código. Isso permitirá que o Android Studio extraia todos os componentes necessários.

Além disso, se você receber uma mensagem que diz "Reload for language changes to take effect?" ou algo semelhante, selecione "Yes".

Entender o projeto inicial

Está tudo pronto para você adicionar o reconhecimento de atividade. Usaremos o módulo start, que é o ponto de partida para este codelab. Em outras palavras, você adicionará um código de cada etapa a start.

O módulo complete pode ser usado para verificar seu trabalho ou para consulta em caso de problemas.

Visão geral dos componentes principais:

  • MainActivity.kt: renderiza a tela principal do app quando o usuário inicia o app.
  • SleepReceiver.kt: extrai eventos de sono da API e os armazena no banco de dados.
  • BootReceiver.kt: registra-se novamente na API Sleep quando a inicialização do dispositivo está completa para continuar ouvindo eventos dessa API.

Executar o projeto inicial

Vamos executar o app.

  1. Conecte seu dispositivo Android ao computador.
  2. Na barra de ferramentas, selecione a configuração start no seletor suspenso, escolha seu dispositivo e clique no botão de triângulo verde (Executar) ao lado dele:

177045a302bf57d8.png

Você verá o app no seu dispositivo:

30efe28b9757e1e7.png

311c83ca64556d94.png

Ainda não adicionamos nenhum código para monitorar o sono. Isso será feito nas próximas seções.

Na próxima seção, analisaremos a biblioteca e as permissões necessárias.

Revisar build.gradle e AndroidManifest.xml

Para usar a API Sleep no app, você precisa declarar uma dependência à API Google Location and Activity Recognition e especificar a permissão com.google.android.gms.permission.ACTIVITY_RECOGNITION no manifesto do app.

  1. Pesquise TODO: Review play services library required for activity recognition de atividades no arquivo build.gradle do módulo start. Não há ações nessa etapa. Apenas analise a dependência declarada de que precisamos. Ela teve ter a seguinte aparência:
    // TODO: Review play services library required for activity recognition.
    implementation 'com.google.android.gms:play-services-location:18.0.0'
  1. No módulo start, pesquise TODO: Add activity Recognition and boot complete permissions no arquivo AndroidManifest.xml e adicione o seguinte código ao elemento <manifest>.
<!-- TODO: Add activity recognition and receive boot complete permissions. -->
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Agora, seu código ficará assim:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.example.sleepcodelab">
...
<!-- TODO: Add activity recognition and receive boot complete permissions. -->
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  ...
</manifest>

Como é possível ver nos comentários, é necessário adicionar a permissão de execução para a API versão 29.

Pronto! Agora seu app é compatível com reconhecimento de atividade de sono. Basta adicionar o código para receber as informações.

Revisar a verificação de permissão do reconhecimento de atividade

Precisamos verificar e solicitar as permissões de execução, se necessário:

  • No MainActivity.kt, verificaremos as permissões de reconhecimento da atividade.
  • Se as permissões não tiverem sido concedidas, chamaremos displayPermissionSettingsSnackBar(). Este snackbar explica as necessidades da permissão e permite que os usuários aprovem a permissão nas configurações do sistema.

No módulo start, pesquise TODO: Review Activity Recognition permission check em MainActivity.kt. Você verá este snippet de código.

Não há ações para esta seção.

// TODO: Review Activity Recognition permission checking.
private fun activityRecognitionPermissionApproved(): Boolean {
   return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
           this,
           Manifest.permission.ACTIVITY_RECOGNITION
   );
}

Ativar/desativar o Monitoramento do sono

No módulo start, pesquise TODO: Enable/Disable Sleep tracking and ask for permissions if needed em MainActivity.kt. Substitua o método onClickRequestSleepData() pelo código a seguir.

// TODO: Enable/Disable sleep tracking and ask for permissions if needed.
fun onClickRequestSleepData(view: View) {
   if (activityRecognitionPermissionApproved()) {
       if (subscribedToSleepData) {
           unsubscribeToSleepSegmentUpdates(applicationContext, sleepPendingIntent)
       } else {
           subscribeToSleepSegmentUpdates(applicationContext, sleepPendingIntent)
       }
   } else {
       requestPermissionLauncher.launch(permission.ACTIVITY_RECOGNITION)
   }
}

Se a permissão de reconhecimento de atividade for aprovada e o usuário tiver se inscrito para dados de sono, receberemos atualizações de sono. Caso contrário, cancelamos a inscrição.

Quando a permissão não é aprovada, enviamos o usuário para a atividade na tela de apresentação, que explica por que precisamos da permissão, e permitimos que ele a ative.

Criar um PendingIntent

No módulo start, pesquise TODO: Create a PendingIntent for Sleep API events em MainActivity.kt. Cole o snippet a seguir.

// TODO: Create a PendingIntent for Sleep API events
sleepPendingIntent =
   SleepReceiver.createSleepReceiverPendingIntent(context = applicationContext)

Agora temos uma maneira de receber atualizações quando os dados da API Sleep estiverem disponíveis.

Solicitar atualizações da API Sleep

No módulo start, pesquise TODO: Request Sleep API updates em MainActivity.kt. Cole o snippet a seguir.

// TODO: Request Sleep API updates
val task = ActivityRecognition.getClient(context).requestSleepSegmentUpdates(
   pendingIntent,
   // Registers for both SleepSegmentEvent and SleepClassifyEvent data.
   SleepSegmentRequest.getDefaultSleepSegmentRequest()
)

task.addOnSuccessListener {
   mainViewModel.updateSubscribedToSleepData(true)
   Log.d(TAG, "Successfully subscribed to sleep data.")
}
task.addOnFailureListener { exception ->
   Log.d(TAG, "Exception when subscribing to sleep data: $exception")
}

Depois de se registrar para receber atualizações da API Sleep, o app receberá notificações de detecção de sono na PendingIntent registrada.

Inscrever-se novamente após a inicialização

No módulo start, pesquise TODO: Request Sleep API when boot complete em receiver/BootReceiver.kt. Cole o snippet a seguir.

// TODO: Request Sleep API upon boot complete
val subscribedToSleepData = repository.subscribedToSleepDataFlow.first()
if (subscribedToSleepData) {
   subscribeToSleepSegmentUpdates(
       context = context,
       pendingIntent = SleepReceiver.createSleepReceiverPendingIntent(context)
   )
}

O código permite que o app continue recebendo atualizações da API Sleep após a reinicialização do dispositivo.

Quando ocorre um evento de classificação ou detecção do tempo de sono, seu app recebe um callback de Intent. Uma lista de objetos SleepSegmentEvent ou SleepClassifyEvent pode ser extraída da intent.

Vamos adicionar o código para lidar com esses eventos.

No módulo start, pesquise TODO: Extract sleep information from PendingIntent em receiver/SleepReceiver.kt. Adicione o seguinte código após o comentário.

// TODO: Extract sleep information from PendingIntent.
if (SleepSegmentEvent.hasEvents(intent)) {
   val sleepSegmentEvents: List<SleepSegmentEvent> =
       SleepSegmentEvent.extractEvents(intent)
   addSleepSegmentEventsToDatabase(repository, sleepSegmentEvents)
} else if (SleepClassifyEvent.hasEvents(intent)) {
   val sleepClassifyEvents: List<SleepClassifyEvent> =
       SleepClassifyEvent.extractEvents(intent)
   addSleepClassifyEventsToDatabase(repository, sleepClassifyEvents)
}

Isso salvará os dados de SleepSegmentEvent ou SleepClassifyEvent em um banco de dados do Room. A MainActivity acessa essas informações do banco de dados por um ViewModel usando LiveData. Para saber mais sobre como essas classes funcionam juntas, confira o codelab Room com View.

É isso. Está tudo pronto! Tente executar o app.

Conecte seu dispositivo à estação de trabalho usando um cabo. Clique em "Run" no Android Studio para instalar e executar o app no seu dispositivo. Depois de conceder a permissão de reconhecimento de atividade e tocar no botão SUBSCRIBE TO SLEEP DATA, o primeiro SleepClassifyEvent será exibido em aproximadamente 10 minutos. O SleepSegmentEvent deve aparecer em um dia.

Você poderá ler o código completo para revisar o que foi feito e entender melhor como ele funciona.

Revisões de código opcionais

As seguintes revisões de código são opcionais. Elas fornecem detalhes sobre o mapeamento de dados entre a API Sleep e as entidades do banco de dados:

  • data/db/SleepClassifyEventEntity.kt
  • data/db/SleepSegmentEventEntity.kt

Documentos de referência