Я сталкиваюсь с этой проблемой уже несколько дней и не могу найти объяснения:
Я работаю над приложением для Android, которое должно отправлять уведомления в указанное время.
Поэтому я использую диспетчер тревог, передавая время срабатывания с setExact()
.Дело в том, что если я устанавливаю время «вручную», что означает использование calendar.set(2019 ,1 ,24 ,15 , 30)
, то все работает нормально.
Теперь, когда я пытаюсь установить время запуска, используя объект даты, например, calendar.setTime(myDate)
, уведомление не отправляется в указанное время, а отправляется, когда приложение снова открывается и время уже прошло.
Я знаю, что если время срабатывания истекло, диспетчер аварийных сигналов срабатывает немедленно - это объясняет, почему я получаю уведомление после открытия приложения позже.
Вот мой код:
public void sendNotification() {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
setProgramFavorites();
Calendar triggerTime = Calendar.getInstance();
for (IProgram program : mFavoriteProgramItems) {
triggerTime.setTime(program.getProgramStart());
//triggerTime.set(2019, 1, 24, 15, 20); -> this is working just fine
Intent intent = new Intent(this, NotificationReceiver.class);
intent.putExtra("Program", program.getProgramName());
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime.getTimeInMillis(), pendingIntent);
}
}
}
Вот как форматируется дата:
public static Date parseDateTimeFromString(String value, String pattern) {
Date date = null;
//Convert string with given pattern into LocalDate
try {
date = new SimpleDateFormat(pattern).parse(value);
} catch (ParseException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return date;
}
, который используется в другом классе, как этот:
@Override
public Date getProgramStart() {
return DateFormatter.parseDateTimeFromString(programStartDate, "yyyy-MM-dd HH:mm:ss");
}
это мой IntentService:
public class NotificationService extends IntentService {
private NotificationManager mNotificationManager;
private NotificationCompat.Builder mBuilder;
public NotificationService() {
super("NotificationService");
}
/**
* this method creates the notification which is send if one of the favorite program items is about to start
* @param intent
*/
@Override
protected void onHandleIntent(Intent intent) {
String programTitle = intent.getStringExtra("Program");
Intent notificationIntent = new Intent(this, ABaseActivity.class);
//tracking stuff
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(100, PendingIntent.FLAG_UPDATE_CURRENT);
createNotificationChannel(this);
mBuilder = new NotificationCompat.Builder(this, "reminder_ID");
//configure the notification appearance
mBuilder.setContentTitle("Deine favorisierte Veranstaltung beginnt in Kürze")
.setContentText(programTitle)
.setSmallIcon(R.drawable.ic_menu_my_program)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
mNotificationManager.notify(0, mBuilder.build());
}
/**
* create a notification channel for devices with api level 28 or higher
*/
private void createNotificationChannel(Context context) {
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = "reminder_ID";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Reminder Notifications", NotificationManager.IMPORTANCE_DEFAULT);
// Configure the notification channel
notificationChannel.setDescription("Reminder for favorite program items");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.setVibrationPattern(new long[]{0, 500, 500});
notificationChannel.enableVibration(true);
mNotificationManager.createNotificationChannel(notificationChannel);
}
}
}
мой BroadcastReciever:
public class NotificationReceiver extends BroadcastReceiver {
public NotificationReceiver() {}
@Override
public void onReceive(Context context, Intent intent) {
//pass the program title to the notification service
String title = intent.getStringExtra("Program");
Intent serviceIntent = new Intent(context, NotificationService.class);
serviceIntent.putExtra("Program", title);
context.startService(serviceIntent);
}
}
и манифест Android:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.swtp.ak18c.eventapp">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".ui.activity.MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.activity.EventActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:parentActivityName=".ui.activity.MainActivity">
</activity>
<receiver android:name=".logic.receiver.NotificationReceiver"
android:exported="false"
android:enabled="true">
</receiver>
<service android:name=".logic.service.NotificationService"
android:enabled="true">
</service>
</application>
Я напечатал значения год, месяц, день, час и минуты объекта даты, который я использовал, и они были точно такими, как ожидалось.Что я делаю не так?