首页 文章

我在特定时间安排本地通知,使用开关但在设定时间不触发

提问于
浏览
11

我正在使用一个开关,当打开时会触发警报并启动通知 .

最初它工作正常并在设定的时间触发警报 . 手动更改时间后,它开始工作奇怪的通知是在开关打开但不在指定的设定时间时立即触发 .

这是交换机的代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    aSwitch = (Switch) findViewById(R.id.switch1);
    prefs = PreferenceManager.getDefaultSharedPreferences(this);
    Boolean switchState = prefs.getBoolean("locked", false);

    if(switchState) {
        aSwitch.setChecked(true);
    } else {
        aSwitch.setChecked(false);
    }

    aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(isChecked) {
                prefs.edit().putBoolean("locked", true).apply();
                NotificationEventReceiver.setupAlarm(getApplicationContext());
                aSwitch.setChecked(true);
            } else {
                prefs.edit().putBoolean("locked", false).apply();
                NotificationEventReceiver.cancelAlarm(getApplicationContext());
                aSwitch.setChecked(false);
            }
        }
    });
  }

 @Override
 protected void onNewIntent(Intent intent) {
     super.onNewIntent(intent);
     setIntent(intent);
 }

当开关打开时,它将使用 WakefullBroadcast 接收器触发通知 .

这是接收器类的代码:

public class NotificationEventReceiver extends WakefulBroadcastReceiver {

    private static final String ACTION_START_NOTIFICATION_SERVICE = "ACTION_START_NOTIFICATION_SERVICE";
    private static final String ACTION_DELETE_NOTIFICATION = "ACTION_DELETE_NOTIFICATION";


    public static void setupAlarm(Context context) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY, 07);
        calendar.set(Calendar.MINUTE, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent alarmIntent = getStartPendingIntent(context);
        alarmManager.setExact(AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(),
            alarmIntent);
}

    public static void cancelAlarm(Context context) {
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        PendingIntent alarmIntent = getStartPendingIntent(context);
        if(alarmManager!= null) {
            alarmManager.cancel(alarmIntent);
        }
    }

    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);
    }

    public static PendingIntent getDeleteIntent(Context context) {
        Intent intent = new Intent(context, NotificationEventReceiver.class);
        intent.setAction(ACTION_DELETE_NOTIFICATION);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Intent serviceIntent = null;
        if (ACTION_START_NOTIFICATION_SERVICE.equals(action)) {
            Log.i(getClass().getSimpleName(), "onReceive from alarm, starting notification service");
            serviceIntent = NotificationIntentService.createIntentStartNotificationService(context);
        } else if (ACTION_DELETE_NOTIFICATION.equals(action)) {
            Log.i(getClass().getSimpleName(), "onReceive delete notification action, starting notification service to handle delete");
            serviceIntent = NotificationIntentService.createIntentDeleteNotification(context);
        }

        if (serviceIntent != null) {
            // Start the service, keeping the device awake while it is launching.
            startWakefulService(context, serviceIntent);
        }
    }
}

我使用该服务来触发通知 .

这是后台服务的代码:

public class NotificationIntentService extends IntentService {

    private static final int NOTIFICATION_ID = 1;
    private static final String ACTION_START = "ACTION_START";
    private static final String ACTION_DELETE = "ACTION_DELETE";

    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;
    }

    public static Intent createIntentDeleteNotification(Context context) {
        Intent intent = new Intent(context, NotificationIntentService.class);
        intent.setAction(ACTION_DELETE);
        return intent;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d(getClass().getSimpleName(), "onHandleIntent, started handling a notification event");
        try {
            String action = intent.getAction();
            if (ACTION_START.equals(action)) {
                processStartNotification();
            }
        } finally {
            WakefulBroadcastReceiver.completeWakefulIntent(intent);
        }
    }

    private void processDeleteNotification(Intent intent) {
        // Log something?
    }

    private void processStartNotification() {
        // Do something. For example, fetch fresh data from backend to create a rich notification?

        final NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("Scheduled Notification")
                .setAutoCancel(true)
                .setColor(getResources().getColor(R.color.colorAccent))
                .setContentText("This notification has been triggered by Notification Service")
                .setSmallIcon(R.drawable.notification_icon);

        Intent mainIntent = new Intent(this, NotificationActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                NOTIFICATION_ID,
                mainIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);
        builder.setDeleteIntent(NotificationEventReceiver.getDeleteIntent(this));

        final NotificationManager manager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(NOTIFICATION_ID, builder.build());
    }
}

编辑1

这是日志:

06-23 11:19:56.807 5630-5630/logi.com.notificationbyschedule I/String: On setupAlarm
06-23 11:19:56.807 5630-5630/logi.com.notificationbyschedule I/String: PendingIntent Started
06-23 11:19:56.809 5630-5630/logi.com.notificationbyschedule V/AAAAA-AlarmManager: logi.com.notificationbyschedule
06-23 11:19:56.810 978-4653/? I/AlarmManager/AlarmPowerSavingMode: the following package : logi.com.notificationbyschedule is trusted app
06-23 11:19:56.810 978-4653/? I/AlarmManager/AlarmPowerSavingMode: logi.com.notificationbyschedule not in the white list or system app, do not use exact interface.
06-23 11:19:56.810 978-4653/? I/AlarmManager/AlarmPowerSavingMode: logi.com.notificationbyschedule in whitelist or system app not forece batched
06-23 11:19:56.810 978-4653/? V/AlarmManager: set(PendingIntent{16198c6a: PendingIntentRecord{1ed2c203 logi.com.notificationbyschedule broadcastIntent}}) : type=0 triggerAtTime=1466645456807 win=-1 tElapsed=309263486 maxElapsed=309263486 interval=0 standalone=true intent=Intent { act=ACTION_START_NOTIFICATION_SERVICE cmp=logi.com.notificationbyschedule/.broadcast_receivers.NotificationEventReceiver }
06-23 11:19:56.813 978-4014/? I/AlarmManager/AlarmPowerSavingMode: logi.com.notificationbyschedule Wakeup System : 6 times
06-23 11:19:56.836 5630-5630/logi.com.notificationbyschedule I/NotificationEventReceiver: onReceive from alarm, starting notification service
06-23 11:19:56.836 5630-5630/logi.com.notificationbyschedule I/String: CreateIntentServiceStart
06-23 11:19:56.967 5630-11858/logi.com.notificationbyschedule D/NotificationIntentService: onHandleIntent, started handling a notification event
06-23 11:19:56.967 5630-11858/logi.com.notificationbyschedule I/String: ProcessStartNotification
06-23 11:19:56.974 5630-11858/logi.com.notificationbyschedule I/String: PendingIntent Deleted
06-23 11:23:58.820 5630-5630/logi.com.notificationbyschedule I/String: On CancelAlarm
06-23 11:23:58.820 5630-5630/logi.com.notificationbyschedule I/String: PendingIntent Started
06-23 11:23:58.823 5630-5630/logi.com.notificationbyschedule I/String: Inside alarmManager not null

2 回答

  • 0

    尝试将on trigger方法更改为:

    private static long getTriggerAt(Date now) {
    Calendar calendar = new GregorianCalendar();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 7);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    
    if (System.currentTimeMillis() > calendar.getTimeInMillis()){
    calendar.setTimeInMillis(calendar.getTimeInMillis()+ 24*60*60*1000);// Okay, then tomorrow ...
    }
    return calendar.getTimeInMillis();
    }
    

    它将让你在24小时后设置闹钟

  • 1

    对于任何寻求实现上述目标的好解决方案的人,请同时查看此页面:https://developer.android.com/topic/performance/scheduling.html

    就个人而言,我是Firebase JobDispatcher解决方案的粉丝,它提供了一个强大的解决方案,甚至可以通过设备重启触发预定事件 .

相关问题