Skip to content

Commit

Permalink
feat(push-notifications): Allow to show while in foreground (#919)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcesarmobile committed Apr 18, 2022
1 parent 08af985 commit a90b5fd
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 33 deletions.
30 changes: 15 additions & 15 deletions push-notifications/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ Android Studio has an icon generator you can use to create your Push Notificatio
<docgen-config>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->

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`** | <code>PresentationOption[]</code> | 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`** | <code>PresentationOption[]</code> | 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

Expand Down Expand Up @@ -463,17 +463,17 @@ Remove all native listeners for this plugin.

#### Channel

| Prop | Type | Description | Default | Since |
| ----------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----- |
| **`id`** | <code>string</code> | The channel identifier. | | 1.0.0 |
| **`name`** | <code>string</code> | The human-friendly name of this channel (presented to the user). | | 1.0.0 |
| **`description`** | <code>string</code> | The description of this channel (presented to the user). | | 1.0.0 |
| **`sound`** | <code>string</code> | 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`** | <code><a href="#importance">Importance</a></code> | The level of interruption for notifications posted to this channel. | <code>3</code> | 1.0.0 |
| **`visibility`** | <code><a href="#visibility">Visibility</a></code> | 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`** | <code>boolean</code> | Whether notifications posted to this channel should display notification lights, on devices that support it. | | 1.0.0 |
| **`lightColor`** | <code>string</code> | 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`** | <code>boolean</code> | Whether notifications posted to this channel should vibrate. | | 1.0.0 |
| Prop | Type | Description | Default | Since |
| ----------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- | ----- |
| **`id`** | <code>string</code> | The channel identifier. | | 1.0.0 |
| **`name`** | <code>string</code> | The human-friendly name of this channel (presented to the user). | | 1.0.0 |
| **`description`** | <code>string</code> | The description of this channel (presented to the user). | | 1.0.0 |
| **`sound`** | <code>string</code> | 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`** | <code><a href="#importance">Importance</a></code> | The level of interruption for notifications posted to this channel. | <code>`3`</code> | 1.0.0 |
| **`visibility`** | <code><a href="#visibility">Visibility</a></code> | 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`** | <code>boolean</code> | Whether notifications posted to this channel should display notification lights, on devices that support it. | | 1.0.0 |
| **`lightColor`** | <code>string</code> | 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`** | <code>boolean</code> | Whether notifications posted to this channel should vibrate. | | 1.0.0 |


#### ListChannelsResult
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -46,7 +43,7 @@ public void load() {
lastMessage = null;
}

notificationChannelManager = new NotificationChannelManager(getActivity(), notificationManager);
notificationChannelManager = new NotificationChannelManager(getActivity(), notificationManager, getConfig());
}

@Override
Expand Down Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions push-notifications/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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?: {
/**
Expand All @@ -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"]
Expand Down

0 comments on commit a90b5fd

Please sign in to comment.