Точное время для пользовательских уведомлений в Android
Я разрабатываю приложение для Android для консультирования. Клиент может просмотреть свою запланированную встречу в приложении. Например,
Следующая встреча: 31 декабря 2016 года 10: 00 утра
Теперь мне нужно сделать так, чтобы пользователь получил 2 уведомления-напоминания о встрече. Один на 7 дней раньше, а другой на 3 дня раньше. Я сохраняю эту дату (31 декабря 2016 г. 10: 00) как String
, чтобы извлечь год, месяц и т. д.
Я обнаружил, что мне нужно написать какой-то сервис, который будет отправлять это уведомление. Это то, что я пытался (не завершено):
public class NotificationService extends Service {
@Override
public void onCreate() {
Intent resultIntent=new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, resultIntent, 0);
Notification nBuilder = new Notification.Builder(this)
.setContentTitle("Don't miss! ")
.setTicker("Notification!")
.setContentIntent(pIntent)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setSmallIcon(R.drawable.my_logo)
.setContentText("7 days left till your appointment...")
//.setWhen(System.currentTimeMillis())
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nBuilder.flags |=Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1,nBuilder);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
И метод, который я не знаю, откуда вызвать:
public void reminder() {
Intent intent = new Intent(getActivity(), MainActivity.class);
AlarmManager manager =(AlarmManager) getActivity().getSystemService(Activity.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(getActivity().getApplicationContext(),
0,intent, 0);
Calendar cal=Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 8);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
manager.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),24*60*60*1000,pendingIntent);
}
Для целей тестирования я установил час/минуту/секунду вручную, но, очевидно, мне нужно будет извлечь его из даты String
.
1 ответ:
Сначала нужно написать
IntentService
. Вот пример, вы можете написать код для отображения уведомления в функцииprocessNotification
.public class NotificationIntentService extends IntentService { private static final String ACTION_START = "ACTION_START"; public NotificationIntentService() { super(NotificationIntentService.class.getSimpleName()); } public static Intent createIntentStartNotificationService(Context context) { Intent intent = new Intent(context, NotificationIntentService.class); intent.setAction(ACTION_START); return intent; } @Override protected void onHandleIntent(Intent intent) { try { String action = intent.getAction(); if (ACTION_START.equals(action)) processNotification(); } finally { WakefulBroadcastReceiver.completeWakefulIntent(intent); } } private void processNotification() { Intent resultIntent=new Intent(this, MainActivity.class); PendingIntent pIntent = PendingIntent.getActivity(this, 0, resultIntent, 0); Notification nBuilder = new Notification.Builder(this) .setContentTitle("Don't miss! ") .setTicker("Notification!") .setContentIntent(pIntent) .setDefaults(Notification.DEFAULT_SOUND) .setAutoCancel(true) .setSmallIcon(R.drawable.my_logo) .setContentText("7 days left till your appointment...") .build(); NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); nBuilder.flags |=Notification.FLAG_AUTO_CANCEL; notificationManager.notify(1, nBuilder); } }
И затем создать
NotificationEventReceiver
public class NotificationEventReceiver extends WakefulBroadcastReceiver { private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE"; public static void setupAlarm(Context context, long interval) { AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PendingIntent alarmIntent = getStartPendingIntent(context); alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), interval, alarmIntent); } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Intent serviceIntent = null; if (ACTION_START_NOTIFICATION_SERVICE.equals(action)) { serviceIntent = NotificationIntentService.createIntentStartNotificationService(context); } if (serviceIntent != null) { startWakefulService(context, serviceIntent); } } private static PendingIntent getStartPendingIntent(Context context) { Intent intent = new Intent(context, NotificationEventReceiver.class); intent.setAction(ACTION_START_NOTIFICATION_SERVICE); return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } }
И
NotificationServiceStarterReceiver
public final class NotificationServiceStarterReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { long interval = getIntent().getLongExtra("alarm_interval", 0); NotificationEventReceiver.setupAlarm(context, interval); } }
Добавьте их в свой
AndroidManifest.xml
внутренний<application>
тегТеперь из вашего<service android:name="YourPackage.NotificationIntentService" android:enabled="true" android:exported="false" /> <receiver android:name="YourPackage.BroadcastReceiver.NotificationEventReceiver" /> <receiver android:name="YourPackage.BroadcastReceiver.NotificationServiceStarterReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.TIMEZONE_CHANGED" /> <action android:name="android.intent.action.TIME_SET" /> </intent-filter> </receiver>
Activity
Вы можете вызвать функциюsetupAlarm()
insideonCreate
.NotificationEventReceiver.setupAlarm(getApplicationContext(), interval);
Вам нужно добавить разрешение
WAKE_LOCK
в манифест.<uses-permission android:name="android.permission.WAKE_LOCK" />
Здесь вы видите, что можете передать
interval
следующее уведомление будет показано. Используйтеinterval
с умом. Вы можете сохранить текущие статусы встречи в базе данных, а затем при необходимости вызвать сигнал тревоги, передав соответствующий интервал следующего сигнала тревоги. Вот в чем идея.Обновить
Поэтому в вашем случае вы не хотите показывать уведомление, когда пользователь выходит из системы. Поэтому в этом случае вы можете рассмотреть возможность сохранения
Таким образом, псевдокод может выглядеть следующим образом.SharedPreference
для сохранения статуса входа. Вы можете вызвать функциюprocessNotification
на основе значения на хранении.if(pref.getBoolean("login_status", false)) { // If the login status is true, process the notification processNotification(); } else { // Do nothing }