如何将PendingIntent存入SharedPreferences并在其存在时执行操作?
Hey there! Storing a PendingIntent directly in SharedPreferences isn't straightforward because it's a complex object that can't be serialized like primitive types (strings, integers, etc.). But since PendingIntent implements the Parcelable interface, we can use that to convert it to a byte array—this lets us save it to SharedPreferences and reconstruct it later. Here's a step-by-step solution:
Step 1: Create Utility Functions for Conversion
First, make helper functions to convert between PendingIntent and ByteArray:
import android.os.Parcel import android.app.PendingIntent fun pendingIntentToBytes(pendingIntent: PendingIntent): ByteArray { val parcel = Parcel.obtain() pendingIntent.writeToParcel(parcel, 0) val bytes = parcel.marshall() parcel.recycle() // Always recycle parcels to avoid memory leaks return bytes } fun bytesToPendingIntent(bytes: ByteArray): PendingIntent? { val parcel = Parcel.obtain() parcel.unmarshall(bytes, 0, bytes.size) parcel.setDataPosition(0) // Reset parcel position to start reading val pendingIntent = PendingIntent.CREATOR.createFromParcel(parcel) parcel.recycle() return pendingIntent }
Step 2: Save PendingIntent to SharedPreferences
Once you have your PendingIntent instance, convert it to a byte array and store it:
import android.content.Context import android.content.Intent // Example: Create a PendingIntent for an Activity val intent = Intent(context, YourTargetActivity::class.java) val myPendingIntent = PendingIntent.getActivity( context, 0, // Request code (use a unique value if you have multiple PendingIntents) intent, PendingIntent.FLAG_IMMUTABLE // Use FLAG_MUTABLE if you need to modify the intent later ) // Save to SharedPreferences val sharedPrefs = context.getSharedPreferences("AppPreferences", Context.MODE_PRIVATE) sharedPrefs.edit() .putByteArray("stored_pending_intent", pendingIntentToBytes(myPendingIntent)) .apply()
Step 3: Retrieve and Use the Stored PendingIntent
Later, check if the PendingIntent exists in SharedPreferences, reconstruct it, and perform your specific action:
val sharedPrefs = context.getSharedPreferences("AppPreferences", Context.MODE_PRIVATE) val storedPiBytes = sharedPrefs.getByteArray("stored_pending_intent", null) storedPiBytes?.let { bytes -> val retrievedPendingIntent = bytesToPendingIntent(bytes) retrievedPendingIntent?.let { pi -> // Execute your specific operation here try { pi.send() // Example: Trigger the PendingIntent } catch (e: PendingIntent.CanceledException) { // Handle case where the PendingIntent is no longer valid e.printStackTrace() } } }
Important Notes
- PendingIntent Validity: A stored
PendingIntentmight become invalid if the target component (Activity/Service/BroadcastReceiver) is updated, uninstalled, or if the app's package name changes. Always handle exceptions likeCanceledExceptionand consider clearing stored PendingIntents when your app is updated. - Flags: Use
FLAG_IMMUTABLE(default for API 31+) unless you need to modify the intent later (useFLAG_MUTABLEin that case). Using the wrong flag can cause runtime errors on newer Android versions. - Multiple PendingIntents: If you need to store an
ArrayList<PendingIntent>, convert each to a byte array, then use a library like Gson to convert the list of byte arrays to a JSON string for storage, or use aParcelablearray.
内容的提问来源于stack exchange,提问作者Fahad Shahid

