首页 > 解决方案 > 设置 AlarmManager 以随机间隔重复

问题描述

我正在尝试发出在某个特定间隔内随机重复的警报。

例如,让我们选择 1 周的间隔值。此警报应在当前时间和 1 周上限之间随机响起。这意味着,如果当前是星期一,那么例如警报应该响起;周三或周六,只要不超过下周一的上限。

这种情况应该每周重复一次,并且警报应该随机选择下一周的另一个时间。

我已经设法用这种方法实现了上半年 alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, currentTime + tenSecondsInMillis,getRandomInterval(),pendingIntent);

我已经为setRepeating()实现了一个名为getRandomInterval()的方法,这样它每次重复时都会使用不同的重复时间,但不幸的是,一旦它被调用,setRepeating()就不会再次调用这个方法,因此getRandomInterval()不能给出新的随机间隔值,第一次调用的初始随机值除外。

有没有办法随机重复警报,每次重复时都有不同的随机时间值?

MainActivity.java

package com.example.trs;

import androidx.appcompat.app.AppCompatActivity;

import android.app.AlarmManager;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Toast;

import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private SchedulerDatabaseHelper db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        db = new SchedulerDatabaseHelper(this);

        CheckBox coldShowerCheckBox = findViewById(R.id.coldShowerCheckBox);
        
        coldShowerCheckBox.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                db.UPDATE_SCHEDULE(SchedulerDatabaseHelper.COLD_SHOWER_SCHEDULE_STRING);
                AlarmManager alarmManager =  (AlarmManager) getSystemService(ALARM_SERVICE);
                Intent intent = new Intent(MainActivity.this, SchedulerBroadcast.class);
                intent.setAction(SchedulerDatabaseHelper.COLD_SHOWER_SCHEDULE_STRING);
                createNotificationChannel(SchedulerDatabaseHelper.COLD_SHOWER_SCHEDULE_STRING);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this,0,intent,0);

                if(coldShowerCheckBox.isChecked()){
                    //TODO WILL SET A RANDOM COLD SHOWER SCHEDULE
                    Toast.makeText(getApplicationContext(), "Schedule is set for Cold Shower",Toast.LENGTH_SHORT).show();
                    long currentTime = System.currentTimeMillis();
                    long tenSecondsInMillis = 1000 * 10;
                    //TODO WILL CALCULATE RANDOM DATE
                    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, currentTime + tenSecondsInMillis,getRandomInterval(),pendingIntent);

                } else {
                    Toast.makeText(getApplicationContext(), "Schedule is removed for Cold Shower",Toast.LENGTH_SHORT).show();
                    alarmManager.cancel(pendingIntent);
                    deleteNotificationChannel(SchedulerBroadcast.coldShowerChannelId);
                }
            }
        });

    }

    private void createNotificationChannel(String channelName){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            CharSequence name = "SchedulerReminderChannel";
            String description = "Channel for The Random Scheduler";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel(channelName, name, importance);
            channel.setDescription(description);

            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

    private void deleteNotificationChannel(int channelID){
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            NotificationManager notificationManager = getSystemService(NotificationManager.class);
            notificationManager.deleteNotificationChannel(String.valueOf(channelID));
        }
    }

    //TODO setRepeating() will call this everytime, and update new interval value for the next repeat
    private int getRandomInterval(){

        Random r = new Random();
        int low = 5;
        int high = 20;
        int result = r.nextInt(high-low) + low;
        //Log.e("Next Interval Value: ", String.valueOf(result * 1000));
        return result * 1000;
    }
}

SchedulerBroadcast.java

package com.example.trs;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;

public class SchedulerBroadcast extends BroadcastReceiver {

    public static final int coldShowerChannelId = 400;

    @Override
    public void onReceive(Context context, Intent intent) {

        String scheduleType = intent.getAction();

        if(scheduleType.equals(SchedulerDatabaseHelper.COLD_SHOWER_SCHEDULE_STRING)){
            NotificationCompat.Builder builder = new NotificationCompat.Builder(context, 
                    SchedulerDatabaseHelper.COLD_SHOWER_SCHEDULE_STRING)
                    .setSmallIcon(R.drawable.ic_baseline_add_alert_24)
                    .setContentTitle("It is time for Cold Shower")
                    .setContentText("This is a reminder for taking a Cold Shower.")
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT);

            NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);

            notificationManager.notify(coldShowerChannelId, builder.build());
        }
    }
}

标签: androidandroid-studiobroadcastreceiveralarmmanager

解决方案


推荐阅读