<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Murillo Alves da Silva</title>
    <description>The latest articles on DEV Community by Murillo Alves da Silva (@tumusx).</description>
    <link>https://dev.to/tumusx</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1057452%2F249b56bc-052c-4063-b9c4-8c8111e01487.jpeg</url>
      <title>DEV Community: Murillo Alves da Silva</title>
      <link>https://dev.to/tumusx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tumusx"/>
    <language>en</language>
    <item>
      <title>Lendo SMS em dispositivos android</title>
      <dc:creator>Murillo Alves da Silva</dc:creator>
      <pubDate>Mon, 10 Apr 2023 19:37:01 +0000</pubDate>
      <link>https://dev.to/tumusx/lendo-sms-em-dispositivos-android-2lfa</link>
      <guid>https://dev.to/tumusx/lendo-sms-em-dispositivos-android-2lfa</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introdução&lt;/strong&gt;&lt;br&gt;
A verificação em dois fatores é amplamente utilizada, visto que garante maior segurança tanto para a empresa quanto para o usuário, pois confirma que o recurso está sendo acessado pelo titular da conta. Com isso, foi desenvolvida uma API que permite a leitura de SMS recebidos em tempo real. Neste artigo, abordaremos essa forma de verificação e como ela é suportada usando conceitos de broadcast receiver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prós e contras da API&lt;/strong&gt;&lt;br&gt;
Como todo recurso de software, existe prós e contras e deve ser resguardado para se utilizar em uma ocasião que realmente traz mais benefício do que malefício. &lt;/p&gt;

&lt;p&gt;Os pontos fortes da API SMS Retriever são: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sem permissões no manifest&lt;/li&gt;
&lt;li&gt;API mantida pela criadora do android, a Google;&lt;/li&gt;
&lt;li&gt;Fácil implementação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Os pontos contras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Permissão de consentimento único. Enquanto o aplicativo estiver em execução, só consegue ler o SMS única vez;&lt;/li&gt;
&lt;li&gt;Documentação da API desatualizada com alguns métodos;&lt;/li&gt;
&lt;li&gt;É necessário fazer manipulações para pegar o SMS e implementar um regex para pegar o código de verificação.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;O que de fato é essa API e por que deve usar ela?&lt;/strong&gt;&lt;br&gt;
A API SMS Retriever, é o principal e único recurso de aplicativos que não tem como objetivo principal o tratamento de mensagens e ligações. Com isso, em um aplicativo que se adequam a esses requisitos, como Whatsapp, Telegram e entre outros conseguem fazer a verificação por SMS através de apenas um broadcast receiver e permissões, seja em tempo de execução (programáticamente) quanto no manifest. Antes, era bem comum os aplicativos pegarem o SMS do usuário com essas permissões, mas em 2018, a Google tirou essa flexibilização devido o uso &lt;a href="https://9to5google.com/2018/10/08/play-store-policy-prevent-leaks/"&gt;indevido &lt;/a&gt; do recurso. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementação&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependências:
Adicione no build.gradle do app essas dependências:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    implementation 'com.google.android.gms:play-services-auth:17.0.0'
    implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Declarando as váriaveis
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    private lateinit var smsClient: SmsRetrieverClient
    private val broadcastReceiver = SmsBroadcastReceiver()
    private lateinit var resultLauncher: ActivityResultLauncher&amp;lt;Intent&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Instanciando e registrando o SmsClient
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        resultLauncher()
        smsClient = SmsRetriever.getClient(this@MainActivity)
        val actionId = IntentFilter()
        val intentFilter = IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION)
        registerReceiver(broadcastReceiver, intentFilter)
        configureFieldsWithSMS()
        initSmsClient()
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Criando listeners de sucesso e erro para o usuário:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface States {

    fun onSuccess(consentIntent: Intent)
    fun error(typeError: TypeError)

    companion object {
        var statesResult: States? = null
        fun instanceStates(states: States) {
            statesResult = states
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Colocando para detectar o primeiro SMS a ser recebido&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Caso dê erro, entra no onFailure e se der sucesso para poder detectar os SMS a ser recebido, entra no onSuccess. Caso não receba um SMS a 5 minutos, ele entra em Timeout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; fun initSmsClient() {
        smsClient.startSmsUserConsent(null).addOnSuccessListener {
            Toast.makeText(this, "Esperando pelo SMS", Toast.LENGTH_LONG).show()
        }.addOnFailureListener {
            Toast.makeText(this, it.message.toString(), Toast.LENGTH_LONG).show()
            it.printStackTrace()
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configurando o broadcast receiver&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para processar as transmissões e eventos, é necessário utilizar um broadcast receiver, registrar ele na activity e passar um IntentFilter (assim como está no onCreate)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SmsBroadcastReceiver() : BroadcastReceiver() {

    private fun &amp;lt;T&amp;gt;configureParcelable(parcelable: String, intent: Intent, classParcelable: Class&amp;lt;T&amp;gt;) : T? {
        return if(Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.TIRAMISU) {
            intent.extras?.getParcelable(parcelable, classParcelable)
        }else{
            intent.extras?.getParcelable(parcelable)
        }
    }

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == SmsRetriever.SMS_RETRIEVED_ACTION) {
            try {
                val smsRetrieverStatus = configureParcelable(SmsRetriever.EXTRA_STATUS, intent, Status::class.java)

                when (smsRetrieverStatus?.statusCode) {
                    CommonStatusCodes.SUCCESS -&amp;gt; {
                        val consentIntent = configureParcelable(SmsRetriever.EXTRA_CONSENT_INTENT, intent, Intent::class.java)
                        consentIntent?.let { States.statesResult?.onSuccess(it)}
                    }

                    CommonStatusCodes.ERROR -&amp;gt; {
                        States.statesResult?.error(TypeError.ERROR)
                    }

                    CommonStatusCodes.TIMEOUT -&amp;gt; {
                        States.statesResult?.error(TypeError.TIMEOUT)
                    }
                }

            } catch (exception: java.lang.Exception) {
                States.statesResult?.error(TypeError.EXCEPTION)
                exception.printStackTrace()
            }
        }
    }
}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Apresentando o SMS para o usuário
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; private fun configureFieldsWithSMS() {
        States.instanceStates(object : States {
            override fun onSuccess(consentIntent: Intent) {
                resultLauncher.launch(consentIntent)
            }

            override fun error(typeError: TypeError) {
                Log.d("ERROR", typeError.name)
            }
        })
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Processando resposta do usuário: 
Caso o usuário deu OK ao consentimento de ler SMS, conseguiremos ler a mensagem. Com isso, é necessário resgatar esse código no activityResult
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private fun resultLauncher() {
         resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result-&amp;gt;
            if(result.resultCode == Activity.RESULT_OK) {
                val sms = result.data?.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE).toString()
                Toast.makeText(this@MainActivity, sms, Toast.LENGTH_LONG).show()
            }
        }
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Criando a mensagem no emulador:
Para simular, é necessário seguir um padrão de mensagem especificada pela Google. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S4FC8AcK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9d7nth1s8sfc5n1bzeul.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S4FC8AcK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9d7nth1s8sfc5n1bzeul.png" alt="Imagem retirada da [documentação](https://developers.google.com/identity/sms-retriever/verify?hl=pt-br)" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
Com isso, já que não temos um server side para mandar o SMS com códigos, iremos configurar manualmente no emulador e mandar por lá mesmo. &lt;br&gt;
Clique nas configurações do emulador (3 pontos): &lt;br&gt;
Vá na opção &lt;em&gt;Phone&lt;/em&gt; do lado esquerdo e depois insira um texto com os padrões especificados acima. Exemplo: &lt;strong&gt;teste 1234&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Com isso, será apresentando o bottomSheet pedindo o consentimento: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MekRY1oE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ujbuekne9gx8b4a5op3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MekRY1oE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ujbuekne9gx8b4a5op3.png" alt="BottomSheet requisitando consentimento do usuário" width="322" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;E caso o usuário dê o aceite, o SMS será apresentando na tela em forma de Toast:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--amRu7VmL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43ppx5z1u5nhccbzfiws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--amRu7VmL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43ppx5z1u5nhccbzfiws.png" alt="SMS em forma de Toast" width="322" height="688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso queira ver o código todo, ele se encontra neste &lt;a href="https://github.com/tumusx/tools-android/tree/master/tasks/src/main/java/com/github/tumusx/tasks"&gt;repositório &lt;/a&gt; do github.&lt;/p&gt;

&lt;p&gt;Contate-me&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/tumusx/"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Garantindo a execução de alarmes no modo soneca do Android</title>
      <dc:creator>Murillo Alves da Silva</dc:creator>
      <pubDate>Sun, 02 Apr 2023 21:27:32 +0000</pubDate>
      <link>https://dev.to/tumusx/garantindo-a-execucao-de-alarmes-no-modo-soneca-do-android-2pcn</link>
      <guid>https://dev.to/tumusx/garantindo-a-execucao-de-alarmes-no-modo-soneca-do-android-2pcn</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introdução&lt;/strong&gt;&lt;br&gt;
A medida que novas versões do android vão surgindo, são criadas  diferentes formas de trabalho e acesso aos dados do ecossistema. Diante disso, desde a versão do android 6, a Google vem tratando a forma que os serviços são executados, visando uma boa experiência do usuário e diminuindo riscos em potenciais. &lt;br&gt;
A Google também avançou em diversas ferramentas para trabalhos em segundo plano e agendamentos de tarefas, no qual podemos citar: AlarmManager, WorkManager(oficial) e Firebase JobDispatcher. A medida que crescia a popularidade dessas ferramentas, a preocupação com o consumo de bateria também aumentava. &lt;br&gt;
Em suma, o consumo de bateria diminui quando estamos executando alguma tarefa em segundo plano, visto que a execução dela pode ser feita de diferentes formatos, desde uma vez a cada hora e até de maneira recorrente com poucos intervalos de 10 segundos. &lt;br&gt;
Com isso, a partir do android 6, foi introduzido o modo Soneca e amplamente apoiado pela comunidade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que é o modo soneca?&lt;/strong&gt;&lt;br&gt;
O modo soneca no android é uma forma de economizar bateria quando o dispositivo está muito tempo sem interação, ou seja, o celular só entra neste modo quando o usuário não utiliza. Sendo assim, o modo soneca entende que o dispositivo não está sendo utilizado e barra qualquer alarme, notificação, acesso a dados remotos e até tarefas que estão sendo executados em segundo plano, mas com uma condição: Essas tarefas, alarmes, notificações e etc são executados, mas em um formato de janela e varia com o tempo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que são as janelas de execução?&lt;/strong&gt;&lt;br&gt;
As &lt;a href="https://developer.android.com/training/monitoring-device-state/doze-standby?hl=pt-br"&gt;janelas de execução&lt;/a&gt; são feitas para poder executar qualquer tarefa quando o dispositivo estiver no modo soneca. A partir da janela, o sistema operacional aciona algumas tarefas e coloca em uma janela. Com isso, todas as tarefas são executadas naquele período. O problema é que a medida que uma janela é colocada, a próxima executa em um tempo maior que a outra, sendo assim, a tarefa que era para ser executada a cada 30 segundos, naquela janela ela será executada daqui a 30 minutos e prejudicando o seu aplicativo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AlarmManager&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Não vamos nos aprofundar nesse momento com o alarmManager, mas é necessário termos um breve conhecimento.&lt;/em&gt;&lt;br&gt;
Segundo a &lt;a href="https://developer.android.com/training/scheduling/alarms?hl"&gt;documentação do AlarmManager&lt;/a&gt;, ele é uma ferramenta para realizar operações baseadas em tempo fora da vida útil do seu app. Em qualquer projeto tem seu caso de uso, mas podemos imaginar uma o conceito de despertador, mas imaginemos o seguinte: o despertador só sabe que precisa tocar todos os dias as 16:30 horas porque foi programado através do alarmManager para ele realizar aquela operação. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problemática&lt;/strong&gt; &lt;br&gt;
Temos um seguinte problema e precisamos resolver ele urgente: Um grupo de desenvolvedores criaram um aplicativo que gerencia o tempo de estudos dos usuários. Logo após o desenvolvimento, eles notaram que aqueles estudantes que passavam um bom tempo sem o celular começaram a reclamar que o dispositivo não estava tocando no horário programado e ocasionando em tempos indevidos de estudos.&lt;br&gt;
Basicamente, é isso que vamos resolver aqui. Será criado uma solução para este problema e fazer com que o dispositivo toque mesmo no modo soneca. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementação&lt;/strong&gt; &lt;br&gt;
Criando um projeto android, iremos criar a classe &lt;em&gt;IdleAlarmManager&lt;/em&gt;, onde fica responsável por configurar toda ação de alarme do aplicativo. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;IdleAlarmManager&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class IdleAlarmManager(context: Context) {
    private val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
    private val alarmIntent =
        PendingIntent.getBroadcast(context, 0, Intent(context, AlarmReceiver::class.java), 0)
    private val calendar = Calendar.getInstance().apply {
        timeInMillis = System.currentTimeMillis()
        set(Calendar.HOUR_OF_DAY, SUA_HORA)
        set(Calendar.MINUTE, SEU_MINUTO)
    }

    fun setAlarmManager() = alarmManager.setExactAndAllowWhileIdle (
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        alarmIntent
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicação do código acima: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;É criado uma pendingIntent e passando qual broadcast receiver deve ser chamado quando o alarme for disparado. &lt;/li&gt;
&lt;li&gt;O objeto &lt;em&gt;calendar&lt;/em&gt; é utilizado para definir o horário que o alarme será disparado. &lt;/li&gt;
&lt;li&gt;A parte mais importante do código: O metódo setAlarmManager() faz a configuração do alarme e a sua característica, no nosso caso, um alarme que dispara mesmo no modo soneca. 

&lt;ul&gt;
&lt;li&gt;o metódo &lt;em&gt;setExactAndAllowWhileIdle()&lt;/em&gt; garante que o alarme será chamado mesmo quando estiver no modo soneca, diferente do &lt;em&gt;setAndAllowWhileIdle&lt;/em&gt;(), no qual não tem total garantia. Este método exato ou o outro deve ser chamado para que o alarme seja tocado. Se for usado qualquer outro método, só será disparado quando o dispositivo sair do modo soneca. Lembrando que ambos podem haver atrasos em disparar esse alarme.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Depois, para mostrar a notificação após o alarme ser executado, será necessário criar um broadcast receiver e registrar no manifest. O broadcast receiver permite que um aplicativo receba mensagens ou "broadcasts" do sistema operacional ou de outros aplicativos, mesmo quando o aplicativo não está em execução. O metódo onReceive() é chamado toda vez que recebe uma mensagem do sistema.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Android Manifest&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        &amp;lt;receiver android:name="com.github.tumusx.idle.alarmManager.AlarmReceiver"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;AlarmReceiver&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
            val builder = NotificationCompat.Builder(context, SEU_CHANNEL_ID)
                .setSmallIcon(R.drawable.notification)
                .setContentTitle(SEU_TITULO)
                .setContentText(SUA_MENSAGEM)
                .setStyle(
                    NotificationCompat.BigTextStyle()
                        .bigText(SUA_MENSAGEM)
                )
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            val name = SEU_NOME
            val description = SUA_DESCRICAO
            val channelNotification = NotificationChannel(
                SEU_CHANNEL_ID,
                name,
                NotificationManager.IMPORTANCE_HIGH,
            ).also {
                it.description = description
            }
            val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channelNotification)
            notificationManager.notify(SEU_CHANNEL_ID, builder.build())
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não irei entrar em detalhes sobre o código acima pois não é o objetivo tratar notificações, mas em resumo, toda vez que o alarme for disparado, será construído e mostrado uma notificação para o usuário. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NÃO É POSSÍVEL ALTERAR PROGRAMATICAMENTE O MODO SONECA NO ANDROID&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para testar se realmente o alarme está sendo despertado no modo soneca, é necessário executar alguns comandos para forçar o dispositivo a entrar no modo soneca:&lt;br&gt;
Com o seguinte caminho, abra o cmd: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;C:\Users\SEU_USER\AppData\Local\Android\Sdk\platform-tools&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;adb shell dumpsys deviceidle enable: Força a entrar em modo econômico;&lt;/li&gt;
&lt;li&gt;adb shell dumpsys deviceidle force-idle: Força a entrar em modo soneca;&lt;/li&gt;
&lt;li&gt;adb shell dumpsys deviceidle get deep: Checa o estado atual do dispositivo. Se retornar a mensagem IDLE, ele está em modo soneca;&lt;/li&gt;
&lt;li&gt;adb shell dumpsys deviceidle unforce: Remove o dispositivo do modo soneca.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Caso queira consultar o &lt;a href="https://github.com/tumusx/tools-android/tree/master/idle"&gt;repositório&lt;/a&gt;, se encontra no github.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Considerações finais&lt;/strong&gt;&lt;br&gt;
Como foi mostrado, é possível sim executar alguns processos mesmo quando o dispositivo estiver no modo soneca. Lembrando que o uso dessa implementação, o modo soneca não é desativado. Apenas garante que o alarme seja disparado quando estiver neste modo. &lt;br&gt;
Existe outra solução para o problema, mas é utilizado o Firebase Cloud Messaging e a notificação tem que ser definida como prioridade alta. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contate-me&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/tumusx/"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
