AlarmManager é uma classe que nos permite criar alarmes. Os alarmes permitem que nossos aplicativos programem códigos específicos para serem executados em determinados momentos no futuro.

public class AlarmManager extends Object{}

É melhor e mais eficiente utilizar a classe 'AlarmManager' para criar alarmes para programação do que utilizar algo como um temporizador.

AlarmManager nos fornece o acesso aos serviços de alarme do sistema, portanto não é como se fôssemos inventar nossos algoritmos de agendamento.

O "AlarmManager" é utilizado principalmente em conjunto com BroadcastReceivers. É assim que ele funciona:

  • O primeiro alarme dispara ou toca.
  • O sistema emite um "alerta". Este é o intent que tinha sido registrado para ele.
  • Isto inicia automaticamente a aplicação alvo caso ainda não esteja funcionando.
  • Se o dispositivo dormir, os alarmes que já estão registrados são mantidos.
  • Se o alarme dispara enquanto o dispositivo está dormindo, então o dispositivo é despertado. Isto é opcional.
  • Se o usuário desligar o dispositivo ou reinicializá-lo, então os alarmes são liberados.

Você tem a garantia de que o telefone não irá dormir até que tenha terminado de transmitir. As transmissões são tratadas pelo método 'onReceive()`android.content.BroadcastReceiver'. Este é um método que você anula depois de derivar esta classe.

Enquanto o método onReceive() ainda estiver sendo executado, o `AlarmManager' manterá um bloqueio de despertar da CPU. Assim, o dispositivo não vai dormir.

Então o AlarmManager' libera o bloqueio de despertar quando o onReceive()` termina a execução e retorna.

Mas às vezes, assim que o método onReceive() termina, é possível que o telefone possa dormir imediatamente. Como o dispositivo dormiu rapidamente, se você tivesse solicitado um serviço utilizando o Context.startService(), ele não será iniciado. Isto porque o dispositivo já dormiu antes de ser chamado. Entretanto, a trava de despertar inicial não está mais no lugar. Ela havia sido liberada no momento em que o onReceive() havia retornado. Então, qual é a solução? Bem, você implementa uma trava de velório separada em seu "BroadcastReceiver" e "Service". Esta trava de velório garantirá que o dispositivo funcione até que o serviço esteja disponível.

Então, quando você deve utilizar o AlarmManager e quando não deve? Bem, utilize o "AlarmManager" para programar as operações. Não o utilize para operações de cronometragem e marcação de tempo. E não utilize temporizadores para operações de agendamento. O código programado utilizando o `AlarmManager' não requer que o aplicativo esteja em execução o tempo todo. Se você utilizasse um temporizador, ele teria que rodar o tempo todo. Isto desperdiça memória e tempo de processamento.

O Sistema Operacional Android muda os alarmes para minimizar o despertar e o uso da bateria. Isto é a partir do Android API 19(KitKat). Isto os alarmes podem não ser estritamente exatos. Se você precisar ser estritamente exato, então você pode utilizar o método setExact().

O AlarmManager' não é diretamente instanciado. Em vez disso, você utiliza o getSystemService() estático da classe Context'. Você passa a bandeira `Context.ALARM_SERVICE'.

Context.getSystemService(Context.ALARM_SERVICE

Exemplo 1: Kotlin Android Construir um Relógio de Alarme

Este é um exemplo para lhe ensinar o uso de Alarmes e Broadcastreceiver. No processo, você constrói um simples despertador. Este exemplo permite que você aprenda estas tecnologias de forma prática.

Passo 1: Criar o Projeto Kotlin

Comece criando um projeto Kotlin vazio no Android Studio.

Passo 2: Dependências

Não são necessárias dependências especiais. Entretanto, como são usados coroutinos, não deixe de usar o Kotlin.

Passo 3: Permissões

Nenhuma permissão é necessária para este projeto. Entretanto, em seu in 'AndroidManifest.xml', certifique-se de registrar o 'receptor', uma vez que 'BroadcastReceiver' é utilizado neste relógio despertador.

        <receiver
            android:name=".AlarmReceiver"
            android:exported="false" />

Passo 4: Layout do projeto

Você só precisa de um layout, o layout "MainActivity". Basta adicionar TextViews e botões e restringi-los utilizando o `ConstraintLayout' como a seguir:

**activity_main.xml***

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/background_black"
    tools:context=".MainActivity">

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginHorizontal="50dp"
        android:background="@drawable/background_white_ring"
        app:layout_constraintBottom_toTopOf="@id/onOffButton"
        app:layout_constraintDimensionRatio="H,1:1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/timeTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="09:30"
        android:textColor="@color/white"
        android:textSize="50sp"
        app:layout_constraintBottom_toTopOf="@id/ampmTextView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed" />

    <TextView
        android:id="@+id/ampmTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="AM"
        android:textColor="@color/white"
        android:textSize="25sp"
        app:layout_constraintBottom_toTopOf="@id/onOffButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/timeTextView" />

    <Button
        android:id="@+id/onOffButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/on_alarm"
        app:layout_constraintBottom_toTopOf="@id/changeAlarmTimeButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <Button
        android:id="@+id/changeAlarmTimeButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/change_time"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Passo 5: Criar classe de modelo

Criar uma classe modelo, classe de dados Kotlin que recebe os dois inteiros e um booleano através do construtor. Os inteiros são a hora e o minuto, enquanto o booleano é um swicth on-off. Estes serão utilizados para construir uma vista de temporizador a ser apresentada no relógio despertador:

**AlarmDisplayModel.kt***

package com.example.alarmclock

data class AlarmDisplayModel(
    val hour: Int,
    val minute: Int,
    var onOff: Boolean
) {

    val timeText: String
        get() {
            val h = "%02d".format(if (hour < 12) hour else hour - 12)
            val m = "%02d".format(minute)

            return "$h:$m"
        }

    val ampmText: String
        get() {
            return if (hour < 12) "AM" else "PM"
        }

    val onOffText: String
        get() {
            return if (onOff) "알람 끄기" else "알람 켜기"
        }

    fun makeDataForDB(): String {
        return "$hour:$minute"
    }

}

Passo 5: Criar um "Receptor de Alarme".

Você faz isto estendendo o "receptor de transmissão" e substituindo o método "onReceive()onReceive(). Dentro do onReceive(), você criará um canal de notificação, bem como construirá uma notificação.

Aqui está o código completo:

**AlarmReceiver.kt***

package com.example.alarmclock

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat

class AlarmReceiver: BroadcastReceiver() {

    companion object {
        const val NOTIFICATION_ID = 100
        const val NOTIFICATION_CHANNEL_ID = "1000"
    }

    override fun onReceive(context: Context, intent: Intent) {
        createNotificationChannel(context)
        notifyNotification(context)
    }

    private fun createNotificationChannel(context: Context) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel = NotificationChannel(
                NOTIFICATION_CHANNEL_ID,
                "기상 알람",
                NotificationManager.IMPORTANCE_HIGH
            )

            NotificationManagerCompat.from(context).createNotificationChannel(notificationChannel)
        }
    }

    private fun notifyNotification(context: Context) {
        with(NotificationManagerCompat.from(context)) {
            val build = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
                .setContentTitle("알람")
                .setContentText("일어날 시간입니다.")
                .setSmallIcon(R.drawable.ic_launcher_foreground)
                .setPriority(NotificationCompat.PRIORITY_HIGH)

            notify(NOTIFICATION_ID, build.build())

        }

    }

}

Etapa 6: Criar a atividade principal

Finalmente crie sua MainActivity como abaixo:

"atividade principal".kt****

package com.example.alarmclock

import android.app.AlarmManager
import android.app.PendingIntent
import android.app.TimePickerDialog
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import java.util.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initOnOffButton()
        initChangeAlarmTimeButton()

        val model = fetchDataFromSharedPreferences()
        renderView(model)

    }

    private fun initOnOffButton() {
        val onOffButton = findViewById<Button>(R.id.onOffButton)
        onOffButton.setOnClickListener {

            val model = it.tag as? AlarmDisplayModel ?: return@setOnClickListener
            val newModel = saveAlarmModel(model.hour, model.minute, model.onOff.not())
            renderView(newModel)

            if (newModel.onOff) {
                // 켜진 경우 -> 알람을 등록
                val calendar = Calendar.getInstance().apply {
                    set(Calendar.HOUR_OF_DAY, newModel.hour)
                    set(Calendar.MINUTE, newModel.minute)

                    if (before(Calendar.getInstance())) {
                        add(Calendar.DATE, 1)
                    }
                }

                val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
                val intent = Intent(this, AlarmReceiver::class.java)
                val pendingIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE,
                    intent, PendingIntent.FLAG_UPDATE_CURRENT)

                alarmManager.setInexactRepeating(
                    AlarmManager.RTC_WAKEUP,
                    calendar.timeInMillis,
                    AlarmManager.INTERVAL_DAY,
                    pendingIntent
                )

            } else {
                cancelAlarm()
            }

        }
    }

    private fun initChangeAlarmTimeButton() {
        val changeAlarmButton = findViewById<Button>(R.id.changeAlarmTimeButton)
        changeAlarmButton.setOnClickListener {

            val calendar = Calendar.getInstance()
            TimePickerDialog(this, { picker, hour, minute ->

                val model = saveAlarmModel(hour, minute, false)
                renderView(model)
                cancelAlarm()

            }, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false).show()

        }

    }

    private fun saveAlarmModel(
        hour: Int,
        minute: Int,
        onOff: Boolean
    ): AlarmDisplayModel {
        val model = AlarmDisplayModel(
            hour = hour,
            minute = minute,
            onOff = onOff
        )

        val sharedPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)

        with(sharedPreferences.edit()) {
            putString(ALARM_KEY, model.makeDataForDB())
            putBoolean(ONOFF_KEY, model.onOff)
            commit()
        }

        return model
    }

    private fun fetchDataFromSharedPreferences():AlarmDisplayModel {
        val sharedPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)

        val timeDBValue = sharedPreferences.getString(ALARM_KEY, "9:30") ?: "9:30"
        val onOffDBValue = sharedPreferences.getBoolean(ONOFF_KEY, false)
        val alarmData = timeDBValue.split(":")

        val alarmModel = AlarmDisplayModel(
            hour = alarmData[0].toInt(),
            minute = alarmData[1].toInt(),
            onOff = onOffDBValue
        )

        // 보정 보정 예외처리

        val pendingIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE, Intent(this, AlarmReceiver::class.java), PendingIntent.FLAG_NO_CREATE)

        if ((pendingIntent == null) and alarmModel.onOff) {
            // 알람은 꺼져있는데, 데이터는 켜저있는 경우
            alarmModel.onOff = false

        } else if ((pendingIntent != null) and alarmModel.onOff.not()){
            // 알람은 켜져있는데, 데이터는 꺼져있는 경우
            // 알람을 취소함
            pendingIntent.cancel()
        }

        return alarmModel

    }

    private fun renderView(model: AlarmDisplayModel) {
        findViewById<TextView>(R.id.ampmTextView).apply {
            text = model.ampmText
        }

        findViewById<TextView>(R.id.timeTextView).apply {
            text = model.timeText
        }

        findViewById<Button>(R.id.onOffButton).apply {
            text = model.onOffText
            tag = model
        }

    }

    private fun cancelAlarm() {
        val pendingIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE, Intent(this, AlarmReceiver::class.java), PendingIntent.FLAG_NO_CREATE)
        pendingIntent?.cancel()
    }

    companion object {
        private const val SHARED_PREFERENCES_NAME = "time"
        private const val ALARM_KEY = "alarm"
        private const val ONOFF_KEY = "onOff"
        private const val ALARM_REQUEST_CODE = 1000

    }
}

Passo 7: Correr

Finalmente, executar o projeto.

Referência

Aqui estão os links de referência do código:

Número Link Link
1. Código de download Código de download [Código de download
2. Siga o autor do código Siga o autor do código [Siga o autor do código

Exemplo 2: Como Iniciar um Alarme

Uma dessas aplicações de software do tipo móvel é o Alarme. Ou qualquer aplicativo que possa agendar algo para acontecer no futuro. Isto é ainda mais importante em dispositivos móveis do que em aplicações desktop.

Porque nós nunca deixamos ou desligamos nossos dispositivos móveis. Eles são nossos assistentes pessoais. Portanto, os usamos de forma mais pessoal do que jamais faríamos com aplicações de desktop.

Portanto, o Android nos fornece uma classe rica chamada AlarmManager. Uma classe que nos permite acessar serviços de sistema. A classe é obviamente pública e deriva de 'java.lang.Object'.

Aqui está sua definição:

    public class AlarmManager extends Object{}

O que nós construímos?

Bem, vamos ver um exemplo simples de andróide 'AlarmManager'. Vejamos como iniciar e cancelar um alarme em andróide. Temos um texto de edição básica. O usuário entra no tempo em milissegundos para que o alarme toque. O alarme toca exibindo uma simples mensagem 'Toast'.

Estrutura do projeto

Aqui está a estrutura do projeto:

Passo 1 - Criar projeto Android

  • Em seu estúdio andróide, vá para File -- New -- New Project.
  • Digite o nome do projeto.
  • Escolha o mínimo sdk.
  • A partir de modelos, escolha atividade vazia ou bla.

Passo 2. - Vamos modificar nosso build.gradle.

Este é o nosso segundo passo. Os projetos Android criados no estúdio andróide têm dois arquivos 'buil.gradle'. Estamos interessados no aplicativo nível build.gradle.

Adicione o seguinte código sob a seção dependências:

        implementation 'com.android.support:appcompat-v7:24.2.1'
        implementation 'com.android.support:design:24.2.1'

Acrescentamos duas dependências da biblioteca de apoio: AppCompat e design.

Passo 3. Vamos preparar nossos recursos.

O único recurso que precisamos preparar neste caso são os layouts. Eu escolhi a atividade básica como meu modelo. Portanto, eu tenho dois layouts:

  • activity_main.xm : modelo de layout
  • content_main.xml : isto que modificamos.

Tudo o que preciso é adicionar um texto de edição e um botão. O texto de edição onde o usuário entrará o tempo em segundos e o botão de início para iniciar o alarme.

     <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout

        android_layout_width="match_parent"
        android_layout_height="match_parent"
        android_paddingBottom="@dimen/activity_vertical_margin"
        android_paddingLeft="@dimen/activity_horizontal_margin"
        android_paddingRight="@dimen/activity_horizontal_margin"
        android_paddingTop="@dimen/activity_vertical_margin"
        app_layout_behavior="@string/appbar_scrolling_view_behavior"
        tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
        tools_showIn="@layout/activity_main">

        <EditText
            android_id="@+id/timeTxt"
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_layout_alignParentLeft="true"
            android_layout_alignParentTop="true"
            android_layout_marginTop="28dp"
            android_ems="10"
            android_hint="Number of seconds"
            android_inputType="numberDecimal" />

        <Button
            android_id="@+id/startBtn"
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_layout_alignRight="@+id/timeTxt"
            android_layout_below="@+id/timeTxt"
            android_layout_marginRight="60dp"
            android_layout_marginTop="120dp"
            android_text="Start" />
    </RelativeLayout>

Passo 4. Vamos criar nossa classe BroadcastReceiver.

Um 'BroadcastReceiver' é um dos componentes do andróide. Outros incluem Atividade, Serviço e ContentProvider.
Um BroadcastReceiver ouve os eventos do sistema.

Na verdade é uma classe abstrata que é obviamente pública. Ela deriva da forma java.lang.Object :

    public abstract class BroadcastReceiver extends Object{}

As intenções enviadas pelo sendBroadcast() serão recebidas por esta classe base.

Trata-se de uma classe abstrata, portanto, vamos anular o método onReceive().

Primeiro crie uma classe java :

    public class MyReceiver{}

Acrescente as importações dobráveis:

    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.widget.Toast;

Fazê-la derivar de android.content.BroadcastReceiver:

    public class MyReceiver extends BroadcastReceiver {}

Isto nos forçará a ultrapassar o método onReceive():

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
        }

Passo 5. Vamos à nossa classe MainActivity.

As atividades são componentes andróides que representam uma interface de usuário. Nós criamos atividades derivando de uma atividade. Para suportar mais dispositivos, utilizamos o `AppCompatActivity'.

Portanto, vamos criar uma atividade:

    public class MainActivity extends AppCompatActivity {}

Acrescente as seguintes importações em cima da atividade:

    import android.app.AlarmManager;
    import android.app.PendingIntent;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.design.widget.FloatingActionButton;
    import android.support.design.widget.Snackbar;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;

Nossa atividade terá três métodos e dois campos:

Primeiro definimos nossos dois campos: basicamente um botão e um texto de edição. Adicioná-los dentro da classe `MainActivity':

        Button startBtn;
        EditText timeTxt;

Então criamos um método go(). Este método será responsável por inicializar nosso AlarmManager e iniciar o alarme:

        private void go()
        {
            //GET TIME IN SECONDS AND INITIALIZE INTENT
            int time=Integer.parseInt(timeTxt.getText().toString());
            Intent i=new Intent(this,MyReceiver.class);

            //PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
            PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);

            //INITIALIZE ALARM MANAGER
            AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);

            //SET THE ALARM
            alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
            Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
        }

Então viemos criar outro método para inicializar nosso botão e editar o texto e lidar com o ouvinte do botão:

        private void initializeViews()
        {
            timeTxt= (EditText) findViewById(R.id.timeTxt);
            startBtn= (Button) findViewById(R.id.startBtn);

            startBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                   go();
                }
            });
        }

Passo 6. Vamos checar o "AndroidManifest".

Passe por cima do 'androidmanifest.xml'. Queremos garantir que nossa classe BroadcastReceiver esteja registrada dentro de nosso manifesto.

Você pode ver que nossa classe broadcastreceiver está registrada:

            <receiver android_name="MyReceiver" >
            </receiver>

Eis o que eu tenho:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
        package="com.tutorials.hp.alarmmanagerstarter">
        <application
            android_allowBackup="true"
            android_icon="@mipmap/ic_launcher"
            android_label="@string/app_name"
            android_supportsRtl="true"
            android_theme="@style/AppTheme">
            <activity
                android_name=".MainActivity"
                android_label="@string/app_name"
                android_theme="@style/AppTheme.NoActionBar">
                <intent-filter>
                    <action android_name="android.intent.action.MAIN" />

                    <category android_name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <receiver android_name="MyReceiver" >
            </receiver>
        </application>

    </manifest>

Exemplo: Android AlarmManager - Exibição de calendário de Toast.

Os engenheiros Android adicionaram a classe 'AlarmManager' na API nível 1, por isso, ela existe desde o início do andróide. Esta classe permite que o agendamento de operações seja feito em algum momento no futuro. Com o 'AlarmManager', você pode definir algum código que será executado no futuro.

Isto é legal, já que não é necessário que seu aplicativo esteja sendo executado para que esse código seja executado. É claro que seu aplicativo será iniciado, mas somente no momento do registro. Alarm Maanager pertence ao pacote android.app e herda do java.lang.Object.

Mesmo enquanto o dispositivo estiver dormindo, os alarmes são retidos enquanto eles estiverem registrados. Você pode encontrar mais detalhes sobre o AlarmManager aqui.

Screenshot
  • Aqui está a captura de tela do projeto.

Perguntas comuns que este exemplo explora

  • Como utilizar o andróide AlarmManager.
  • O que é o AlarmManager?
  • Como programar o trabalho a ser feito no futuro no andróide?
  • Exemplo fácil de "AlarmManager" com um "Toast".

*Ferramentas utilizadas

Este exemplo foi escrito com as seguintes ferramentas:

  • Windows 8
  • AndroidStudio IDE
  • Emulador Genymotion

Código fonte

Vamos pular diretamente para o código fonte.

Build.Gradle

  • Normalmente em projetos de andróides, existem dois arquivos build.gradle'. Um é o nível de aplicativo build.gradle, o outro é o nível de projeto build.gradle`. O nível app pertence dentro da pasta app e é onde normalmente adicionamos nossas dependências e especificamos a compilação e os sdks alvo.
  • Também adicionamos dependências para as bibliotecas de suporte AppCompat e Design.
  • Nossa MainActivity' deve derivar de AppCompatActivity' enquanto que também utilizaremos `FloatingActionButton' de bibliotecas de suporte a projetos.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "25.0.1"

    defaultConfig {
        applicationId "com.tutorials.hp.alarmmanagerstarter"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:24.2.1'
    implementation 'com.android.support:design:24.2.1'
}

MyReceiver.java"

  • Nossa classe Broadcast Receiver.
  • Faça-o estender o conteúdo android.app.content.BroadCastReceiver.
  • Substituímos então o método OnReceive(). É aqui que escrevemos o código a ser executado quando o alarme toca.
  • Neste caso, simplesmente exibimos uma mensagem 'Toast'.

package com.tutorials.hp.alarmmanagerstarter;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {

    /*
    RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
    }
}

MainActivity.java

  • Atividade do lançador.
  • 'ActivityMain.xml' inflacionado como a visão do conteúdo para esta atividade.
  • Inicializamos visões e widgets dentro desta atividade.
  • Também inicializamos e iniciamos nosso alarme aqui dentro utilizando o objeto 'AlarmManager'.

package com.tutorials.hp.alarmmanagerstarter;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button startBtn;
    EditText timeTxt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

         initializeViews();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

    }

    /*
    INITIALIZE VIEWS
     */
    private void initializeViews()
    {
        timeTxt= (EditText) findViewById(R.id.timeTxt);
        startBtn= (Button) findViewById(R.id.startBtn);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               go();
            }
        });
    }

    /*
    INITIALIZE AND START OUR ALARM
     */
    private void go()
    {
        //GET TIME IN SECONDS AND INITIALIZE INTENT
        int time=Integer.parseInt(timeTxt.getText().toString());
        Intent i=new Intent(this,MyReceiver.class);

        //PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
        PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);

        //INITIALIZE ALARM MANAGER
        AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);

        //SET THE ALARM
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
        Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
    }

}

ActivityMain.xml

  • Layout do modelo.
  • Contém nosso ContentMain.xml.
  • Também define o appbarlayout, a barra de ferramentas, bem como o buttton de ação flutuante.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_fitsSystemWindows="true"
    tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity">

    <android.support.design.widget.AppBarLayout
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android_id="@+id/toolbar"
            android_layout_width="match_parent"
            android_layout_height="?attr/actionBarSize"
            android_background="?attr/colorPrimary"
            app_popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_gravity="bottom|end"
        android_layout_margin="@dimen/fab_margin"
        android_src="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

ContentMain.xml

  • Layout do conteúdo.
  • Define as vistas e widgets a serem exibidos dentro da `MainActivity'.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    android_paddingBottom="@dimen/activity_vertical_margin"
    android_paddingLeft="@dimen/activity_horizontal_margin"
    android_paddingRight="@dimen/activity_horizontal_margin"
    android_paddingTop="@dimen/activity_vertical_margin"
    app_layout_behavior="@string/appbar_scrolling_view_behavior"
    tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
    tools_showIn="@layout/activity_main">

    <EditText
        android_id="@+id/timeTxt"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_alignParentLeft="true"
        android_layout_alignParentTop="true"
        android_layout_marginTop="28dp"
        android_ems="10"
        android_hint="Number of seconds"
        android_inputType="numberDecimal" />

    <Button
        android_id="@+id/startBtn"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_alignRight="@+id/timeTxt"
        android_layout_below="@+id/timeTxt"
        android_layout_marginRight="60dp"
        android_layout_marginTop="120dp"
        android_text="Start" />
</RelativeLayout>

Como Funcionar

  1. Faça o download do projeto acima.
  2. Você receberá um arquivo zipado, extraia-o.
  3. Abra o Estúdio Android.
  4. Agora feche, projeto já aberto.
  5. Na barra de menu, clique em Arquivo >Novo> Importar Projeto.
  6. Agora escolha uma pasta de destino, de onde você quer importar o projeto.
  7. Escolha um Projeto Android.
  8. Agora clique em "OK".
  9. Feito, você acabou de importar o projeto, agora edite-o.

Conclusão.

Vimos um exemplo simples de andróide AlarmManager.

Exemplo: Alarmes de repetição/reincidência do calendário do Android

O 'AlarmManager' existe desde o início do Android. Ele nos permite programar tarefas para serem feitas em algum momento no futuro.

Com o 'AlarmManager', você pode definir algum código que será executado no futuro.

O AlarmManager pertence ao pacote 'android.app' e herda do 'java.lang.Object'. Mesmo enquanto o dispositivo estiver adormecido, os alarmes são retidos enquanto estiverem registrados. Neste exemplo, veremos como trabalhar com um Alarme recorrente/repetitivo.

Programaremos a exibição das mensagens 'Toast' após um determinado número de segundos. Por exemplo, o usuário entra 5 nos "textos de edição" e clica no botão de início, após cada 5 segundos a mensagem "Brinde" é mostrada até que o usuário clica no botão de cancelamento para cancelar os alarmes. Assim, vemos como começar a repetir os alarmes e cancelá-los. Você pode encontrar mais detalhes sobre o AlarmManager aqui.

Perguntas comuns que este exemplo explora

  • Como utilizar o andróide AlarmManager.
  • Como definir alarmes repetitivos/recorrentes no andróide e cancelá-los.
  • Como iniciar e cancelar alarmes no andróide.
  • Como programar o trabalho a ser feito no futuro no andróide?
  • Exemplo fácil e recorrente de "AlarmManager" com um "Toast".

*Ferramentas utilizadas

Este exemplo foi escrito com as seguintes ferramentas:

  • Windows 8
  • AndroidStudio IDE
  • Emulador Genymotion
  • Linguagem : Java
  • Tópico : Alarmes recorrentes Android, 'AlarmManager', Iniciar Cancelamento de repetição de alarmes

Liberação utilizada

  • Não utilizamos nenhuma biblioteca de terceira parte.
  • Código fonte

Vamos pular diretamente para o código fonte.

Build.Gradle

Normalmente em projetos de andróides, existem dois arquivos "build.gradle". Um é o nível de aplicativo build.gradle, o outro é o nível de projeto build.gradle. O nível app pertence dentro da pasta app e é onde normalmente adicionamos nossas dependências e especificamos a compilação e os sdks alvo.

Também adicionamos dependências para as bibliotecas de suporte AppCompat e Design.
Nossa MainActivity' deve derivar de AppCompatActivity' enquanto que também utilizaremos `FloatingActionButton' de bibliotecas de suporte a projetos.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"
    defaultConfig {
        applicationId "com.tutorials.hp.repeatingalarm"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidtestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation 'com.android.support:appcompat-v7:26.+'
    implementation 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
    implementation 'com.android.support:design:26.+'
    testImplementation 'junit:junit:4.12'
}

MeuReceptor.java

  • Nossa classe MeuReceptor.
  • Deriva de android.content.BroadcastReceiver.
  • Substituímos o método onReceive() e executamos a tarefa a ser feita quando o alarme toca aqui.

package com.tutorials.hp.repeatingalarm;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
    /*
   RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
    */
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
    }
}

MainActivity.java

  • Nossa classe MainActivity.
  • Deriva de `AppCompatActivity' que é uma classe Base para atividades que utilizam os recursos da barra de ação da biblioteca de suporte.
  • Métodos: onCreate(),initializeViews(),initializeAlarmManager(),go().
  • Inflado de activity_main.xml utilizando o método setContentView().
  • As visualizações que utilizamos são EditTexts' e buttons'.
  • Consulte-os a partir de nossa especificação de layout utilizando findViewById().
  • Inicializar o `AlarmManager'.
  • Iniciar o alarme utilizando o setInExactRepeating().

package com.tutorials.hp.repeatingalarm;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button startBtn,cancelBtn;
    EditText timeTxt;
    AlarmManager alarmManager;
    PendingIntent pi;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

     initializeViews();
     initializeAlarmManager();

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                go();
            }
        });

    }

    /*
    INITIALIZE VIEWS
     */
    private void initializeViews()
    {
        timeTxt= (EditText) findViewById(R.id.timeTxt);
        startBtn= (Button) findViewById(R.id.startBtn);
        cancelBtn= (Button) findViewById(R.id.cancelBtn);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                go();
            }
        });
        cancelBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(alarmManager != null)
                {
                    alarmManager.cancel(pi);
                }
            }
        });
    }
  /*
  INITIALIZE AND START OUR ALARM
  */
  private void initializeAlarmManager()
  {
    // INITIALIZE INTENT
    Intent intent=new Intent(this,MyReceiver.class);

        //PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
        pi= PendingIntent.getBroadcast(this,0,intent,0);

        //INITIALIZE ALARM MANAGER
        alarmManager= (AlarmManager) this.getSystemService(ALARM_SERVICE);
  }

    /*
    START OUR ALARM
     */
    private void go()
    {
        //GET TIME IN SECONDS
        int time=Integer.parseInt(timeTxt.getText().toString());

        //SET THE ALARM
       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+(time*1000),time*1000,pi);
            Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();

        }else
        {
            alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,System.currentTimeMillis()+(time*1000),time*1000,pi);
            Toast.makeText(MainActivity.this, "Yes Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();

        }
    }

}

ActivityMain.xml

Este é um modelo de layout para nossa MainActivity. Nossa etiqueta de layout Raiz é "CoordinatorLayout". O "CoordinatorLayout" é um grupo de visão que é superpoderoso no framelayout.

  • O "CoordinatorLayout" é destinado a dois casos de uso primário: Como uma decoração de aplicação de nível superior ou disposição cromada Como um recipiente para uma interação específica com uma ou mais vistas de crianças
  • Dentro de nosso 'CoordinatorLayout' adicionamos: 'AppBarLayout', FloatingActionButton e incluímos `content_main.xml'.
  • O AppBarLayout é um LinearLayout vertical que implementa características de rolagem do conceito de design do material.
  • Deve ser um filho direto do 'CoordinatorLayout', caso contrário, muitas características não funcionarão.
  • Dentro do AppBarLayout adicionamos nossa toolbar, que damos uma cor azul.
  • Acrescentaremos nossos widgets em nosso content_main.xml, não aqui, pois este é um modelo de layout.
  • Finalmente temos um FloatingActionButton, uma classe que deriva de android.support.design.widget.VisibilityAwareImageButton. É o botão redondo que você vê em nossa interface de usuário.

<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    tools_context="com.tutorials.hp.repeatingalarm.MainActivity">

    <android.support.design.widget.AppBarLayout
        android_layout_width="match_parent"
        android_layout_height="wrap_content"
        android_theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android_id="@+id/toolbar"
            android_layout_width="match_parent"
            android_layout_height="?attr/actionBarSize"
            android_background="?attr/colorPrimary"
            app_popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />

    <android.support.design.widget.FloatingActionButton
        android_id="@+id/fab"
        android_layout_width="wrap_content"
        android_layout_height="wrap_content"
        android_layout_gravity="bottom|end"
        android_layout_margin="@dimen/fab_margin"
        app_srcCompat="@android:drawable/ic_dialog_email" />

</android.support.design.widget.CoordinatorLayout>

ContentMain.xml

  • Nosso arquivo ContentMain.xml.
  • Deverá ser inflado para `MainActivity'.
  • Root tag é `ConstraintLayout'.
  • Contém `EditTexts' e dois botões.
  • O usuário digitará o número de segundos após os quais o alarme soará no texto de edição.
  • Em seguida, clique no botão start para iniciar o alarme.
  • E botão Cancelar para cancelar o alarme.

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout

    android_layout_width="match_parent"
    android_layout_height="match_parent"
    app_layout_behavior="@string/appbar_scrolling_view_behavior"
    tools_context="com.tutorials.hp.repeatingalarm.MainActivity"
    tools_showIn="@layout/activity_main">

    <LinearLayout
        android_layout_width="368dp"
        android_layout_height="327dp"
        android_orientation="vertical"
        app_layout_constraintTop_toTopOf="parent"
        android_layout_marginTop="8dp">
        <EditText
            android_id="@+id/timeTxt"
            android_layout_width="wrap_content"
            android_layout_height="wrap_content"
            android_layout_alignParentLeft="true"
            android_layout_alignParentTop="true"
            android_ems="10"
            android_hint="Number of seconds"
            android_inputType="numberDecimal"
            />

        <Button
            android_id="@+id/startBtn"
            android_layout_width="match_parent"
            android_layout_height="wrap_content"
            android_layout_alignRight="@+id/timeTxt"
            android_layout_below="@+id/timeTxt"
            android_text="Start"
            />
        <Button
            android_id="@+id/cancelBtn"
            android_layout_width="match_parent"
            android_layout_height="wrap_content"
            android_layout_alignRight="@+id/timeTxt"
            android_layout_below="@+id/timeTxt"
            android_text="Cancel"
            />

    </LinearLayout>

</android.support.constraint.ConstraintLayout>

Vídeo/Previsão

  • Temos um canal YouTube com quase mil tutoriais, sendo este abaixo um deles.

https://www.youtube.com/watch?v=23Gw-11JFqc

Download

  • Você pode baixar o projeto completo abaixo. O código fonte é bem comentado.

Download

Categorized in: