0

I'm creating an app that lists upcoming movies, the user sets a reminder for any movie he wants to be reminded about when its release is approaching (using DatePicker he chooses the date when the notification will pop up). So you guessed it each movie will be capable to ho have a notification. I'm guessing to do this, I need to put the movie's name and id in a SharedPreference when the user sets the reminder like so;

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));
}

Then on the OnRecieve() method I get the SharedPreference and use the name and id to build a message

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 works great, but it seems I could only create one reminder at a time, like SharedPreference overwrite the old with the new, i think? Do I need to declare a new SharedPreference for each movie I setAlarm() to? Then the BroadcastReceiver's OnReceive method will get the values out of the SharedPreference?

2 Answers2

0

SharedPreference is not required in your case, you can directly put data to intent and get that data from intent in onReceive method.

If you want to set multiple alarms (repeating or single), then you just need to create their PendingIntents with different requestCode. If requestCode is the same, then the new alarm will overwrite the old one. For this you can use 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 method get data from 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);
}
    }
USKMobility
  • 5,721
  • 2
  • 27
  • 34
  • Yours is perfect, but there's a slight problem after I reboot my phone, the intents get deleted (don't know the proper term). Instead of showing a message like "THIS movie is out" , it shows instead "null is out", and it only shows one notification, no more than one, so BroadcastReceiver only reminds me about the last movie I last set a reminder to, thanks! –  Oct 17 '15 at 03:22
  • use alarmManager.setRepeating in place of alarmManager.set – USKMobility Oct 17 '15 at 08:05
  • and will the movie name save in the device? Instead of saying "null is out" –  Oct 21 '15 at 03:02
  • and btw what do you mean by reset your alarm here and save in the onReceive() method in the BroadcastReceiver class?, thanks!! –  Nov 06 '15 at 04:38
  • what does if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) { mean? –  Nov 14 '15 at 02:41
0

try something like this

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);
    }
}

function for getting all Alarms from DB

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;
    }

populateModel function

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;
    }

Alarm model 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];
    }

}

hope this will help you

Mustanser Iqbal
  • 5,017
  • 4
  • 18
  • 36