Android 中自定义通知的确切时间
Exact time for custom notifications in Android
我正在开发 Android 咨询服务应用程序。客户可以在应用程序中查看他们的预定约会。例如,
下一次约会: 2016 年 12 月 31 日 10:00AM
现在我需要做的是让用户收到 2 条通知——约会提醒。一个在 7 天前,另一个在 3 天前。我将这个日期(2016 年 12 月 31 日 10:00AM)保存为 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);
}
出于测试目的,我手动设置了 hour/minute/second,但显然我需要从日期 String
中提取它。
你需要先写一个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
中调用 onCreate
函数中的 setupAlarm()
。
NotificationEventReceiver.setupAlarm(getApplicationContext(), interval);
您需要在清单中添加 WAKE_LOCK
权限。
<uses-permission android:name="android.permission.WAKE_LOCK" />
这里你看你可以通过interval
下一个要显示的通知。明智地使用 interval
。您可以考虑将约会的当前状态保存在数据库中,然后在必要时通过传递下一个警报的适当间隔来触发警报。就是这个主意。
更新
所以在您的情况下,您不想在用户注销时显示通知。所以在这种情况下,您可以考虑保留一个 SharedPreference
来存储登录状态。您可以根据存储的值调用 processNotification
函数。
所以伪代码可能是这样的。
if(pref.getBoolean("login_status", false)) {
// If the login status is true, process the notification
processNotification();
} else {
// Do nothing
}
我正在开发 Android 咨询服务应用程序。客户可以在应用程序中查看他们的预定约会。例如,
下一次约会: 2016 年 12 月 31 日 10:00AM
现在我需要做的是让用户收到 2 条通知——约会提醒。一个在 7 天前,另一个在 3 天前。我将这个日期(2016 年 12 月 31 日 10:00AM)保存为 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);
}
出于测试目的,我手动设置了 hour/minute/second,但显然我需要从日期 String
中提取它。
你需要先写一个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
中调用 onCreate
函数中的 setupAlarm()
。
NotificationEventReceiver.setupAlarm(getApplicationContext(), interval);
您需要在清单中添加 WAKE_LOCK
权限。
<uses-permission android:name="android.permission.WAKE_LOCK" />
这里你看你可以通过interval
下一个要显示的通知。明智地使用 interval
。您可以考虑将约会的当前状态保存在数据库中,然后在必要时通过传递下一个警报的适当间隔来触发警报。就是这个主意。
更新
所以在您的情况下,您不想在用户注销时显示通知。所以在这种情况下,您可以考虑保留一个 SharedPreference
来存储登录状态。您可以根据存储的值调用 processNotification
函数。
所以伪代码可能是这样的。
if(pref.getBoolean("login_status", false)) {
// If the login status is true, process the notification
processNotification();
} else {
// Do nothing
}