Android 带时间和日期选择器的警报管理器
Android Alarm Manager with Time and Date Picker
我正在开发一个需要用户安排活动的应用程序。我正在使用 TimePicker 和 DatePicker 对话框来设置事件的时间,并使用带有 BroadcastReceiver 的 AlarmManager 在到达时间时执行操作。在测试中,我得出的结论是我的时间和日期选择器对话框工作正常,我能够选择日期和时间。但是,当到达时间时,AlarmManager 不会触发 BroadcastReceiver。
这是我安排活动的 MainActivity.class:
public class MainActivity extends Activity {
Button setTime;
Button scheduleEvent;
static final int DATEPICKER_DIALOG_ID = 0;
static final int TIMEPICKER_DIALOG_ID = 1;
int dpYear, dpMonth, dpDay, tpHour, tpMinute;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Calendar calendar = Calendar.getInstance();
dpYear = calendar.get(Calendar.YEAR);
dpMonth = calendar.get(Calendar.MONTH);
dpDay = calendar.get(Calendar.DAY_OF_MONTH);
tpHour = calendar.get(Calendar.HOUR_OF_DAY);
tpMinute = calendar.get(Calendar.MINUTE);
setTime = (Button) findViewById(R.id.button1);
scheduleEvent = (Button) findViewById(R.id.button2);
setTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showDialog(DATEPICKER_DIALOG_ID);
}
});
scheduleEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.ohs.example.myEvent");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmMgr = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, dpYear);
cal.set(Calendar.MONTH, dpMonth);
cal.set(Calendar.DAY_OF_MONTH, dpDay);
cal.set(Calendar.HOUR_OF_DAY, tpHour);
cal.set(Calendar.MINUTE, tpMinute);
cal.set(Calendar.SECOND, 0);
long mills = cal.getTimeInMillis();
alarmMgr.set(AlarmManager.RTC_WAKEUP, mills, pendingIntent);
Toast.makeText(this, "Event scheduled at " + tpHour + ":" + tpMinute + " " + dpDay + "/" + dpMonth + "/" + dpYear, Toast.LENGTH_LONG).show();
}
});
}
@Override
protected Dialog onCreateDialog(int id) {
if (id == DATEPICKER_DIALOG_ID) {
return new DatePickerDialog(this, datePickerListener, dpYear, dpMonth, dpDay);
} else if (id == TIMEPICKER_DIALOG_ID) {
return new TimePickerDialog(this, timePickerListener, tpHour, tpMinute, false);
} else {
return null;
}
}
private DatePickerDialog.OnDateSetListener datePickerListener =
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
dpYear = i;
dpMonth = i1 + 1;
dpDay = i2;
showDialog(TIMEPICKER_DIALOG_ID);
}
};
protected TimePickerDialog.OnTimeSetListener timePickerListener =
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
tpHour = i;
tpMinute = i1;
}
};
}
AlarmReceiver.class:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast Received", Toast.LENGTH_LONG).show();
eventMethod();
}
protected void eventMethod() {
//Do something...
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ohs.example" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver" android:enabled="true">
<intent-filter>
<action android:name="com.ohs.example.myEvent" />
</intent-filter>
</receiver>
</application>
</manifest>
我之前在其他应用程序上工作时,我必须每 6 小时设置一个重复闹钟。我使用了与上面完全相同的代码(使用 AlarmManager 和 BraodcastReceiver),只是代替了:
cal.set(Calendar.YEAR, dpYear);
cal.set(Calendar.MONTH, dpMonth);
cal.set(Calendar.DAY_OF_MONTH, dpDay);
cal.set(Calendar.HOUR_OF_DAY, tpHour);
cal.set(Calendar.MINUTE, tpMinute);
cal.set(Calendar.SECOND, 0);
我只有:
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR_OF_DAY, 18);
而且效果很好。 "YEAR"、"MONTH" 和 "DAY_OF_MONTH" 也是导致问题的原因。如果是,解决方案是什么?
我已经为我的问题寻找了很多解决方案,并且在 Whosebug 上发现了类似的问题,但是 none 帮助了我。任何帮助将不胜感激。
我遇到过一次这个问题。这种现象在你所有的测试中都发生过吗phone?我的问题出现是因为我的一项测试 phone 修改了 phone 硬件以解决省电问题。所以 alarmReceiver 每五分钟
经过大量尝试...我意识到问题是 Calendar.DAY_OF_MONTH 从 0 到 11 需要几个月(0 是 1 月,11 是 12 月)...不幸的是我没有知道这一点,所以我将 1 添加到从 datePicker 获得的月份值。所以我刚刚删除了 + 1,现在它运行良好。
我正在开发一个需要用户安排活动的应用程序。我正在使用 TimePicker 和 DatePicker 对话框来设置事件的时间,并使用带有 BroadcastReceiver 的 AlarmManager 在到达时间时执行操作。在测试中,我得出的结论是我的时间和日期选择器对话框工作正常,我能够选择日期和时间。但是,当到达时间时,AlarmManager 不会触发 BroadcastReceiver。
这是我安排活动的 MainActivity.class:
public class MainActivity extends Activity {
Button setTime;
Button scheduleEvent;
static final int DATEPICKER_DIALOG_ID = 0;
static final int TIMEPICKER_DIALOG_ID = 1;
int dpYear, dpMonth, dpDay, tpHour, tpMinute;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Calendar calendar = Calendar.getInstance();
dpYear = calendar.get(Calendar.YEAR);
dpMonth = calendar.get(Calendar.MONTH);
dpDay = calendar.get(Calendar.DAY_OF_MONTH);
tpHour = calendar.get(Calendar.HOUR_OF_DAY);
tpMinute = calendar.get(Calendar.MINUTE);
setTime = (Button) findViewById(R.id.button1);
scheduleEvent = (Button) findViewById(R.id.button2);
setTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showDialog(DATEPICKER_DIALOG_ID);
}
});
scheduleEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("com.ohs.example.myEvent");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmMgr = (AlarmManager) (this.getSystemService(Context.ALARM_SERVICE));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, dpYear);
cal.set(Calendar.MONTH, dpMonth);
cal.set(Calendar.DAY_OF_MONTH, dpDay);
cal.set(Calendar.HOUR_OF_DAY, tpHour);
cal.set(Calendar.MINUTE, tpMinute);
cal.set(Calendar.SECOND, 0);
long mills = cal.getTimeInMillis();
alarmMgr.set(AlarmManager.RTC_WAKEUP, mills, pendingIntent);
Toast.makeText(this, "Event scheduled at " + tpHour + ":" + tpMinute + " " + dpDay + "/" + dpMonth + "/" + dpYear, Toast.LENGTH_LONG).show();
}
});
}
@Override
protected Dialog onCreateDialog(int id) {
if (id == DATEPICKER_DIALOG_ID) {
return new DatePickerDialog(this, datePickerListener, dpYear, dpMonth, dpDay);
} else if (id == TIMEPICKER_DIALOG_ID) {
return new TimePickerDialog(this, timePickerListener, tpHour, tpMinute, false);
} else {
return null;
}
}
private DatePickerDialog.OnDateSetListener datePickerListener =
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
dpYear = i;
dpMonth = i1 + 1;
dpDay = i2;
showDialog(TIMEPICKER_DIALOG_ID);
}
};
protected TimePickerDialog.OnTimeSetListener timePickerListener =
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
tpHour = i;
tpMinute = i1;
}
};
}
AlarmReceiver.class:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Broadcast Received", Toast.LENGTH_LONG).show();
eventMethod();
}
protected void eventMethod() {
//Do something...
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ohs.example" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver" android:enabled="true">
<intent-filter>
<action android:name="com.ohs.example.myEvent" />
</intent-filter>
</receiver>
</application>
</manifest>
我之前在其他应用程序上工作时,我必须每 6 小时设置一个重复闹钟。我使用了与上面完全相同的代码(使用 AlarmManager 和 BraodcastReceiver),只是代替了:
cal.set(Calendar.YEAR, dpYear);
cal.set(Calendar.MONTH, dpMonth);
cal.set(Calendar.DAY_OF_MONTH, dpDay);
cal.set(Calendar.HOUR_OF_DAY, tpHour);
cal.set(Calendar.MINUTE, tpMinute);
cal.set(Calendar.SECOND, 0);
我只有:
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR_OF_DAY, 18);
而且效果很好。 "YEAR"、"MONTH" 和 "DAY_OF_MONTH" 也是导致问题的原因。如果是,解决方案是什么?
我已经为我的问题寻找了很多解决方案,并且在 Whosebug 上发现了类似的问题,但是 none 帮助了我。任何帮助将不胜感激。
我遇到过一次这个问题。这种现象在你所有的测试中都发生过吗phone?我的问题出现是因为我的一项测试 phone 修改了 phone 硬件以解决省电问题。所以 alarmReceiver 每五分钟
经过大量尝试...我意识到问题是 Calendar.DAY_OF_MONTH 从 0 到 11 需要几个月(0 是 1 月,11 是 12 月)...不幸的是我没有知道这一点,所以我将 1 添加到从 datePicker 获得的月份值。所以我刚刚删除了 + 1,现在它运行良好。