几天来我正面临这个问题,找不到任何解释:
我正在开发一个应在给定时间发送通知的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>
我确实打印了我使用的日期对象的年,月,日,小时和分钟的值,并且这些值完全符合预期。我在做什么错了?