android notification 總結

今天使用Notification 遇到了 些詭異的問題,記錄下來,以備後用。

  1. 需求:定時獲取消息,並在通知欄顯示;點擊通知欄彈出消息框
  2. 實現:

    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);
        }
    }
  3. 出現問題:

  • 點擊通知,不彈出MessageActivity
解決方法:重啓手機;原因未知
  • 傳遞給activity的bundle爲null

 解決方法:將PendingIntent的flag設爲 PendingIntent.FLAG_UPDATE_CURRENT;

原因見 點擊打開鏈接   待研究

  • 通知欄消息點擊後不消失

      解決方法:notification添加flag​

                        notification.flags = Notification.FLAG_AUTO_CANCEL;

  • 運行程序立即彈出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);
  • 設置的第一個定時器不生效
原因:setRepeating的解釋如下,
    /**
     * 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.......

看來要想設置兩個Intent相同,僅僅是時間不同的鬧鈴是不能簡單的採用設置兩次的方法了。
從網上搜索到一種實現方式,每次找下一個時間點設置鬧鈴,鬧鈴執行時再設置下一個鬧鈴。代碼如下:
    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);
    ......


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章