Exemple de gestionnaire d’alarmes

Je veux implémenter une fonction de planification dans mon projet. J’ai donc cherché sur Google un programme de gestion des alarmes, mais je ne trouve aucun exemple.

Quelqu’un peut-il m’aider avec un programme de base de gestion des alarmes?

C’est du code de travail. Il réveille le processeur toutes les 10 minutes jusqu’à ce que le téléphone s’éteigne.

Ajouter à Manifest.xml:

...  ...  ... 

Code dans votre classe:

 package yourPackage; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.PowerManager; import android.widget.Toast; public class Alarm extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ""); wl.acquire(); // Put here YOUR code. Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example wl.release(); } public void setAlarm(Context context) { AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE); Intent i = new Intent(context, Alarm.class); PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0); am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pi); // Millisec * Second * Minute } public void cancelAlarm(Context context) { Intent intent = new Intent(context, Alarm.class); PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); alarmManager.cancel(sender); } } 

Définir l’alarme du service:

 package yourPackage; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; public class YourService extends Service { Alarm alarm = new Alarm(); public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { alarm.setAlarm(this); return START_STICKY; } @Override public void onStart(Intent intent, int startId) { alarm.setAlarm(this); } @Override public IBinder onBind(Intent intent) { return null; } } 

Si vous voulez que l’alarme se répète au démarrage du téléphone:

Ajoutez la permission et le service à Manifest.xml:

  ...      ...   

Et créer une nouvelle classe:

 package yourPackage; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class AutoStart extends BroadcastReceiver { Alarm alarm = new Alarm(); @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { alarm.setAlarm(context); } } } 

J’ai essayé la solution de XXX et, au début, elle a cessé de fonctionner. Le onReceive n’a jamais été appelé à nouveau. J’ai passé des heures à essayer de comprendre ce que cela pouvait être. Ce que j’ai compris, c’est que l’ Intent pour quelque raison mystérieuse n’était plus appelée. Pour contourner cela, j’ai découvert que vous devez vraiment spécifier une action pour le récepteur dans le manifeste. Exemple:

       

Notez que le nom est ".Alarm" avec le point. Dans la méthode setAlarm de XXX, créez l’ Intent comme suit:

 Intent i = new Intent("mypackage.START_ALARM"); 

Le message START_ALARM peut être ce que vous voulez qu’il soit. Je viens de lui donner ce nom à des fins de démonstration.

Je n’ai pas vu de récepteurs définis dans le manifeste sans filtre d’intention qui spécifie l’action. En les créant comme l’a spécifié XXX, cela semble un peu faux. En spécifiant le nom de l’action, Android sera obligé de créer une instance du BroadcastReceiver utilisant la classe qui correspond à l’action. Si vous vous fiez au contexte, sachez qu’Android possède plusieurs objects différents qui sont tous appelés contexte et peuvent ne pas aboutir à la création de votre BroadcastReceiver . Forcer Android à créer une instance de votre classe en utilisant uniquement le message d’action est bien mieux que de s’appuyer sur un contexte difficile qui pourrait ne jamais fonctionner.

Voici un exemple assez autonome. Il fait clignoter un bouton après 5 secondes.

  public void SetAlarm() { final Button button = buttons[2]; // replace with a button from your own UI BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive( Context context, Intent _ ) { button.setBackgroundColor( Color.RED ); context.unregisterReceiver( this ); // this == BroadcastReceiver, not Activity } }; this.registerReceiver( receiver, new IntentFilter("com.blah.blah.somemessage") ); PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("com.blah.blah.somemessage"), 0 ); AlarmManager manager = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE )); // set alarm to fire 5 sec (1000*5) from now (SystemClock.elapsedRealtime()) manager.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*5, pintent ); } 

N’oubliez pas que le AlarmManager se déclenche même lorsque votre application n’est pas en cours d’exécution. Si vous appelez cette fonction et appuyez sur le bouton Accueil, attendez 5 secondes, puis revenez dans votre application, le bouton sera rouge.

Je ne sais pas quel genre de comportement vous auriez si votre application n’était pas en mémoire, alors faites attention à quel type d’état vous essayez de préserver.

MainActivity.java

 package com.example.alarmexample; import android.app.Activity; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity extends Activity { Button b1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startAlert(); } public void startAlert() { int timeInSec = 2; Intent intent = new Intent(this, MyBroadcastReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast( this.getApplicationContext(), 234, intent, 0); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (timeInSec * 1000), pendingIntent); Toast.makeText(this, "Alarm set to after " + i + " seconds",Toast.LENGTH_LONG).show(); } } 

MyBroadcastReceiver.java

 package com.example.alarmexample; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.widget.Toast; public class MyBroadcastReceiver extends BroadcastReceiver { MediaPlayer mp; @Override public void onReceive(Context context, Intent intent) { mp=MediaPlayer.create(context, R.raw.alarm); mp.start(); Toast.makeText(context, "Alarm", Toast.LENGTH_LONG).show(); } } 

AndroidManifest.xml

               

Ce code vous aidera à faire une alarme répétitive. Le temps de répétition peut être défini par vous.

activity_main.xml

              

MainActivity.java

 public class MainActivity extends Activity { int hr = 0; int min = 0; int sec = 0; int result = 1; AlarmManager alarmManager; PendingIntent pendingIntent; BroadcastReceiver mReceiver; EditText ethr; EditText etmin; EditText etsec; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ethr = (EditText) findViewById(R.id.ethr); etmin = (EditText) findViewById(R.id.etmin); etsec = (EditText) findViewById(R.id.etsec); RegisterAlarmBroadcast(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override protected void onDestroy() { unregisterReceiver(mReceiver); super.onDestroy(); } public void onClickSetAlarm(View v) { Ssortingng shr = ethr.getText().toSsortingng(); Ssortingng smin = etmin.getText().toSsortingng(); Ssortingng ssec = etsec.getText().toSsortingng(); if(shr.equals("")) hr = 0; else { hr = Integer.parseInt(ethr.getText().toSsortingng()); hr=hr*60*60*1000; } if(smin.equals("")) min = 0; else { min = Integer.parseInt(etmin.getText().toSsortingng()); min = min*60*1000; } if(ssec.equals("")) sec = 0; else { sec = Integer.parseInt(etsec.getText().toSsortingng()); sec = sec * 1000; } result = hr+min+sec; alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), result , pendingIntent); } private void RegisterAlarmBroadcast() { mReceiver = new BroadcastReceiver() { // private static final Ssortingng TAG = "Alarm Example Receiver"; @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "Alarm time has been reached", Toast.LENGTH_LONG).show(); } }; registerReceiver(mReceiver, new IntentFilter("sample")); pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent("sample"), 0); alarmManager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE)); } private void UnregisterAlarmBroadcast() { alarmManager.cancel(pendingIntent); getBaseContext().unregisterReceiver(mReceiver); } } 

Si vous n’avez besoin d’alarme que pour une seule fois, remplacez

 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), result , pendingIntent); 

avec

  alarmManager.set( AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + result , pendingIntent ); 

J’ai fait ma propre implémentation pour le faire de la manière la plus simple possible.

 import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import junit.framework.Assert; /** * Created by Daniel on 28/08/2016. */ public abstract class AbstractSystemServiceTask { private final Context context; private final AlarmManager alarmManager; private final BroadcastReceiver broadcastReceiver; private final PendingIntent pendingIntent; public AbstractSystemServiceTask(final Context context, final Ssortingng id, final long time, final AlarmType alarmType, final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("ApplicationContext can't be null", context); Assert.assertNotNull("ID can't be null", id); this.context = context; this.alarmManager = (AlarmManager) this.context.getSystemService(Context.ALARM_SERVICE); this.context.registerReceiver( this.broadcastReceiver = this.getBroadcastReceiver(backgroundTaskListener), new IntentFilter(id)); this.configAlarmManager( this.pendingIntent = PendingIntent.getBroadcast(this.context, 0, new Intent(id), 0), time, alarmType); } public void stop() { this.alarmManager.cancel(this.pendingIntent); this.context.unregisterReceiver(this.broadcastReceiver); } private BroadcastReceiver getBroadcastReceiver(final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("BackgroundTaskListener can't be null.", backgroundTaskListener); return new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { backgroundTaskListener.perform(context, intent); } }; } private void configAlarmManager(final PendingIntent pendingIntent, final long time, final AlarmType alarmType) { long ensurePositiveTime = Math.max(time, 0L); switch (alarmType) { case REPEAT: this.alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ensurePositiveTime, pendingIntent); break; case ONE_TIME: default: this.alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ensurePositiveTime, pendingIntent); } } public interface BackgroundTaskListener { void perform(Context context, Intent intent); } public enum AlarmType { REPEAT, ONE_TIME; } } 

La seule étape suivante, implémentez-le.

 import android.content.Context; import android.content.Intent; import android.util.Log; import ...AbstractSystemServiceTask; import java.util.concurrent.TimeUnit; /** * Created by Daniel on 28/08/2016. */ public class UpdateInfoSystemServiceTask extends AbstractSystemServiceTask { private final static Ssortingng ID = "UPDATE_INFO_SYSTEM_SERVICE"; private final static long REPEAT_TIME = TimeUnit.SECONDS.toMillis(10); private final static AlarmType ALARM_TYPE = AlarmType.REPEAT; public UpdateInfoSystemServiceTask(Context context) { super(context, ID, REPEAT_TIME, ALARM_TYPE, new BackgroundTaskListener() { @Override public void perform(Context context, Intent intent) { Log.i("MyAppLog", "-----> UpdateInfoSystemServiceTask"); //DO HERE WHATEVER YOU WANT... } }); Log.i("MyAppLog", "UpdateInfoSystemServiceTask started."); } } 

J’aime travailler avec cette implémentation, mais une autre bonne façon possible, ce n’est pas de rendre la classe AbstractSystemServiceTask abstraite et de la construire via un Builder.

J’espère que cela vous aidera.

MISE À JOUR Améliorée pour autoriser plusieurs BackgroundTaskListener sur le même BroadCastReceiver .

 import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import junit.framework.Assert; import java.util.HashSet; import java.util.Set; /** * Created by Daniel on 28/08/2016. */ public abstract class AbstractSystemServiceTask { private final Context context; private final AlarmManager alarmManager; private final BroadcastReceiver broadcastReceiver; private final PendingIntent pendingIntent; private final Set backgroundTaskListenerSet; public AbstractSystemServiceTask(final Context context, final Ssortingng id, final long time, final AlarmType alarmType) { Assert.assertNotNull("ApplicationContext can't be null", context); Assert.assertNotNull("ID can't be null", id); this.backgroundTaskListenerSet = new HashSet<>(); this.context = context; this.alarmManager = (AlarmManager) this.context.getSystemService(Context.ALARM_SERVICE); this.context.registerReceiver( this.broadcastReceiver = this.getBroadcastReceiver(), new IntentFilter(id)); this.configAlarmManager( this.pendingIntent = PendingIntent.getBroadcast(this.context, 0, new Intent(id), 0), time, alarmType); } public synchronized void registerTask(final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("BackgroundTaskListener can't be null", backgroundTaskListener); this.backgroundTaskListenerSet.add(backgroundTaskListener); } public synchronized void removeTask(final BackgroundTaskListener backgroundTaskListener) { Assert.assertNotNull("BackgroundTaskListener can't be null", backgroundTaskListener); this.backgroundTaskListenerSet.remove(backgroundTaskListener); } public void stop() { this.backgroundTaskListenerSet.clear(); this.alarmManager.cancel(this.pendingIntent); this.context.unregisterReceiver(this.broadcastReceiver); } private BroadcastReceiver getBroadcastReceiver() { return new BroadcastReceiver() { @Override public void onReceive(final Context context, final Intent intent) { for (BackgroundTaskListener backgroundTaskListener : AbstractSystemServiceTask.this.backgroundTaskListenerSet) { backgroundTaskListener.perform(context, intent); } } }; } private void configAlarmManager(final PendingIntent pendingIntent, final long time, final AlarmType alarmType) { long ensurePositiveTime = Math.max(time, 0L); switch (alarmType) { case REPEAT: this.alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ensurePositiveTime, pendingIntent); break; case ONE_TIME: default: this.alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + ensurePositiveTime, pendingIntent); } } public interface BackgroundTaskListener { void perform(Context context, Intent intent); } public enum AlarmType { REPEAT, ONE_TIME; } }