From 93eb9aa5037b35c1f8c5a2f0ec0f821466f1f7c8 Mon Sep 17 00:00:00 2001 From: jcesarmobile Date: Fri, 3 Apr 2020 11:39:50 +0200 Subject: [PATCH] feat(android): Allow to configure a default notification sound (#2682) --- .../notification/LocalNotification.java | 42 ++++++++++++++++++- .../LocalNotificationManager.java | 17 ++++++-- core/src/core-plugin-definitions.ts | 7 ++++ .../docs-md/apis/local-notifications/index.md | 4 +- 4 files changed, 64 insertions(+), 6 deletions(-) diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotification.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotification.java index 302809751..74ff5ff6d 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotification.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotification.java @@ -1,6 +1,8 @@ package com.getcapacitor.plugin.notification; +import android.content.ContentResolver; import android.content.Context; +import android.net.Uri; import android.util.Log; import com.getcapacitor.Config; @@ -25,6 +27,7 @@ public class LocalNotification { private static final String CONFIG_KEY_PREFIX = "plugins.LocalNotifications."; private static final int RESOURCE_ID_ZERO_VALUE = 0; private static int defaultSmallIconID = RESOURCE_ID_ZERO_VALUE; + private static int defaultSoundID = RESOURCE_ID_ZERO_VALUE; private String title; private String body; @@ -66,8 +69,20 @@ public void setSchedule(LocalNotificationSchedule schedule) { this.schedule = schedule; } - public String getSound() { - return sound; + public String getSound(Context context) { + String soundPath = null; + int resId = RESOURCE_ID_ZERO_VALUE; + String name = getResourceBaseName(sound); + if (name != null) { + resId = getResourceID(context, name, "raw"); + } + if (resId == RESOURCE_ID_ZERO_VALUE) { + resId = getDefaultSound(context); + } + if(resId != RESOURCE_ID_ZERO_VALUE){ + soundPath = ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + resId; + } + return soundPath; } public void setSound(String sound) { @@ -258,6 +273,29 @@ private static int getDefaultSmallIcon(Context context){ return resId; } + private static int getDefaultSound(Context context){ + if(defaultSoundID != RESOURCE_ID_ZERO_VALUE) return defaultSoundID; + + int resId = RESOURCE_ID_ZERO_VALUE; + String soundConfigResourceName = Config.getString(CONFIG_KEY_PREFIX + "sound"); + soundConfigResourceName = getResourceBaseName(soundConfigResourceName); + + if(soundConfigResourceName != null){ + resId = getResourceID(context, soundConfigResourceName, "raw"); + } + + defaultSoundID = resId; + return resId; + } + + public static Uri getDefaultSoundUrl(Context context){ + int soundId = LocalNotification.getDefaultSound(context); + if (soundId != RESOURCE_ID_ZERO_VALUE) { + return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getPackageName() + "/" + soundId); + } + return null; + } + public boolean isScheduled() { return this.schedule != null && (this.schedule.getOn() != null || diff --git a/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotificationManager.java b/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotificationManager.java index d23d4dd96..0bc393517 100644 --- a/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotificationManager.java +++ b/android/capacitor/src/main/java/com/getcapacitor/plugin/notification/LocalNotificationManager.java @@ -8,6 +8,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.Color; +import android.media.AudioAttributes; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -107,6 +108,13 @@ public void createNotificationChannel() { int importance = android.app.NotificationManager.IMPORTANCE_DEFAULT; NotificationChannel channel = new NotificationChannel(DEFAULT_NOTIFICATION_CHANNEL_ID, name, importance); channel.setDescription(description); + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_ALARM).build(); + Uri soundUri = LocalNotification.getDefaultSoundUrl(context); + if (soundUri != null) { + channel.setSound(soundUri, 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); @@ -153,14 +161,13 @@ private void buildNotification(NotificationManagerCompat notificationManager, Lo .setAutoCancel(true) .setOngoing(false) .setPriority(NotificationCompat.PRIORITY_DEFAULT) - .setGroupSummary(localNotification.isGroupSummary()) - .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS); + .setGroupSummary(localNotification.isGroupSummary()); // support multiline text mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(localNotification.getBody())); - String sound = localNotification.getSound(); + String sound = localNotification.getSound(context); if (sound != null) { Uri soundUri = Uri.parse(sound); // Grant permission to use sound @@ -168,8 +175,12 @@ private void buildNotification(NotificationManagerCompat notificationManager, Lo "com.android.systemui", soundUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); mBuilder.setSound(soundUri); + mBuilder.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS); + } else { + mBuilder.setDefaults(Notification.DEFAULT_ALL); } + String group = localNotification.getGroup(); if (group != null) { mBuilder.setGroup(group); diff --git a/core/src/core-plugin-definitions.ts b/core/src/core-plugin-definitions.ts index 427a8bb53..5ab178708 100644 --- a/core/src/core-plugin-definitions.ts +++ b/core/src/core-plugin-definitions.ts @@ -1071,6 +1071,13 @@ export interface LocalNotification { body: string; id: number; schedule?: LocalNotificationSchedule; + /** + * Name of the audio file with extension. + * On iOS the file should be in the app bundle. + * On Android the file should be on res/raw folder. + * Doesn't work on Android version 26+ (Android O and newer), for + * Recommended format is .wav because is supported by both platforms. + */ sound?: string; /** * Android-only: set a custom statusbar icon. diff --git a/site/docs-md/apis/local-notifications/index.md b/site/docs-md/apis/local-notifications/index.md index 1c9c6b240..98fcfc170 100644 --- a/site/docs-md/apis/local-notifications/index.md +++ b/site/docs-md/apis/local-notifications/index.md @@ -46,12 +46,14 @@ The local notification plugin allows the following configuration values to be ad - `smallIcon`: It allows you to set the default icon for the local notification. - `iconColor`: It allows you to set the default color for the local notification icon. +- `sound`: It allows you to set the default notification sound. On Android 26+ it sets the default channel sound and can't be changed unless the app is uninstalled. ```json "plugins": { "LocalNotifications": { "smallIcon": "ic_stat_icon_config_sample", - "iconColor": "#488AFF" + "iconColor": "#488AFF", + "sound": "beep.wav" } } ```