0

I'll explain briefly what I need to achieve, I have used the PendingIntent in combination with AlarmManager.setRepeating() to notify the user every week.

val notificationAlarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val notificationIntent = Intent(this, ReminderBroadcastReceiver::class.java)
val pendingNotificationIntent = PendingIntent.getBroadcast(this, 549078, notificationIntent,
        PendingIntent.FLAG_UPDATE_CURRENT)
 myCalendar.set(Calendar.HOUR_OF_DAY, 10)
 notificationAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, myCalendar.timeInMillis, notificationOffset(sub.cycle),
                    pendingNotificationIntent)

As you can see now I am forcing the 549078 as a resultCode in the PendingIntent.getBroadcast().

What is the correct way to differenciate between the result codes, so that I not only can have multiple notifications (since the same resultCode will be overwritten when I create a new one) but I also need a way to keep track of the result code, because I may want to delete it before it is being shown.

Daniele
  • 4,163
  • 7
  • 44
  • 95
  • "Result code" is something that comes back from starting an activity for result. I assume you mean pending intent request code. You may want to update your question accordingly. – Jeffrey Blattman May 02 '18 at 21:37
  • @JeffreyBlattman yes, you are right, I mean request code, will update the question – Daniele May 02 '18 at 21:54

2 Answers2

2

It is not possible to query the AlarmManager for the PendingIntents. You must store the resultCode and other information to recreate the PendingIntent in order to delete it.

For example in SharedPreferences or in a database like SqliteDB or Room. Then you can recreate the PendingIntent to cancel it.

See how to cancel PendingIntent.

See How does android compare pending intents for details on what fields are important when comparing the intents for deletion.

leonardkraemer
  • 6,573
  • 1
  • 31
  • 54
  • ok I see, should I just use an incremental request code or should I find some criteria and build it from there? – Daniele May 02 '18 at 21:56
  • 1
    If it makes sense for your app an incremental request code is fine. If you have some Alarms that are always the same you can use the same code for them, that way only you can make sure that only one alarm of that type can be present at a time. – leonardkraemer May 02 '18 at 22:03
  • 2
    One thing, if you use Fragments the code must be below 65535 see https://stackoverflow.com/questions/33331073/android-what-to-choose-for-requestcode-values/33331459 – leonardkraemer May 02 '18 at 22:06
  • I will keep that in mind and implement this tomorrow, thanks a lot – Daniele May 02 '18 at 22:09
  • ok I found a way to have a unique `requestCode` for every notification, what are the "other information" I need to store that you are talking about exactly? Now quite getting how to cancel the intent – Daniele May 03 '18 at 11:49
  • see [`AlarmManager.cancel(android.app.PendingIntent)`](https://developer.android.com/reference/android/app/AlarmManager.html#cancel(android.app.PendingIntent)) – leonardkraemer May 03 '18 at 14:21
0

I was facing the same problem, what I did was as follow:

1) I created an int field which I create in my main activity as a static field.

2) I get the value of this variable in onCreate() of the main activity from the application database.

3) Every time I am creating a new alarm I get a new request code through a function as follows:

public static int getRequestCode() {
    int temp = this.requestCode++;
    // Update the database value with the current requestCode value
    return temp;
}

4) In my case I added a new field to the alarm class called requestCode so I can keep track of which request code is for which alarm as I am already saving the alarms in my database, for your case I am not sure how exactly is your application but I guess you need to find a way to store this value for each alarm.

I am not sure this will be very helpful since I am not sure if you are using a database for your app or not, but I recommend you consider creating one, even a local one if you don't care about having your data on a server yet ( you can use Room Library for that and it's very straight forward, here's a link https://developer.android.com/topic/libraries/architecture/room ) as I believe this will definitely create you many problems on the long run, since the system doesn't really create a new PendingIntent when you initiate one, it returns the exciting token if all parameters match

Hope this was helpful :)

Pierre Ghaly
  • 777
  • 2
  • 7
  • 17
  • That will fail if your process is killed. You will lose your static counter. It's also not clear why you'd write the value to the DB if you never read it. – Jeffrey Blattman May 02 '18 at 21:42
  • Exactly for this reason I save it to my database, as I get the value for this counter *(as mentioned in step 2)* from the database `onCreate()`. So when my process is killed, on re-start the value will be retrieved from database with the last value it had and and I will increment from there again not from the beginning. Also as mentioned in another answer, SharedPreferences should be a good way to store it as well. – Pierre Ghaly May 02 '18 at 21:50
  • Why not have one single method for accessing the value? – Jeffrey Blattman May 02 '18 at 21:56
  • I am not sure what you mean? Can you please clarify? @JeffreyBlattman – Pierre Ghaly May 02 '18 at 22:16
  • 1
    Yea now I get it. Well I am actually not taking the value manually on start, I just assign it in the `onChildAdded` method in Firebase `ChildListener`, but I am considering moving it locally as I started to realize it might create bugs later on. Thanks for the hint though, appreciated :) – Pierre Ghaly May 02 '18 at 22:40