嗨,谢谢你的帮助。
我有一个应用程序使用AlarmManager在接下来的几周,几个月内每天设置一个警报......
和
我有以下问题,我将尝试按以下方式解释:
今天是星期三,
我打开应用程序并为MON,TUE,WED,THU,FRI,SAT,SUN设置闹钟...... 一旦我设置闹钟:
MON和TUE的所有警报立即关闭我最终得到4个活动实例!!!!
请问我该如何避免这种情况?
请看一段我的代码:
// SET THE ALARM FOR STARTING THE ACTIVITY
Intent smon = new Intent(ctxt, VideoActivty.class);
smon.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent psmon = PendingIntent.getActivity(ctxt, 0, smon, 0);
Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.DAY_OF_WEEK, 2);
calSet.set(Calendar.HOUR_OF_DAY, hsmon);
calSet.set(Calendar.MINUTE, msmon);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
mgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
7 * 24 * 60 * 60 * 1000, psmon);
// SET THE ALARM FOR KILLING THE ACTIVITY
Intent fmon = new Intent(ctxt, VideoActivty.class);
fmon.putExtra("finish", true);
PendingIntent pfmon = PendingIntent.getActivity(ctxt, 0, fmon, 0);
calSet.set(Calendar.DAY_OF_WEEK, 2);
calSet.set(Calendar.HOUR_OF_DAY, hfmon);
calSet.set(Calendar.MINUTE, mfmon);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
mgr.setRepeating(AlarmManager.RTC_WAKEUP, calSet.getTimeInMillis(),
7 * 24 * 60 * 60 * 1000, pfmon);
这是活动:
public class VideoActivty extends Activity {
private VideoView video;
private MediaController ctlr;
private PowerManager.WakeLock wl;
private KeyguardLock keyguard;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//
PowerManager pm = (PowerManager) this
.getSystemService(this.POWER_SERVICE);
wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
keyguard = km.newKeyguardLock("MyApp");
keyguard.disableKeyguard();
getWindow().setFormat(PixelFormat.TRANSLUCENT);
VideoView videoHolder = new VideoView(this);
//if you want the controls to appear
videoHolder.setMediaController(new MediaController(this));
Uri video = Uri.parse("android.resource://" + getPackageName() + "/"
+ R.raw.ingress); //do not add any extension
//if your file is named sherif.mp4 and placed in /raw
//use R.raw.sherif
videoHolder.setVideoURI(video);
setContentView(videoHolder);
videoHolder.start();
videoHolder.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.start();
}
});
}
@Override
protected void onNewIntent (Intent i){
if( i.getBooleanExtra("finish",false) ){
wl.release();
keyguard.reenableKeyguard();
finish();
}
}
}
答案 0 :(得分:4)
我们有解决方案吗?我仍在寻找解决方案,我的代码如下..
calendar.set(Calendar.DAY_OF_WEEK,getweekday(obj));
calendar.set(Calendar.HOUR_OF_DAY,timepicker.getCurrentHour());
calendar.set(Calendar.MINUTE, timepicker.getCurrentMinute());
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
if(calendar.before(cal_now)){//if its in the past increment
calendar.add(Calendar.DATE,1);
}
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(),_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY * 7, sender);
答案 1 :(得分:4)
作为AlarmManager状态的API页面,关于 set(...)和 setRepeating(...)方法:
“如果指定的触发时间是过去的,则报警将是 立即触发,警报计数取决于在多远 超过触发时间是相对于重复间隔。“
因此,如果您在星期三,那么AlarmManager将触发以下事件:星期日,星期一,星期二和(可能)星期三。它实际上只会为所有人发射一个。
以下是我如何避免这种情况。不确定这是最好的方式,但它运作顺畅。
假设您存储了要解雇的当天的一天,小时和分钟 AlarmManager中包含以下变量:
final int myAlarmDayOfTheWeek = ...;
final int myAlarmHour = ...;
final int myAlarmMinute = ...;
当然,在这里,我假设您使用Calendar class的相同惯例存储星期几,即:
星期日= Calendar.SUNDAY = 1
星期一= Calendar.MONDAY = 2
...... ......
星期六= Calendar.SATURDAY = 7
然后:
Calendar timestamp = Calendar.getInstance();
//Check whether the day of the week was earlier in the week:
if( myAlarmDayOfTheWeek > timestamp.get(Calendar.DAY_OF_WEEK) ) {
//Set the day of the AlarmManager:
time.add(Calendar.DAY_OF_YEAR, (myAlarmDayOfTheWeek - timestamp.get(Calendar.DAY_OF_WEEK)));
}
else {
if( myAlarmDayOfTheWeek < timestamp.get(Calendar.DAY_OF_WEEK) ) {
//Set the day of the AlarmManager:
timestamp.add(Calendar.DAY_OF_YEAR, (7 - (timestamp.get(Calendar.DAY_OF_WEEK) - myAlarmDayOfTheWeek)));
}
else { // myAlarmDayOfTheWeek == time.get(Calendar.DAY_OF_WEEK)
//Check whether the time has already gone:
if ( (myAlarmHour < timestamp.get(Calendar.HOUR_OF_DAY)) || ((myAlarmHour == timestamp.get(Calendar.HOUR_OF_DAY)) && (myAlarmMinute < timestamp.get(Calendar.MINUTE))) ) {
//Set the day of the AlarmManager:
timestamp.add(Calendar.DAY_OF_YEAR, 7);
}
}
}
//Set the time of the AlarmManager:
timestamp.set(Calendar.HOUR_OF_DAY, myAlarmHour);
timestamp.set(Calendar.MINUTE, myAlarmMinute);
timestamp.set(Calendar.SECOND, 0);
请注意,在Calendar.DAY_OF_YEAR中使用Calendar.add(...),您甚至不需要处理月份的变化......
如果你处于第一个条件(即myAlarmDayOfTheWeek&gt; timestamp.get(Calendar.DAY_OF_WEEK)),你也可以使用Calendar.set(...)作为Calendar.DAY_OF_WEEK字段和 myAlarmDayOfTheWeek 作为价值。
现在,您只需要设置AlarmManager即可。例如:
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timestamp.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, myAlarmPendingIntent);
请避免每次计算日间隔(即24 * 60 * 60 * 1000),而是使用AlarmManager.INTERVAL_DAY(或最多 86400000 )。
答案 2 :(得分:1)
来自AlarmManager
int RTC_WAKE System.currentTimeMillis()中的闹钟时间(以UTC为挂钟时间),它将在设备关闭时唤醒设备。
从日历
Calendar.getInstance()
将Calendar子类实例设置为默认时区中的当前日期和时间。
这两个用途将是不同的时区。
另外,只更改DAY_OF_WEEK
,您不会更改Calendar对象的WEEK_OF_YEAR
字段。这意味着,如果它是星期三,但你正在为星期一设置闹钟(通过仅更改星期几),它将立即关闭,因为它设置为本星期一。如果您需要在同一时间设置一周中每一天的闹钟
alarmManager(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (24hoursOfMilliseconds), 24hoursOfMilliseconds, pendingIntent);
这将设置相同的闹钟,每24小时重复一次。如果您需要在不同的日子做不同的事情,请使用
switch(calendarObj.get(Calendar.DAY_OF_WEEK) { }
答案 3 :(得分:0)
只需使用boolean在共享首选项中注册今天的日期,并在第一次执行时将其设置为true。在重新启动期间,如果通知已经发送,则忽略else通知用户。第二天,只需删除旧的首选项并创建新的共享偏好值
public boolean isAlreadyWished(String date,String previousDate){
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
if(sharedPref.contains(alreadyNotifiedString+previousDate)){
sharedPref.edit().remove(alreadyNotifiedString+previousDate);
}
if(sharedPref.contains(alreadyNotifiedString+date)){
boolean displayOrderString = sharedPref.getBoolean(alreadyNotifiedString+date, false);
return displayOrderString;
}else{
SharedPreferences.Editor editor=sharedPref.edit();
editor.putBoolean(alreadyNotifiedString+date,true);
return false;
}
}