android - 设置 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());
}
}
}
解决方案
推荐阅读
- ip - mikrotik 路线每秒自动出现并删除
- c# - 多对多关系上的 Dotnet Api Auto Mapper 不起作用
- php - 在我的 S3 存储桶中的应用程序 php 中将图像显示为 jpeg?
- python - 如何修复 Kivy 中 RecyleView 行之间的额外空间?
- python - 网页抓取 Javascript 表的问题
- html - 无法使用视口宽度使图像响应
- php - PHP - GET 请求适用于 Postman,但不适用于 cUrl
- html - 使用 VBA 查找子菜单元素并单击
- python - 用数字替换每列中的字符串
- java - PDFBox EOFException:设置文本字段值时为空