Я хочу отправить уведомление в свое приложение в определенное время. Говорите каждый день, я должен давать уведомление в 7 утра, даже если приложение закрыто.
Как я могу это сделать? Любой учебник? Пожалуйста, укажите ссылку.
Я хочу отправить уведомление в свое приложение в определенное время. Говорите каждый день, я должен давать уведомление в 7 утра, даже если приложение закрыто.
Как я могу это сделать? Любой учебник? Пожалуйста, укажите ссылку.
сначала вам нужно использовать трансляцию. и потому, что широковещательный приемник работает только на короткое время
из блога разработчика 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);
Надеюсь, это поможет вам.
Решение из принятого ответа не будет работать должным образом на 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
:
расширить ваш Service
из JobIntentService
вместо IntentService
и использовать метод onHandleWork
вместо onHandleIntent
.
добавьте android:permission="android.permission.BIND_JOB_SERVICE"
к вашей Service
в AndroidManifest.xml
.
Вы можете использовать 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" />
Пример кода для того же:
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.");
}
}