By default, notifications are bridged (shared) from an app on a phone to any paired watches. If you build a watch app and your app also exists on a paired phone, the app may create duplicate notifications. Wear OS includes features to handle this problem.
Avoid duplicate notifications
When you create notifications from an external source, such as from Firebase Cloud Messaging, your mobile app and your wearable app may each display its own notifications on the watch. To avoid this sort of duplication, you disable bridging from your wearable app when it is installed.
1. In the mobile app, use bridge tags when applicable
If you want to bridge some of the notifications created on your mobile app to the watch when your wearable app is installed, set bridge tags.
Set a bridge tag
Set a bridge tag on a notification by using the
setBridgeTag(String)
method as shown in the following code sample:
val notification = NotificationCompat.Builder(context, channelId) // ... set other fields ... .extend( NotificationCompat.WearableExtender() .setBridgeTag("foo") ) .build()
2. In the wearable app, disable bridging
If you are using bridge tags, disable bridging at run time.
Disable bridging with exceptions
You can set a bridging mode, and optionally set tags for notifications that are exempt from the
bridging mode, using a BridgingManager
object. Create a
BridgingConfig
object as shown in this section.
You can disable bridging for all notifications, except those with certain tags.
For example, you can disable bridging for all notifications except those tagged as
foo
, bar
, or baz
as shown in the following sample:
BridgingManager.fromContext(context).setConfig( BridgingConfig.Builder(context, false) .addExcludedTags(listOf("foo", "bar", "baz")) .build() )
Disable bridging for all notifications
If you aren't using bridge tags from mobile, prevent bridging of all notifications from a
phone app. Use the <meta-data>
entry in the manifest file of the
watch app, as shown in the following example:
com.google.android.wearable.notificationBridgeMode
Add that <meta-data>
entry as a child of the <application>
element. Set the meta-data entry to NO_BRIDGING
as shown in the following example:
<application> ... <meta-data android:name="com.google.android.wearable.notificationBridgeMode" android:value="NO_BRIDGING" /> ... </application>
The default bridging behavior occurs if you do not include the
<meta-data>
entry or if you set the value to BRIDGING
instead of
NO_BRIDGING
.
The bridging configuration that is set in the manifest takes effect as soon as a watch app is installed.
Note: Specifying a bridging configuration at runtime overrides a bridging-related setting in the Android manifest file.
3. Set a dismissal ID to sync similar notifications on Wear OS and mobile
When you prevent bridging with the bridging mode feature, dismissals of notifications are not synced across a user's devices.
However, if similar notifications are created on both mobile and the watch, you still want both notifications dismissed if the user dismisses any one of them.
In the
NotificationCompat.WearableExtender
,
you can set a global unique id, so that when one notification is dismissed, other notifications
with the same ID on paired watch(es) will also be dismissed.
The
NotificationCompat.WearableExtender
class has methods that enable you to use dismissal IDs, as shown in the following example:
fun setDismissalId(dismissalId: String): WearableExtender fun getDismissalId(): String
To sync a dismissal, use the
setDismissalId()
method. For each notification, pass a globally unique ID, as a string, when you call the
setDismissalId()
method.
When the notification is dismissed, all other notifications with the same dismissal ID are
dismissed on the watch(es) and on the phone. To retrieve a dismissal ID, use
getDismissalId()
.
In the following example, syncing of dismissals is enabled because a globally unique ID is specified for a new notification:
val notification = NotificationCompat.Builder(context, channelId) // ... set other fields ... .extend( NotificationCompat.WearableExtender() .setDismissalId("abc123") ) .build()
Note: Dismissal IDs work if a watch is paired to an Android phone, but not if a watch is paired to an iPhone.
When notifications aren't bridged
Notifications are not bridged in the following cases:
- Local-only notifications set using
Notification.Builder.setLocalOnly(boolean)
. - Ongoing notifications set using
Notification.Builder.setOngoing(boolean)
orNotification.FLAG_ONGOING_EVENT
. - Non-clearable notifications set using
Notification.FLAG_NO_CLEAR
. - Notifications where the counterpart wearable app has disabled notification bridging.
Best practices for bridged notifications
It takes time to push or remove bridged notifications from a wearable device. As you design your notifications, make sure to avoid unexpected behavior caused by this latency. The following guidelines ensure that your bridged notifications work with asynchronous notifications:
- If you cancel a notification on the phone, it may take some time to cancel the corresponding notification on the watch. During this time, a user could send one of the pending intents on that notification. For this reason, your app should receive pending intents from notifications it has canceled. Thus, when canceling notifications, make sure to keep those notifications’ pending intent receivers valid.
- Don't cancel and retrigger an entire stack of notifications at one time. Only modify or remove the notifications that have actually been modified. This avoids the latency on updating the wearable device and ensures that the impact of your app on battery life is minimal.
Design considerations
Wear OS notifications have their own design guidelines. For more information, review the Wear OS Design Guidelines.