2

Я разрабатываю приложение для 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.

+0

@Reaz: может ли удаление этих «импортных» линий затруднить понимание читателем проблемы? – halfer

+0

Импорт вопрос долго думаю.Поэтому я удалил их. Импорт часто не нужен. –

ответ

2

Сначала необходимо написать 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() внутри функции onCreate.

NotificationEventReceiver.setupAlarm(getApplicationContext(), interval); 

В вашем манифесте необходимо добавить разрешение WAKE_LOCK.

<uses-permission android:name="android.permission.WAKE_LOCK" /> 

Здесь вы видите, вы можете передать interval следующего уведомления будут показаны. Используйте разумно interval. Возможно, вы захотите сохранить текущие статусы назначения в базе данных, а затем, при необходимости, активировать сигнал тревоги, пройдя надлежащий интервал следующего сигнала. Это идея.

Update

Так что в вашем случае, вы не хотите, чтобы показать уведомление, когда пользователь выходит из системы. Поэтому в этом случае вы можете сохранить SharedPreference, чтобы сохранить статус входа в систему. Вы можете вызвать функцию processNotification на основе сохраненного значения.

Таким образом, псевдокод может выглядеть следующим образом.

if(pref.getBoolean("login_status", false)) { 
    // If the login status is true, process the notification 
    processNotification(); 
} else { 
    // Do nothing 
} 
+0

Спасибо, он работает. Но вместо setRepeating я использовал простой набор, потому что мне нужно одноразовое уведомление. Тем не менее, не могли бы вы рассказать мне, как я могу отменить эти уведомления, например, когда пользователь выходит из системы, больше не полезно показывать уведомления (я проверяю статус входа в основной метод onPause активности). Я был бы признателен за помощь. –

+0

Кроме того, вы забыли упомянуть, что мне нужно добавить разрешение wake_lock в файл манифеста. –

+0

Извините, отредактировал ответ. –