如何在应用程序中设置多个 BroadcastReceivers
How to set up multiple BroadcastReceivers in an app
我正在创建一个列出即将上映的电影的应用程序,用户为他希望在其发布临近时收到提醒的任何电影设置提醒(他使用 DatePicker 选择弹出通知的日期)。所以你猜对了,每部电影都可以收到通知。我猜想这样做,当用户像这样设置提醒时,我需要将电影的名称和 ID 放在 SharedPreference 中;
public void setAlarm(View view){
Intent alertIntent = new Intent(this, AlertReceiver.class);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = settings.edit();
editor.putString("name", name);
editor.putInt("id", mainId);
editor.commit();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set() schedules an alarm to trigger
// FLAG_UPDATE_CURRENT : Update the Intent if active
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, 1, alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
}
然后在 OnRecieve() 方法上我获取 SharedPreference 并使用名称和 ID 构建一条消息
public void onReceive(Context context, Intent intent) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
String name = settings.getString("name", "");
int id = settings.getInt("id", 0);
createNotification(context, "" , name + " Coming soon" , name, id);
}
public void createNotification(Context context, String msg, String msgText, String msgAlert, int id){
// Define an Intent and an action to perform with it by another application
PendingIntent notificIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
// Builds a notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setContentTitle(msg)
.setContentText(msgText)
.setTicker(msgAlert)
.setSmallIcon(R.mipmap.ic_launcher);
//the intent when the notification is clicked on
mBuilder.setContentIntent(notificIntent); //goes to MainActivity
//how the user will be notified
mBuilder.setDefaults(NotificationCompat.DEFAULT_LIGHTS);
//stop notification when it's clicked on
mBuilder.setAutoCancel(true);
//now to notify the user with NotificationManager
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, mBuilder.build());
}
OnReceive 效果很好,但似乎我一次只能创建一个提醒,比如 SharedPreference 用新的覆盖旧的,我想?我是否需要为我 setAlarm() 的每部电影声明一个新的 SharedPreference?然后 BroadcastReceiver 的 OnReceive 方法将从 SharedPreference?
中获取值
您的情况不需要 SharedPreference,您可以直接将数据放入意图并在 onReceive 方法中从意图中获取该数据。
如果你想设置多个闹钟(重复或单个),那么你只需要用不同的requestCode创建他们的PendingIntents。如果 requestCode 相同,则新警报将覆盖旧警报。
为此,您可以使用
System.currentTimeMillis();
public void setAlarm(View view){
Intent alertIntent = new Intent(this, AlertReceiver.class);
alertIntent.putExtra("name", name);
alertIntent.putExtra("id", mainId);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set() schedules an alarm to trigger
// FLAG_UPDATE_CURRENT : Update the Intent if active
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
}
onReceive 方法从 intent 获取数据
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
//reset your alarm here save your alarms in database or shared //preferences so that you can reset here
}else{
String name = intent.getStringExtra("name", "");
int id = intent.getIntExtra("id", 0);
createNotification(context, "" , name + " Coming soon" , name, id);
}
}
尝试这样的事情
public class AlarmManagerHelper extends BroadcastReceiver {
public static final String ID = "id";
public static final String NAME = "name";
public static final String TIME_HOUR = "timeHour";
public static final String TIME_MINUTE = "timeMinute";
public static final String TONE = "alarmTone";
public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
@Override
public void onReceive(Context context, Intent intent) {
setAlarms(context);
}
public static void setAlarms(Context context) {
cancelAlarms(context);
AlarmDBHelper dbHelper = new AlarmDBHelper(context);
List<AlarmModel> alarms = dbHelper.getAlarms();
if (alarms != null) {
for (AlarmModel alarm : alarms) {
if (alarm.isEnabled) {
PendingIntent pIntent = createPendingIntent(context, alarm);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarm.timeHour);
calendar.set(Calendar.MINUTE, alarm.timeMinute);
calendar.set(Calendar.SECOND, 00);
//Find next time to set
final int nowDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
final int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
final int nowMinute = Calendar.getInstance().get(Calendar.MINUTE);
boolean alarmSet = false;
//First check if it's later in the week
for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek >= nowDay &&
!(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
!(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
setAlarm(context, calendar, pIntent);
alarmSet = true;
setStatusBarIcon(context, alarmSet);
break;
}
}
//Else check if it's earlier in the week
if (!alarmSet) {
for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek <= nowDay && alarm.repeatWeekly) {
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
calendar.add(Calendar.WEEK_OF_YEAR, 1);
setAlarm(context, calendar, pIntent);
alarmSet = true;
break;
}
}
}
}
}
}
}
@SuppressLint("NewApi")
private static void setAlarm(Context context, Calendar calendar, PendingIntent pIntent) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
}
}
public static void cancelAlarms(Context context) {
AlarmDBHelper dbHelper = new AlarmDBHelper(context);
List<AlarmModel> alarms = dbHelper.getAlarms();
if (alarms != null) {
for (AlarmModel alarm : alarms) {
if (alarm.isEnabled) {
PendingIntent pIntent = createPendingIntent(context, alarm);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pIntent);
}
}
}
}
public static void setStatusBarIcon(Context context, boolean enabled) {
Intent alarmChanged = new Intent(ACTION_ALARM_CHANGED);
alarmChanged.putExtra("alarmSet", enabled);
context.sendBroadcast(alarmChanged);
}
private static PendingIntent createPendingIntent(Context context, AlarmModel model) {
Intent intent = new Intent(context, AlarmService.class);
intent.putExtra(ID, model.id);
intent.putExtra(NAME, model.name);
intent.putExtra(TIME_HOUR, model.timeHour);
intent.putExtra(TIME_MINUTE, model.timeMinute);
intent.putExtra(TONE, model.alarmTone.toString());
return PendingIntent.getService(context, (int) model.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
从数据库中获取所有警报的函数
public ArrayList<AlarmModel> getAlarms() {
SQLiteDatabase db = this.getReadableDatabase();
String select = "SELECT * FROM " + Alarm.TABLE_NAME;
Cursor c = db.rawQuery(select, null);
ArrayList<AlarmModel> alarmList = new ArrayList<AlarmModel>();
while (c.moveToNext()) {
alarmList.add(populateModel(c));
}
if (!alarmList.isEmpty()) {
return alarmList;
}
return null;
}
填充模型函数
private ContentValues populateContent(AlarmModel model) {
ContentValues values = new ContentValues();
values.put(Alarm.COLUMN_NAME_ALARM_NAME, model.name);
values.put(Alarm.COLUMN_NAME_ALARM_TIME_HOUR, model.timeHour);
values.put(Alarm.COLUMN_NAME_ALARM_TIME_MINUTE, model.timeMinute);
values.put(Alarm.COLUMN_NAME_ALARM_REPEAT_WEEKLY, model.repeatWeekly);model.showMathProblem);
values.put(Alarm.COLUMN_NAME_ALARM_TONE, model.alarmTone != null ? model.alarmTone.toString() : "");
values.put(Alarm.COLUMN_NAME_ALARM_ENABLED, model.isEnabled);
String repeatingDays = "";
for (int i = 0; i < 7; ++i) {
repeatingDays += model.getRepeatingDay(i) + ",";
}
values.put(Alarm.COLUMN_NAME_ALARM_REPEAT_DAYS, repeatingDays);
return values;
}
报警模型Calss
public class AlarmModel {
public static final int SUNDAY = 0;
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRDIAY = 5;
public static final int SATURDAY = 6;
public long id = -1;
public int timeHour;
public int timeMinute;
public int snoozeTime;
private boolean repeatingDays[];
public boolean repeatWeekly;
public Uri alarmTone;
public String name;
public boolean isEnabled;
public AlarmModel() {
repeatingDays = new boolean[7];
}
public void setRepeatingDay(int dayOfWeek, boolean value) {
repeatingDays[dayOfWeek] = value;
}
public boolean getRepeatingDay(int dayOfWeek) {
return repeatingDays[dayOfWeek];
}
}
希望这对您有所帮助
我正在创建一个列出即将上映的电影的应用程序,用户为他希望在其发布临近时收到提醒的任何电影设置提醒(他使用 DatePicker 选择弹出通知的日期)。所以你猜对了,每部电影都可以收到通知。我猜想这样做,当用户像这样设置提醒时,我需要将电影的名称和 ID 放在 SharedPreference 中;
public void setAlarm(View view){
Intent alertIntent = new Intent(this, AlertReceiver.class);
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = settings.edit();
editor.putString("name", name);
editor.putInt("id", mainId);
editor.commit();
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set() schedules an alarm to trigger
// FLAG_UPDATE_CURRENT : Update the Intent if active
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, 1, alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
}
然后在 OnRecieve() 方法上我获取 SharedPreference 并使用名称和 ID 构建一条消息
public void onReceive(Context context, Intent intent) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
String name = settings.getString("name", "");
int id = settings.getInt("id", 0);
createNotification(context, "" , name + " Coming soon" , name, id);
}
public void createNotification(Context context, String msg, String msgText, String msgAlert, int id){
// Define an Intent and an action to perform with it by another application
PendingIntent notificIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
// Builds a notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setContentTitle(msg)
.setContentText(msgText)
.setTicker(msgAlert)
.setSmallIcon(R.mipmap.ic_launcher);
//the intent when the notification is clicked on
mBuilder.setContentIntent(notificIntent); //goes to MainActivity
//how the user will be notified
mBuilder.setDefaults(NotificationCompat.DEFAULT_LIGHTS);
//stop notification when it's clicked on
mBuilder.setAutoCancel(true);
//now to notify the user with NotificationManager
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, mBuilder.build());
}
OnReceive 效果很好,但似乎我一次只能创建一个提醒,比如 SharedPreference 用新的覆盖旧的,我想?我是否需要为我 setAlarm() 的每部电影声明一个新的 SharedPreference?然后 BroadcastReceiver 的 OnReceive 方法将从 SharedPreference?
中获取值您的情况不需要 SharedPreference,您可以直接将数据放入意图并在 onReceive 方法中从意图中获取该数据。
如果你想设置多个闹钟(重复或单个),那么你只需要用不同的requestCode创建他们的PendingIntents。如果 requestCode 相同,则新警报将覆盖旧警报。 为此,您可以使用 System.currentTimeMillis();
public void setAlarm(View view){
Intent alertIntent = new Intent(this, AlertReceiver.class);
alertIntent.putExtra("name", name);
alertIntent.putExtra("id", mainId);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set() schedules an alarm to trigger
// FLAG_UPDATE_CURRENT : Update the Intent if active
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime,
PendingIntent.getBroadcast(this, (int) System.currentTimeMillis(), alertIntent,
PendingIntent.FLAG_UPDATE_CURRENT));
}
onReceive 方法从 intent 获取数据
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
//reset your alarm here save your alarms in database or shared //preferences so that you can reset here
}else{
String name = intent.getStringExtra("name", "");
int id = intent.getIntExtra("id", 0);
createNotification(context, "" , name + " Coming soon" , name, id);
}
}
尝试这样的事情
public class AlarmManagerHelper extends BroadcastReceiver {
public static final String ID = "id";
public static final String NAME = "name";
public static final String TIME_HOUR = "timeHour";
public static final String TIME_MINUTE = "timeMinute";
public static final String TONE = "alarmTone";
public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
@Override
public void onReceive(Context context, Intent intent) {
setAlarms(context);
}
public static void setAlarms(Context context) {
cancelAlarms(context);
AlarmDBHelper dbHelper = new AlarmDBHelper(context);
List<AlarmModel> alarms = dbHelper.getAlarms();
if (alarms != null) {
for (AlarmModel alarm : alarms) {
if (alarm.isEnabled) {
PendingIntent pIntent = createPendingIntent(context, alarm);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarm.timeHour);
calendar.set(Calendar.MINUTE, alarm.timeMinute);
calendar.set(Calendar.SECOND, 00);
//Find next time to set
final int nowDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
final int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
final int nowMinute = Calendar.getInstance().get(Calendar.MINUTE);
boolean alarmSet = false;
//First check if it's later in the week
for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek >= nowDay &&
!(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
!(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
setAlarm(context, calendar, pIntent);
alarmSet = true;
setStatusBarIcon(context, alarmSet);
break;
}
}
//Else check if it's earlier in the week
if (!alarmSet) {
for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
if (alarm.getRepeatingDay(dayOfWeek - 1) && dayOfWeek <= nowDay && alarm.repeatWeekly) {
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
calendar.add(Calendar.WEEK_OF_YEAR, 1);
setAlarm(context, calendar, pIntent);
alarmSet = true;
break;
}
}
}
}
}
}
}
@SuppressLint("NewApi")
private static void setAlarm(Context context, Calendar calendar, PendingIntent pIntent) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
}
}
public static void cancelAlarms(Context context) {
AlarmDBHelper dbHelper = new AlarmDBHelper(context);
List<AlarmModel> alarms = dbHelper.getAlarms();
if (alarms != null) {
for (AlarmModel alarm : alarms) {
if (alarm.isEnabled) {
PendingIntent pIntent = createPendingIntent(context, alarm);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pIntent);
}
}
}
}
public static void setStatusBarIcon(Context context, boolean enabled) {
Intent alarmChanged = new Intent(ACTION_ALARM_CHANGED);
alarmChanged.putExtra("alarmSet", enabled);
context.sendBroadcast(alarmChanged);
}
private static PendingIntent createPendingIntent(Context context, AlarmModel model) {
Intent intent = new Intent(context, AlarmService.class);
intent.putExtra(ID, model.id);
intent.putExtra(NAME, model.name);
intent.putExtra(TIME_HOUR, model.timeHour);
intent.putExtra(TIME_MINUTE, model.timeMinute);
intent.putExtra(TONE, model.alarmTone.toString());
return PendingIntent.getService(context, (int) model.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
从数据库中获取所有警报的函数
public ArrayList<AlarmModel> getAlarms() {
SQLiteDatabase db = this.getReadableDatabase();
String select = "SELECT * FROM " + Alarm.TABLE_NAME;
Cursor c = db.rawQuery(select, null);
ArrayList<AlarmModel> alarmList = new ArrayList<AlarmModel>();
while (c.moveToNext()) {
alarmList.add(populateModel(c));
}
if (!alarmList.isEmpty()) {
return alarmList;
}
return null;
}
填充模型函数
private ContentValues populateContent(AlarmModel model) {
ContentValues values = new ContentValues();
values.put(Alarm.COLUMN_NAME_ALARM_NAME, model.name);
values.put(Alarm.COLUMN_NAME_ALARM_TIME_HOUR, model.timeHour);
values.put(Alarm.COLUMN_NAME_ALARM_TIME_MINUTE, model.timeMinute);
values.put(Alarm.COLUMN_NAME_ALARM_REPEAT_WEEKLY, model.repeatWeekly);model.showMathProblem);
values.put(Alarm.COLUMN_NAME_ALARM_TONE, model.alarmTone != null ? model.alarmTone.toString() : "");
values.put(Alarm.COLUMN_NAME_ALARM_ENABLED, model.isEnabled);
String repeatingDays = "";
for (int i = 0; i < 7; ++i) {
repeatingDays += model.getRepeatingDay(i) + ",";
}
values.put(Alarm.COLUMN_NAME_ALARM_REPEAT_DAYS, repeatingDays);
return values;
}
报警模型Calss
public class AlarmModel {
public static final int SUNDAY = 0;
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
public static final int THURSDAY = 4;
public static final int FRDIAY = 5;
public static final int SATURDAY = 6;
public long id = -1;
public int timeHour;
public int timeMinute;
public int snoozeTime;
private boolean repeatingDays[];
public boolean repeatWeekly;
public Uri alarmTone;
public String name;
public boolean isEnabled;
public AlarmModel() {
repeatingDays = new boolean[7];
}
public void setRepeatingDay(int dayOfWeek, boolean value) {
repeatingDays[dayOfWeek] = value;
}
public boolean getRepeatingDay(int dayOfWeek) {
return repeatingDays[dayOfWeek];
}
}
希望这对您有所帮助