I'm trying to send a notification from Firebase with some info. Then, when the message is received I want to create a notification that has an action when a button on that notification is clicked. I want that action to be an IntentChooser. I'm creating the notification like so:
val intentChooser: Intent = IntentUtils.getChoosingIntent(this)
val pendingIntent =
PendingIntent.getActivity(
this,
reqCode,
intentChooser,
PendingIntent.FLAG_IMMUTABLE
)
val CHANNEL_ID = "channel_name" // The id of the channel.
val notificationBuilder: NotificationCompat.Builder =
NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(it.title)
.setContentText(it.body)
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentIntent(pendingIntent)
.addAction(
NotificationCompat.Action(
R.drawable.baseline_assistant_direction_24,
"Directions",
pendingIntent
)
)
val notificationManager =
this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
val name: CharSequence = "Channel Name" // The user-visible name of the channel.
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(CHANNEL_ID, name, importance)
notificationManager.createNotificationChannel(mChannel)
notificationManager.notify(
reqCode,
notificationBuilder.build()
) // 0 is the request code, it should be unique id
And the getChoosingIntent()
is this:
fun getChoosingIntent(context: Context, lat: Double, long: Double): Intent {
val arr = arrayListOf<Intent>()
val intent1 = Intent(Intent.ACTION_VIEW, Uri.parse(someUri))
intent1.setPackage(somePackage)
arr.add(intent1)
val intent2 = Intent(Intent.ACTION_VIEW, Uri.parse(someUri))
intent2.setPackage(somePackage)
arr.add(intent2)
val mainIntent = Intent(Intent.ACTION_VIEW)
val title = "title"
val chooserIntent = Intent.createChooser(mainIntent, title)
chooserIntent.putParcelableArrayListExtra(Intent.EXTRA_INITIAL_INTENTS, arr)
chooserIntent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
return chooserIntent
}
This is throwing an error:
Attempt to cast generated internal exception:
java.lang.ClassCastException: java.util.ArrayList cannot be cast to android.os.Parcelable[]
at android.os.Bundle.getParcelableArray(Bundle.java:980)
at android.content.Intent.getParcelableArrayExtra(Intent.java:8974)
at android.content.Intent.migrateExtraStreamToClipData(Intent.java:12111)
at android.app.PendingIntent.getActivityAsUser(PendingIntent.java:486)
at android.app.PendingIntent.getActivity(PendingIntent.java:470)
at android.app.PendingIntent.getActivity(PendingIntent.java:434)
at com.rfsfernandes.findmyhere.firebase.MobileFirebaseMessageService.onMessageReceived(MobileFirebaseMessageService.kt:46)
at com.google.firebase.messaging.FirebaseMessagingService.dispatchMessage(FirebaseMessagingService.java:243)
at com.google.firebase.messaging.FirebaseMessagingService.passMessageIntentToSdk(FirebaseMessagingService.java:193)
at com.google.firebase.messaging.FirebaseMessagingService.handleMessageIntent(FirebaseMessagingService.java:179)
at com.google.firebase.messaging.FirebaseMessagingService.handleIntent(FirebaseMessagingService.java:168)
at com.google.firebase.messaging.EnhancedIntentService.lambda$processIntent$0$com-google-firebase-messaging-EnhancedIntentService(EnhancedIntentService.java:82)
at com.google.firebase.messaging.EnhancedIntentService$$ExternalSyntheticLambda0.run(Unknown Source:6)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at com.google.android.gms.common.util.concurrent.zza.run(com.google.android.gms:play-services-basement@@18.1.0:2)
at java.lang.Thread.run(Thread.java:1012)
Is there something else that I should try? I really don't want to manually create a chooser
try this
fun getChoosingIntent(context: Context, lat: Double, long: Double): Intent {
val gmmIntentUri = Uri.parse("geo:$lat,$long?q=$lat,$long")
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
val chooserIntent = Intent.createChooser(mapIntent, "Open with")
val otherIntents = ArrayList<Intent>()
val additionalIntent = Intent(Intent.ACTION_VIEW, Uri.parse("someUri"))
additionalIntent.setPackage("com.example.app")
otherIntents.add(additionalIntent)
if (otherIntents.isNotEmpty()) {
val extraIntents = otherIntents.toTypedArray()
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents)
}
return chooserIntent
}
and where you handle the notification use something like this
val intentChooser = getChoosingIntent(this, latitude, longitude) // Replace with actual values
val pendingIntent = PendingIntent.getActivity(
this,
reqCode,
intentChooser,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)