如何在应用程序中设置多个 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];
    }

}

希望这对您有所帮助