The Helper class I picked from the official android documentation. Is there anything I am missing that prevents the bubble from appearing?
@RequiresApi(Build.VERSION_CODES.Q)
class NotificationHelper(private val context: Context, val shortcutId: String) {
companion object {
/**
* The notification channel for messages. This is used for showing Bubbles.
*/
private const val CHANNEL_NEW_MESSAGES = "new_messages"
private const val REQUEST_CONTENT = 1
private const val REQUEST_BUBBLE = 2
}
private val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
private val shortcutManager: ShortcutManager =
context.getSystemService(Context.SHORTCUT_SERVICE) as ShortcutManager
private fun setUpNotificationChannels() {
if (notificationManager.getNotificationChannel(CHANNEL_NEW_MESSAGES) == null) {
notificationManager.createNotificationChannel(
NotificationChannel(
CHANNEL_NEW_MESSAGES,
context.getString(R.string.title_float),
NotificationManager.IMPORTANCE_HIGH
).apply {
description = context.getString(R.string.description_float)
setAllowBubbles(true)
lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC
}
)
}
updateShortcuts()
}
private fun getPerson(): Person {
return Person.Builder()
.setIcon(IconCompat.createWithResource(context, R.drawable.silhouette))
.setName(context.getString(R.string.app_name))
.setKey(context.getString(R.string.app_name))
.setImportant(true)
.build()
}
@WorkerThread
fun updateShortcuts(): ShortcutInfoCompat {
// Create a dynamic shortcut for each of the contacts.
// The same shortcut ID will be used when we show a bubble notification.
return ShortcutInfoCompat.Builder(context, shortcutId)
.setLocusId(LocusIdCompat.toLocusIdCompat(LocusId(shortcutId)))
.setActivity(ComponentName(context, FragmentActivityMain::class.java))
.setShortLabel(context.getString(R.string.app_name))
.setLongLived(true)
.setRank(1)
.setIcon(IconCompat.createWithResource(context, R.drawable.silhouette))
.setCategories(setOf("com.example.android.bubbles.category.TEXT_SHARE_TARGET"))
.setIntent(
Intent(context, FragmentActivityMain::class.java)
.setAction(Intent.ACTION_VIEW)
)
.setPerson(
getPerson()
)
.build()
}
@WorkerThread
fun showNotification(fromUser: Boolean) {
val icon = IconCompat.createWithResource(context, R.drawable.silhouette)
val pendingIntent = PendingIntent.getActivity(
context,
REQUEST_BUBBLE,
// Launch BubbleActivity as the expanded bubble.
Intent(context, FragmentActivityMain::class.java)
.setAction(Intent.ACTION_VIEW),
PendingIntent.FLAG_UPDATE_CURRENT
)
val style = NotificationCompat.MessagingStyle(getPerson())
.addMessage("test Message!", System.currentTimeMillis(), getPerson())
.setGroupConversation(false)
var builder = NotificationCompat.Builder(context, CHANNEL_NEW_MESSAGES)
// A notification can be shown as a bubble by calling setBubbleMetadata()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
builder = builder.setBubbleMetadata(
NotificationCompat.BubbleMetadata.Builder()
// The height of the expanded bubble.
.setIntent(pendingIntent)
.setIcon(icon)
.setDesiredHeight(600)
.apply {
if (fromUser) {
setAutoExpandBubble(true)
setSuppressNotification(true)
}
}
.build()
)
}
// The user can turn off the bubble in system settings. In that case, this notification
// is shown as a normal notification instead of a bubble. Make sure that this
// notification works as a normal notification as well.
builder = builder.setContentTitle(context.getString(R.string.app_name))
.setSmallIcon(R.drawable.silhouette)
.setCategory(Notification.CATEGORY_MESSAGE)
.setShortcutInfo(updateShortcuts())
.addPerson(getPerson())
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setShowWhen(true)
.setStyle(style)
// The content Intent is used when the user clicks on the "Open Content" icon button on
// the expanded bubble, as well as when the fall-back notification is clicked.
.setContentIntent(
PendingIntent.getActivity(
context,
REQUEST_CONTENT,
Intent(context, FragmentActivityMain::class.java)
.setAction(Intent.ACTION_VIEW),
PendingIntent.FLAG_UPDATE_CURRENT
)
)
setUpNotificationChannels()
notificationManager.notify(888, builder.build())
}
fun dismissNotification(id: Long) {
notificationManager.cancel(id.toInt())
}
}
And I am calling it using
NotificationHelper notificationHelper = new NotificationHelper(context, String.valueOf(System.currentTimeMillis()));
notificationHelper.showNotification(true);
Update Here is the manifest -
<activity
android:name=".display.FragmentActivityMain"
android:allowEmbedded="true"
android:configChanges="keyboardHidden|orientation|screenLayout"
android:launchMode="singleTask"
android:resizeableActivity="true"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>