我必须运行一个接收器,该接收器仅在一周中的特定日期的特定持续时间内接收action
USER_PRESENT
。此处,持续时间和工作日由用户选择。
我尝试过使用Preferences
和AlarmManager
来实现此目标,我非常希望使用Alarms
以外的Preferences
来实现此目的。在用户选择的持续时间和用户选择的工作日之后运行的每周警报测试警报变得非常困难。
除了使用Alarms
和Preferences
之外,还有其他方法可以完成这项工作吗?代码示例真有用!!
有关详细信息,请参阅Alarms
使用Preferences
的方法:
现在我首先计算开始时间,让用户通过DialogFragment
选择小时和分钟,其中TimePickerDialog
被夸大,以便用户可以选择开始时间,我得到{{1}在hrs
回调中找到min
,然后找出接收器启动的开始时间。
代码片段用于从onTimeSet()
和hrs
计算以毫秒为单位的开始时间:
min
然后我以 Calendar calSet = Calendar.getInstance();
//setting alarm from current day so that it starts from today onwards
int day = calSet.get(Calendar.DAY_OF_WEEK);
calSet.set(Calendar.DAY_OF_WEEK, day);
calSet.set(Calendar.HOUR_OF_DAY, hrs);
calSet.set(Calendar.MINUTE, min);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
Long milliseconds = calSet.getTimeInMillis();
//check if the time is already passed
Long daily = 24L * 60L * 60L * 1000L;
if (milliseconds < System.currentTimeMillis()) {
//if already passed then push it for next day by adding just 24 hrs
milliseconds = milliseconds + daily;
}
说preference
说:SharedPreferences.Editor.putLong("PeriodicLockStartTimeInMillis", milliseconds);
现在,我使用checkBoxes
存储用户选择的日期,并为每一天的复选框设置preferences
SharedPreferences.Editor.putBoolean("DAYNAME", true);
还存储用户希望接收者工作的持续时间:
SharedPreferences.Editor.putLong("LockDurationInMillis", minutesinmillis);
然后使用AlarmManager
设置一个警报,该警报会将BroadcastReceiver
的名称PeriodicLockService
设置为PendingIntent
作为Intent reminderIntent = new Intent(getActivity(), PeriodicLockService.class);
reminderIntent.setAction("ACTION_REPEATING_ALARM_RECEIVER");
pendingIntent = PendingIntent.getBroadcast(getActivity(), PeriodicLockService.REPEATING_ALARM_UNIQUE_ID, reminderIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, milliseconds, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, milliseconds, pendingIntent);
}
,然后点击其接收方。
此处设置闹钟的代码:
PeriodicLockService
现在onReceive
点击preference
时,我首先使用//Fetching today's day from Calendar to compare if user has set lock for today
Calendar calendar = Calendar.getInstance();
int day = calendar.get(Calendar.DAY_OF_WEEK);
switch (day) {
case Calendar.SUNDAY:
if (Preferences.getBooleanPreference(context, SUN_DAY)) {
startLockNow(context);
}
break;
case Calendar.MONDAY:
if (Preferences.getBooleanPreference(context, MON_DAY)) {
startLockNow(context);
}
break;
case Calendar.TUESDAY:
if (Preferences.getBooleanPreference(context, TUES_DAY)) {
startLockNow(context);
}
break;
case Calendar.WEDNESDAY:
if (Preferences.getBooleanPreference(context, WED_DAY)) {
startLockNow(context);
}
break;
case Calendar.THURSDAY:
if (Preferences.getBooleanPreference(context, THURS_DAY)) {
startLockNow(context);
}
break;
case Calendar.FRIDAY:
if (Preferences.getBooleanPreference(context, FRI_DAY)) {
startLockNow(context);
}
break;
case Calendar.SATURDAY:
if (Preferences.getBooleanPreference(context, SAT_DAY)) {
startLockNow(context);
}
break;
}
private void startLockNow(Context context) {
Long lockStartTimeInMillis = Preferences.getLongPreference(context, "PeriodicLockStartTimeInMillis");
//Update Unlock Time
Long LockDurationInMillis = Preferences.getLongPreference(context, "LockDurationInMillis"); //End time to stop the Receiver for action USER_PRESENT
Long newEndTime = lockStartTimeInMillis + LockDurationInMillis;
//Set Unlocked notification broadcast which also disables the receiver for action `USER_PRESENT`
Intent intent = new Intent(context, FinalUnlockedBroadcast.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, newEndTime + 1000, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, newEndTime + 1000, pendingIntent);
}
//update the time for next lock by adding a day
milliseconds = Preferences.getLongPreference(context, "PeriodicLockStartTimeInMillis") + 24L * 60L * 60L * 1000L;
Intent reminderIntent = new Intent(context, PeriodicLockService.class);
reminderIntent.setAction("ACTION_REPEATING_ALARM_RECEIVER");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REPEATING_ALARM_UNIQUE_ID, reminderIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, milliseconds , pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, milliseconds , pendingIntent);
}
}
检查用户是否设置了今天要运行的内容:
Alarms
但问题是,这似乎并不总是有用,而且很难从运行我的应用的用户设备获取日志。
除了使用Preferences
和Human human1 = new Human();
human1.name = "John";
答案 0 :(得分:1)
Android-Job Android-Job repo
实施Android-Job非常简单。
API包括以下类/接口。
如果你有兴趣阅读更多plz,请参阅这篇精彩的文章Easy Job Scheduling with Android-Job
感谢 Rajesh Pattanaik 撰写本文的人
答案 1 :(得分:0)
我建议你使用Firebase Job Dispatcher。它是一个用于在Android应用中安排后台作业的库。它提供了与JobScheduler兼容的API,适用于安装了Google Play服务的所有最新版本的Android(API级别9+)。
有关如何在您的应用中使用它的说明,请点击here。
答案 2 :(得分:0)
您可以使用Job Scheduler
public class MyJobService extends JobService {
@Override
public boolean onStartJob(JobParameters params) {
Toast.makeText(this, "testing", Toast.LENGTH_LONG).show();
Log.i("sid", "Job scheduler called");
jobFinished(params, true);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
}
在您的活动中调用以下方法
private void constructJob(){
JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, new ComponentName(this, MyJobService.class));
builder.setMinimumLatency(60000)
.setBackoffCriteria(10000,JobInfo.BACKOFF_POLICY_LINEAR)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setPersisted(true);
mJobScheduler.schedule(builder.build());
}
确保调用builder.setPersisted(true)以便在重新启动后运行该服务。另外要看一下这个代码在Android N(API 24)或更高版本的API上可以正常工作,但是,对于API 21 - 23,它调用builder.setPeriodic(60000)而不是builder.setMinimumLatency(60000)
<强>更新强> 要在API 15及更高版本上运行Job Scheduler,请使用JobSchedulerCompat。
在您的gradle文件中添加以下依赖项 -
compile 'me.tatarka.support:jobscheduler:0.1.1'