Je souhaite notifier mon application à une heure précise. Dites tous les jours que je dois donner une notification à 7 heures du matin, même si l'application est fermée.
Comment puis-je faire ceci? Un tutoriel? Merci de mentionner le lien.
vous devez d'abord utiliser un récepteur large bande. et parce qu'un récepteur de diffusion ne fonctionne que pendant une courte période
à partir du Android blog du développeur. Lors du traitement d'une diffusion, l'application dispose d'un délai fixe (actuellement de 10 secondes) pour effectuer son travail. Si elle ne se termine pas dans ce délai , l'application est considérée comme se comportant mal, et son processus est immédiatement jeté dans l'état d'arrière-plan pour être supprimé pour la mémoire si nécessaire.
c'est une meilleure pratique d'utiliser également un service intentionnel ici, vous avez un exemple comment le faire.
c'est la classe des récepteurs de diffusion.
public class MyReceiver extends BroadcastReceiver {
public MyReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
Intent intent1 = new Intent(context, MyNewIntentService.class);
context.startService(intent1);
}
}
et l'enregistrer dans le manifeste.
<receiver
Android:name=".MyReceiver"
Android:enabled="true"
Android:exported="false" >
</receiver>
c'est la classe de service intentionnelle.
public class MyNewIntentService extends IntentService {
private static final int NOTIFICATION_ID = 3;
public MyNewIntentService() {
super("MyNewIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle("My Title");
builder.setContentText("This is the Body");
builder.setSmallIcon(R.drawable.whatever);
Intent notifyIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 2, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//to be able to launch your activity from the notification
builder.setContentIntent(pendingIntent);
Notification notificationCompat = builder.build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
}
}
et l'enregistrer dans le manifeste.
<service
Android:name=".MyNewIntentService"
Android:exported="false" >
</service>
puis dans votre activité, réglez le gestionnaire d'alarmes pour démarrer le récepteur de diffusion à une heure spécifique et utilisez la méthode setRepeating AlarmManager pour le répéter, cet exemple ci-dessous le répétera tous les jours.
Intent notifyIntent = new Intent(this,MyReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast
(context, NOTIFICATION_REMINDER_NIGHT, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
1000 * 60 * 60 * 24, pendingIntent);
j'espère que cela t'aidera.
Une solution de la réponse acceptée ne fonctionnera pas correctement sur Android 8 Oreo (api niveau 26) et supérieur en raison des limites de service en arrière-plan ( https : //developer.Android.com/about/versions/oreo/background.html#services ) et provoquera une exception comme celle-ci lorsque l'application est en arrière-plan:
Java.lang.IllegalStateException: Not allowed to start service Intent xxx: app is in background
L'une des solutions possibles consiste à utiliser JobIntentService
:
étendez votre Service
à partir de JobIntentService
au lieu de IntentService
et utilisez la méthode onHandleWork
au lieu de onHandleIntent
.
ajouter Android:permission="Android.permission.BIND_JOB_SERVICE"
à votre Service
dans AndroidManifest.xml
.
Vous pouvez utiliser AlarmManager
pour régler l'alarme à une heure spécifiée
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if (!prefs.getBoolean("firstTime", false)) {
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.apply();
}
J'ai utilisé SharedPreferences
pour vérifier que ce n'est pas la première fois que vous exécutez l'application et si c'est le cas, vous définissez cette alarme sinon ne faites rien au lieu de réinitialiser l'alarme chaque fois que vous démarrez votre application.
Utilisez un BroadcastReceiver
pour écouter quand l'alarme se produit
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// show toast
Toast.makeText(context, "Alarm running", Toast.LENGTH_SHORT).show();
}
}
Utilisez un autre récepteur pour écouter le démarrage de l'appareil afin de pouvoir réinitialiser l'alarme
public class DeviceBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("Android.intent.action.BOOT_COMPLETED")) {
// on device boot compelete, reset the alarm
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 7);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 1);
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
}
ajouter l'autorisation au manifeste
<uses-permission Android:name="Android.permission.WAKE_LOCK" />
<uses-permission Android:name="Android.permission.RECEIVE_BOOT_COMPLETED" />
puis enregistrez vos récepteurs
<receiver Android:name=".DeviceBootReceiver">
<intent-filter>
<action Android:name="Android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver Android:name=".AlarmReceiver" />
Exemple de code pour le même:
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = new Intent(context of current file, AlarmReceiver1.class);
AlarmReceiver1 = broadcast receiver
pendingIntent = PendingIntent.getBroadcast( Menu.this, 0, alarmIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmIntent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
alarmManager.cancel(pendingIntent);
Calendar alarmStartTime = Calendar.getInstance();
Calendar now = Calendar.getInstance();
alarmStartTime.set(Calendar.HOUR_OF_DAY, 8);
alarmStartTime.set(Calendar.MINUTE, 00);
alarmStartTime.set(Calendar.SECOND, 0);
if (now.after(alarmStartTime)) {
Log.d("Hey","Added a day");
alarmStartTime.add(Calendar.DATE, 1);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
alarmStartTime.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Log.d("Alarm","Alarms set for everyday 8 am.");
Venir à la classe de récepteur de diffusion. Vous devez enregistrer votre récepteur de diffusion dans le manifeste. Cela vous fera recevoir des événements d'horloge. Remplacez la méthode onReceive de ce récepteur de diffusion et faites-y une notification lui-même ou effectuez un service de création de notification distinct et créez et affichez votre notification là-bas.
L'extrait de code manifeste:
L'extrait de code du récepteur de diffusion:
public class AlarmReceiver1 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent service1 = new Intent(context, NotificationService1.class);
service1.setData((Uri.parse("custom://"+System.currentTimeMillis())));
context.startService(service1);
}
Extrait de code du service de création de notifications:
public class NotificationService1 extends IntentService{
private NotificationManager notificationManager;
private PendingIntent pendingIntent;
private static int NOTIFICATION_ID = 1;
Notification notification;
@Override
protected void onHandleIntent(Intent intent) {
Context context = this.getApplicationContext();
notificationManager =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, Activity to be opened after clicking on the
notif);
Bundle bundle = new Bundle();
bundle.putString("test", "test");
mIntent.putExtras(bundle);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Resources res = this.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
notification = new NotificationCompat.Builder(this)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
.setTicker("ticker value")
.setAutoCancel(true)
.setPriority(8)
.setSound(soundUri)
.setContentTitle("Notif title")
.setContentText("Text").build();
notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE;
notification.ledARGB = 0xFFFFA500;
notification.ledOnMS = 800;
notification.ledOffMS = 1000;
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, notification);
Log.i("notif","Notifications sent.");
}
}