Как давать уведомления о android в определенное время?

Я хочу отправить уведомление в свое приложение в определенное время. Говорите каждый день, я должен давать уведомление в 7 утра, даже если приложение закрыто.

Как я могу это сделать? Любой учебник? Пожалуйста, укажите ссылку.

Ответ 1

сначала вам нужно использовать трансляцию. и потому, что широковещательный приемник работает только на короткое время

из блога разработчика Android. При обработке широковещательной передачи приложению предоставляется фиксированный набор времени (в настоящее время 10 секунд) для выполнения своей работы. Если это не завершено за это время, приложение считается ошибочным, и его процесс немедленно перебрасывается в фоновое состояние, которое необходимо убить для памяти, если это необходимо.

его лучше использовать для использования также умышленного сервиса, здесь у вас есть пример, как это сделать.

это класс вещательного приемника.

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);
    }
}

и зарегистрируйте его в манифесте.

<receiver
    android:name=".MyReceiver"
    android:enabled="true"
    android:exported="false" >
</receiver>

это класс сервиса намерения.

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);
    }
}

и зарегистрируйте его в манифесте.

<service
    android:name=".MyNewIntentService"
    android:exported="false" >
</service>

а затем в вашей активности установите будильника для запуска широковещательного приемника в определенное время и используйте метод AlarmManager setRepeating, чтобы повторить его, этот пример ниже будет повторяться каждый день.

 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);

Надеюсь, это поможет вам.

Ответ 2

Решение из принятого ответа не будет работать должным образом на Android 8 Oreo (уровень API 26) и выше из-за ограничений фонового обслуживания (https://developer.android.com/about/versions/oreo/background.html#services) и вызовет исключение, подобное этому, когда приложение находится в фоновом режиме:

java.lang.IllegalStateException: Not allowed to start service Intent xxx: app is in background

Одним из возможных обходных путей является использование JobIntentService:

  1. расширить ваш Service из JobIntentService вместо IntentService и использовать метод onHandleWork вместо onHandleIntent.

  2. добавьте android:permission="android.permission.BIND_JOB_SERVICE" к вашей Service в AndroidManifest.xml.

Ответ 3

Вы можете использовать AlarmManager для установки сигнала тревоги в указанное время

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();
}

Я использовал SharedPreferences, чтобы проверить, что не первый раз для запуска приложения, и если это так, вы устанавливаете этот сигнал, иначе ничего не делаете вместо сброса тревоги каждый раз, когда вы запускаете приложение.
Используйте BroadcastReceiver для прослушивания при возникновении тревоги

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // show toast
        Toast.makeText(context, "Alarm running", Toast.LENGTH_SHORT).show();
    }
}

Используйте другой приемник для прослушивания загрузки устройства, чтобы вы могли reset аварийный сигнал

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);
        }
    }
}

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

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

затем зарегистрируйте приемники

<receiver android:name=".DeviceBootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>
<receiver android:name=".AlarmReceiver" />

Ответ 4

  • Получить службу сигнализации из системы.
  • Создайте намерение, передавая имя класса получателя вещания.
  • Сделайте объект календаря и установите его время 8 утра.
  • Проверьте, не истекло ли текущее время 8. Если да, то добавьте еще один день к нему.
  • Вызовите повторяющийся метод набора класса AlarmManager.

Пример кода для того же:

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.");

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

Фрагмент кода манифеста:

Фрагмент кода приемника вещания:

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);
}

Фрагмент кода службы создания уведомлений:

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.");

}

}