diff --git a/push-notifications/README.md b/push-notifications/README.md index 8ff76a92e..26861450c 100644 --- a/push-notifications/README.md +++ b/push-notifications/README.md @@ -54,11 +54,11 @@ Android Studio has an icon generator you can use to create your Push Notificatio -On iOS you can configure the way the push notifications are displayed when the app is in foreground. +You can configure the way the push notifications are displayed when the app is in foreground. -| Prop | Type | Description | Since | -| ------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | -| **`presentationOptions`** | PresentationOption[] | This is an array of strings you can combine. Possible values in the array are: - `badge`: badge count on the app icon is updated (default value) - `sound`: the device will ring/vibrate when the push notification is received - `alert`: the push notification is displayed in a native dialog An empty array can be provided if none of the options are desired. Only available for iOS. | 1.0.0 | +| Prop | Type | Description | Since | +| ------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | +| **`presentationOptions`** | PresentationOption[] | This is an array of strings you can combine. Possible values in the array are: - `badge`: badge count on the app icon is updated (default value) - `sound`: the device will ring/vibrate when the push notification is received - `alert`: the push notification is displayed in a native dialog An empty array can be provided if none of the options are desired. badge is only available for iOS. | 1.0.0 | ### Examples @@ -463,17 +463,17 @@ Remove all native listeners for this plugin. #### Channel -| Prop | Type | Description | Default | Since | -| ----------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----- | -| **`id`** | string | The channel identifier. | | 1.0.0 | -| **`name`** | string | The human-friendly name of this channel (presented to the user). | | 1.0.0 | -| **`description`** | string | The description of this channel (presented to the user). | | 1.0.0 | -| **`sound`** | string | The sound that should be played for notifications posted to this channel. Notification channels with an importance of at least `3` should have a sound. The file name of a sound file should be specified relative to the android app `res/raw` directory. | | 1.0.0 | -| **`importance`** | Importance | The level of interruption for notifications posted to this channel. | 3 | 1.0.0 | -| **`visibility`** | Visibility | The visibility of notifications posted to this channel. This setting is for whether notifications posted to this channel appear on the lockscreen or not, and if so, whether they appear in a redacted form. | | 1.0.0 | -| **`lights`** | boolean | Whether notifications posted to this channel should display notification lights, on devices that support it. | | 1.0.0 | -| **`lightColor`** | string | The light color for notifications posted to this channel. Only supported if lights are enabled on this channel and the device supports it. Supported color formats are `#RRGGBB` and `#RRGGBBAA`. | | 1.0.0 | -| **`vibration`** | boolean | Whether notifications posted to this channel should vibrate. | | 1.0.0 | +| Prop | Type | Description | Default | Since | +| ----------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----- | +| **`id`** | string | The channel identifier. | | 1.0.0 | +| **`name`** | string | The human-friendly name of this channel (presented to the user). | | 1.0.0 | +| **`description`** | string | The description of this channel (presented to the user). | | 1.0.0 | +| **`sound`** | string | The sound that should be played for notifications posted to this channel. Notification channels with an importance of at least `3` should have a sound. The file name of a sound file should be specified relative to the android app `res/raw` directory. | | 1.0.0 | +| **`importance`** | Importance | The level of interruption for notifications posted to this channel. | `3` | 1.0.0 | +| **`visibility`** | Visibility | The visibility of notifications posted to this channel. This setting is for whether notifications posted to this channel appear on the lockscreen or not, and if so, whether they appear in a redacted form. | | 1.0.0 | +| **`lights`** | boolean | Whether notifications posted to this channel should display notification lights, on devices that support it. | | 1.0.0 | +| **`lightColor`** | string | The light color for notifications posted to this channel. Only supported if lights are enabled on this channel and the device supports it. Supported color formats are `#RRGGBB` and `#RRGGBBAA`. | | 1.0.0 | +| **`vibration`** | boolean | Whether notifications posted to this channel should vibrate. | | 1.0.0 | #### ListChannelsResult diff --git a/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/NotificationChannelManager.java b/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/NotificationChannelManager.java index 1bfeaff40..60458a997 100644 --- a/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/NotificationChannelManager.java +++ b/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/NotificationChannelManager.java @@ -4,25 +4,29 @@ import android.app.NotificationManager; import android.content.ContentResolver; import android.content.Context; -import android.graphics.Color; import android.media.AudioAttributes; import android.net.Uri; +import android.os.Build; +import android.provider.Settings; import androidx.core.app.NotificationCompat; -import com.getcapacitor.JSArray; -import com.getcapacitor.JSObject; -import com.getcapacitor.Logger; -import com.getcapacitor.PluginCall; +import com.getcapacitor.*; import com.getcapacitor.util.WebColor; +import java.util.Arrays; import java.util.List; public class NotificationChannelManager { + public static final String FOREGROUND_NOTIFICATION_CHANNEL_ID = "PushDefaultForeground"; + private Context context; private NotificationManager notificationManager; + private PluginConfig config; - public NotificationChannelManager(Context context, NotificationManager manager) { + public NotificationChannelManager(Context context, NotificationManager manager, PluginConfig config) { this.context = context; this.notificationManager = manager; + this.config = config; + createForegroundNotificationChannel(); } private static String CHANNEL_ID = "id"; @@ -136,4 +140,35 @@ public void listChannels(PluginCall call) { call.unavailable(); } } + + /** + * Create notification channel + */ + public void createForegroundNotificationChannel() { + // Create the NotificationChannel only if presentationOptions is defined + // Because the channel can't be changed after creation + String[] presentation = config.getArray("presentationOptions"); + if (presentation != null) { + // And only on API 26+ because the NotificationChannel class + // is new and not in the support library + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + CharSequence name = "Push Notifications Foreground"; + String description = "Push notifications in foreground"; + int importance = NotificationManager.IMPORTANCE_HIGH; + NotificationChannel channel = new NotificationChannel(FOREGROUND_NOTIFICATION_CHANNEL_ID, name, importance); + channel.setDescription(description); + if (Arrays.asList(presentation).contains("sound")) { + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ALARM) + .build(); + channel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, audioAttributes); + } + // Register the channel with the system; you can't change the importance + // or other notification behaviors after this + android.app.NotificationManager notificationManager = context.getSystemService(android.app.NotificationManager.class); + notificationManager.createNotificationChannel(channel); + } + } + } } diff --git a/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/PushNotificationsPlugin.java b/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/PushNotificationsPlugin.java index 49bb99fd9..0cee22647 100644 --- a/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/PushNotificationsPlugin.java +++ b/push-notifications/android/src/main/java/com/capacitorjs/plugins/pushnotifications/PushNotificationsPlugin.java @@ -4,22 +4,19 @@ import android.app.NotificationManager; import android.content.Context; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.service.notification.StatusBarNotification; -import com.getcapacitor.Bridge; -import com.getcapacitor.JSArray; -import com.getcapacitor.JSObject; -import com.getcapacitor.Plugin; -import com.getcapacitor.PluginCall; -import com.getcapacitor.PluginHandle; -import com.getcapacitor.PluginMethod; +import androidx.core.app.NotificationCompat; +import com.getcapacitor.*; import com.getcapacitor.annotation.CapacitorPlugin; import com.getcapacitor.annotation.Permission; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.RemoteMessage; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.json.JSONException; import org.json.JSONObject; @@ -46,7 +43,7 @@ public void load() { lastMessage = null; } - notificationChannelManager = new NotificationChannelManager(getActivity(), notificationManager); + notificationChannelManager = new NotificationChannelManager(getActivity(), notificationManager, getConfig()); } @Override @@ -215,8 +212,30 @@ public void fireNotification(RemoteMessage remoteMessage) { RemoteMessage.Notification notification = remoteMessage.getNotification(); if (notification != null) { - remoteMessageData.put("title", notification.getTitle()); - remoteMessageData.put("body", notification.getBody()); + String title = notification.getTitle(); + String body = notification.getBody(); + String[] presentation = getConfig().getArray("presentationOptions"); + if (presentation != null) { + if (Arrays.asList(presentation).contains("alert")) { + ApplicationInfo applicationInfo = getContext().getApplicationInfo(); + Bundle bundle = applicationInfo.metaData; + int pushIcon = android.R.drawable.ic_dialog_info; + if (bundle != null && bundle.getInt("com.google.firebase.messaging.default_notification_icon") != 0) { + pushIcon = bundle.getInt("com.google.firebase.messaging.default_notification_icon"); + } + NotificationCompat.Builder builder = new NotificationCompat.Builder( + getContext(), + NotificationChannelManager.FOREGROUND_NOTIFICATION_CHANNEL_ID + ) + .setSmallIcon(pushIcon) + .setContentTitle(title) + .setContentText(body) + .setPriority(NotificationCompat.PRIORITY_DEFAULT); + notificationManager.notify(0, builder.build()); + } + } + remoteMessageData.put("title", title); + remoteMessageData.put("body", body); remoteMessageData.put("click_action", notification.getClickAction()); Uri link = notification.getLink(); diff --git a/push-notifications/src/definitions.ts b/push-notifications/src/definitions.ts index 0c1762c98..9c075a9ac 100644 --- a/push-notifications/src/definitions.ts +++ b/push-notifications/src/definitions.ts @@ -7,7 +7,7 @@ export type PresentationOption = 'badge' | 'sound' | 'alert'; declare module '@capacitor/cli' { export interface PluginsConfig { /** - * On iOS you can configure the way the push notifications are displayed when the app is in foreground. + * You can configure the way the push notifications are displayed when the app is in foreground. */ PushNotifications?: { /** @@ -18,7 +18,7 @@ declare module '@capacitor/cli' { * * An empty array can be provided if none of the options are desired. * - * Only available for iOS. + * badge is only available for iOS. * * @since 1.0.0 * @example ["badge", "sound", "alert"]