3

i am working on an App in which i want to save the pending intent into shared preference and perform some action on app if that pending intent exist in shared preferences.

Reference Link :

Store ArrayList<PendingIntent> into SharedPreferences

but no solution found in this link as well.

if someone know how can i do this then plz let me know.

Thanks.

Fahad Shahid
  • 123
  • 6
  • I just added an answer to the linked question. That should help you. – David Wasser Apr 01 '18 at 16:16
  • Why do you want to save the `PendingIntent`s to `SharedPreferences`? I doubt that this is the correct solution to whatever it is you are trying to do. – David Wasser Apr 01 '18 at 16:30
  • thanks for the solution. i you have multiples alarms and you want to cancel few of them.then i think we can cancel only through its pending intent. that is the reason why i am saving pending intent. is my approach right for this ? – Fahad Shahid Apr 02 '18 at 06:16
  • No this is the wrong approach. I've added an answer. If you post the code that you use to create the `PendingIntent` to set the alarms, I can edit my code to match yours. – David Wasser Apr 02 '18 at 07:42

2 Answers2

3

You wrote in a comment:

If you have multiple alarms and you want to cancel a few of them, then I think we can cancel only through its PendingIntent. That is the reason why I am saving PendingIntent. Is my approach right for this?

No. This isn't the right approach to solve this problem.

Yes, you'll need to provide a PendingIntent to AlarmManager.cancel(). However, you don't need to save the PendingIntent in a persistent store. What you need to do is to save enough information in the persistent store so that you can recreate the PendingIntent.

To recreate the PendingIntent you just do this:

Intent intent = new Intent(context, MyActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, intent, PendingIntent.NO_CREATE);
if (pendingIntent != null) {
    alarmManager.cancel(pendingIntent); // cancel alarm
    pendingIntent.cancel(); // delete the PendingIntent
}

I've used an Activity in the example code, but you can also use a Service or BroadcastReceiver, whatever you are using in your code.

You do NOT need to add any extras to the Intent if you just want to use it to cancel an existing alarm.

If you have multiple alarms, the Intents must be unique. You just need to save whatever you are using to make them unique (requestCode, or Intent ACTION, or whatever) and then use the same parameters to recreate the PendingIntent when you want to cancel the alarms.

David Wasser
  • 93,459
  • 16
  • 209
  • 274
0

You can convert it to bytes-array and back, by using this class I've made (found somewhere else) :

object PendingIntentUtil {
    @JvmStatic
    fun marshall(parcelable: Parcelable): ByteArray {
        val parcel = Parcel.obtain()
        parcelable.writeToParcel(parcel, 0)
        val bytes = parcel.marshall()
        parcel.recycle()
        return bytes
    }

    @JvmStatic
    fun <T> unmarshall(bytes: ByteArray, creator: Parcelable.Creator<T>): T {
        val parcel = Parcel.obtain()
        parcel.unmarshall(bytes, 0, bytes.size)
        parcel.setDataPosition(0)
        val result = creator.createFromParcel(parcel)
        parcel.recycle()
        return result
    }

    @JvmStatic
    fun marshallSerializable(serializable: Serializable): ByteArray? {
        val bos = ByteArrayOutputStream()
        val out: ObjectOutput
        try {
            out = ObjectOutputStream(bos)
            out.writeObject(serializable)
            out.flush()
            return bos.toByteArray()
        } catch (ignored: IOException) {
        } finally {
            closeQuietly(bos)
        }
        return null
    }

    @JvmStatic
    fun <T> unmarshallSerializable(bytes: ByteArray?): T? {
        if (bytes == null) return null
        val bis = ByteArrayInputStream(bytes)
        var objectInput: ObjectInput? = null
        try {
            objectInput = ObjectInputStream(bis)
            @Suppress("UNCHECKED_CAST")
            return objectInput.readObject() as T
        } catch (e: ClassNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            closeQuietly(objectInput)
        }
        return null
    }
}
android developer
  • 114,585
  • 152
  • 739
  • 1,270