今天使用Notification 遇到了 些詭異的問題,記錄下來,以備後用。
- 需求:定時獲取消息,並在通知欄顯示;點擊通知欄彈出消息框
- 實現:
AlarmManager + BroadcastReceiver + NotificationManager
部分代碼如下:
public static void setupGetMessageAlarm(Context context) { Log.d("msg", "setupGetMessageAlarm"); AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent(context, MsgAlarmReceiver.class); intent.setAction(INTENT_GET_MESSAGE_ALARM); PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); Calendar calendar1 = Calendar.getInstance(); calendar1.set(Calendar.HOUR_OF_DAY, 12); calendar1.set(Calendar.MINUTE, 30); Calendar calendar2 = Calendar.getInstance(); calendar2.set(Calendar.HOUR_OF_DAY, 18); calendar2.set(Calendar.MINUTE, 30); am.setRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); am.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); }
public class MsgAlarmReceiver extends BroadcastReceiver { private Context mContext; private MsgInfo mMsgInfo; private NotificationManager mNM; private static final int NOTIFICATION_ID = R.layout.activity_message; @Override public void onReceive(final Context context, Intent intent) { mContext = context; mNM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Intent intent = new Intent(mContext, MessageActivity.class); Bundle bundle = new Bundle(); bundle.putParcelable(MsgInfo.class.getName(), mMsgInfo); intent.putExtras(bundle); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); Notification notification = new Notification(); notification.icon = R.drawable.ic_app; notification.tickerText = mContext.getString(R.string.notification_ticker_message); notification.setLatestEventInfo(mContext, mMsgInfo.getTitle(), noticeMessage, pendingIntent); notification.flags = Notification.FLAG_AUTO_CANCEL; mNM.notify(NOTIFICATION_ID, notification); } }
- 出現問題:
- 點擊通知,不彈出MessageActivity
- 傳遞給activity的bundle爲null
解決方法:將PendingIntent的flag設爲 PendingIntent.FLAG_UPDATE_CURRENT;
原因見 點擊打開鏈接 待研究
- 通知欄消息點擊後不消失
解決方法:notification添加flag
- 運行程序立即彈出notification
Calendar calendar1 = Calendar.getInstance();
calendar1.set(Calendar.HOUR_OF_DAY, 12);
calendar1.set(Calendar.MINUTE, 30);
Calendar calendar2 = Calendar.getInstance();
calendar2.set(Calendar.HOUR_OF_DAY, 18);
calendar2.set(Calendar.MINUTE, 30);
// 若時間已過,設置下一天執行。
long alertTime1 = calendar1.getTimeInMillis(),
alertTime2 = calendar2.getTimeInMillis();
if(System.currentTimeMillis() > alertTime1){
alertTime1 += AlarmManager.INTERVAL_DAY;
}
if(System.currentTimeMillis() > alertTime2){
alertTime2 += AlarmManager.INTERVAL_DAY;
}
am.setRepeating(AlarmManager.RTC_WAKEUP, alertTime1, AlarmManager.INTERVAL_DAY, pi);
am.setRepeating(AlarmManager.RTC_WAKEUP, alertTime2, AlarmManager.INTERVAL_DAY, pi);
- 設置的第一個定時器不生效
* Schedule a repeating alarm. <b>Note: for timing operations (ticks,
* timeouts, etc) it is easier and much more efficient to use
* {@link android.os.Handler}.</b> If there is already an alarm scheduled
* for the same IntentSender, it will first be canceled.......
public static void setupNextGetMessageAlarm(Context context) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MsgAlarmReceiver.class);
intent.setAction(INTENT_GET_MESSAGE_ALARM);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(System.currentTimeMillis());
// 鬧鈴時間
final int HOUR_1 = 12, MINITE_1 = 30, HOUR_2 = 18, MINITE_2 = 30;
if(cal.get(Calendar.HOUR_OF_DAY) <= HOUR_1 && cal.get(Calendar.MINUTE) < MINITE_1){
cal.set(Calendar.HOUR_OF_DAY, HOUR_1);
cal.set(Calendar.MINUTE, MINITE_1);
}else if(cal.get(Calendar.HOUR_OF_DAY) <= HOUR_2 && cal.get(Calendar.MINUTE) < MINITE_2){
cal.set(Calendar.HOUR_OF_DAY, HOUR_2);
cal.set(Calendar.MINUTE, MINITE_2);
}else{
cal.set(Calendar.HOUR_OF_DAY, HOUR_1);
cal.set(Calendar.MINUTE, MINITE_1);
}
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
// 若時間已過,設置下一天執行。
long alertTime1 = cal.getTimeInMillis();
if(System.currentTimeMillis() > alertTime1){
alertTime1 += AlarmManager.INTERVAL_DAY;
}
am.setRepeating(AlarmManager.RTC_WAKEUP, alertTime1, AlarmManager.INTERVAL_DAY, pi);
}
@Override
public void onReceive(final Context context, Intent intent) {
LogUtil.d(TAG, "MsgAlarmReceiver");
mContext = context;
// 設置下一個鬧鈴
MsgUtils.setupNextGetMessageAlarm(context);
......