expo-notifications 1.0.0-canary-20251216-3f01dbf → 1.0.0-canary-20251230-fc48ddc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/notifications/NotificationsPackage.kt +14 -0
  4. package/android/src/main/java/expo/modules/notifications/notifications/NotificationManager.kt +121 -0
  5. package/android/src/main/java/expo/modules/notifications/notifications/categories/ExpoNotificationCategoriesModule.kt +2 -6
  6. package/android/src/main/java/expo/modules/notifications/notifications/categories/serializers/ExpoNotificationsCategoriesSerializer.java +1 -9
  7. package/android/src/main/java/expo/modules/notifications/notifications/channels/AndroidXNotificationsChannelsProvider.kt +11 -4
  8. package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelGroupManagerModule.kt +7 -12
  9. package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelManagerModule.kt +7 -13
  10. package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationsChannelProviderAccessor.kt +9 -0
  11. package/android/src/main/java/expo/modules/notifications/notifications/emitting/NotificationsEmitter.kt +3 -6
  12. package/android/src/main/java/expo/modules/notifications/notifications/enums/NotificationImportance.java +4 -0
  13. package/android/src/main/java/expo/modules/notifications/notifications/handling/NotificationsHandler.kt +3 -10
  14. package/android/src/main/java/expo/modules/notifications/service/delegates/ExpoNotificationLifecycleListener.kt +53 -0
  15. package/android/src/main/java/expo/modules/notifications/tokens/PushTokenModule.kt +9 -5
  16. package/build/NotificationChannelManager.types.d.ts +3 -0
  17. package/build/NotificationChannelManager.types.d.ts.map +1 -1
  18. package/build/NotificationChannelManager.types.js +3 -0
  19. package/build/NotificationChannelManager.types.js.map +1 -1
  20. package/build/setNotificationChannelAsync.android.d.ts.map +1 -1
  21. package/build/setNotificationChannelAsync.android.js +6 -0
  22. package/build/setNotificationChannelAsync.android.js.map +1 -1
  23. package/expo-module.config.json +3 -2
  24. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/{1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf-sources.jar → 1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc-sources.jar} +0 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc-sources.jar.md5 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc-sources.jar.sha1 +1 -0
  27. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc-sources.jar.sha256 +1 -0
  28. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc-sources.jar.sha512 +1 -0
  29. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.aar +0 -0
  30. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.aar.md5 +1 -0
  31. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.aar.sha1 +1 -0
  32. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.aar.sha256 +1 -0
  33. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.aar.sha512 +1 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/{1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.module → 1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.module} +22 -22
  35. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.module.md5 +1 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.module.sha1 +1 -0
  37. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.module.sha256 +1 -0
  38. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.module.sha512 +1 -0
  39. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/{1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.pom → 1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.pom} +1 -1
  40. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.pom.md5 +1 -0
  41. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.pom.sha1 +1 -0
  42. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.pom.sha256 +1 -0
  43. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251230-fc48ddc/expo.modules.notifications-1.0.0-canary-20251230-fc48ddc.pom.sha512 +1 -0
  44. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/maven-metadata.xml +4 -4
  45. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/maven-metadata.xml.md5 +1 -1
  46. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/maven-metadata.xml.sha1 +1 -1
  47. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/maven-metadata.xml.sha256 +1 -1
  48. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/maven-metadata.xml.sha512 +1 -1
  49. package/package.json +6 -6
  50. package/src/NotificationChannelManager.types.ts +3 -0
  51. package/src/setNotificationChannelAsync.android.ts +12 -1
  52. package/android/src/main/java/expo/modules/notifications/NotificationsPackage.java +0 -46
  53. package/android/src/main/java/expo/modules/notifications/notifications/NotificationManager.java +0 -158
  54. package/android/src/main/java/expo/modules/notifications/notifications/channels/AbstractNotificationsChannelsProvider.java +0 -21
  55. package/android/src/main/java/expo/modules/notifications/service/delegates/ExpoNotificationLifecycleListener.java +0 -75
  56. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf-sources.jar.md5 +0 -1
  57. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf-sources.jar.sha1 +0 -1
  58. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf-sources.jar.sha256 +0 -1
  59. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf-sources.jar.sha512 +0 -1
  60. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.aar +0 -0
  61. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.aar.md5 +0 -1
  62. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.aar.sha1 +0 -1
  63. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.aar.sha256 +0 -1
  64. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.aar.sha512 +0 -1
  65. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.module.md5 +0 -1
  66. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.module.sha1 +0 -1
  67. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.module.sha256 +0 -1
  68. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.module.sha512 +0 -1
  69. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.pom.md5 +0 -1
  70. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.pom.sha1 +0 -1
  71. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.pom.sha256 +0 -1
  72. package/local-maven-repo/host/exp/exponent/expo.modules.notifications/1.0.0-canary-20251216-3f01dbf/expo.modules.notifications-1.0.0-canary-20251216-3f01dbf.pom.sha512 +0 -1
package/CHANGELOG.md CHANGED
@@ -9,14 +9,17 @@
9
9
 
10
10
  ### 🎉 New features
11
11
 
12
+ - migrate off of legacy core apis on Android ([#41731](https://github.com/expo/expo/pull/41731) by [@vonovak](https://github.com/vonovak))
12
13
  - improve runtime validation for NotificationTriggerInput ([#41538](https://github.com/expo/expo/pull/41538) by [@vonovak](https://github.com/vonovak))
13
14
 
14
15
  ### 🐛 Bug fixes
15
16
 
17
+ - avoid crash emitting new token event when module is destroyed ([#41754](https://github.com/expo/expo/pull/41754) by [@vonovak](https://github.com/vonovak))
16
18
  - fix completion handler never called for background notifications ([#41300](https://github.com/expo/expo/pull/41300) by [@vonovak](https://github.com/vonovak))
17
19
 
18
20
  ### 💡 Others
19
21
 
22
+ - mark `NotificationImportance.UNSPECIFIED` as not suitable for use ([#41709](https://github.com/expo/expo/pull/41709) by [@vonovak](https://github.com/vonovak))
20
23
  - remove token listener on module destroy ([#41275](https://github.com/expo/expo/pull/41275) by [@vonovak](https://github.com/vonovak))
21
24
  - Remove tests related files from the published package content. ([#39551](https://github.com/expo/expo/pull/39551) by [@Simek](https://github.com/Simek))
22
25
  - [ios] migrate notification serializer to swift ([#38633](https://github.com/expo/expo/pull/38633) by [@vonovak](https://github.com/vonovak))
@@ -5,13 +5,13 @@ plugins {
5
5
  }
6
6
 
7
7
  group = 'host.exp.exponent'
8
- version = '1.0.0-canary-20251216-3f01dbf'
8
+ version = '1.0.0-canary-20251230-fc48ddc'
9
9
 
10
10
  android {
11
11
  namespace "expo.modules.notifications"
12
12
  defaultConfig {
13
13
  versionCode 21
14
- versionName '1.0.0-canary-20251216-3f01dbf'
14
+ versionName '1.0.0-canary-20251230-fc48ddc'
15
15
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16
16
  }
17
17
 
@@ -0,0 +1,14 @@
1
+ package expo.modules.notifications
2
+
3
+ import android.content.Context
4
+ import expo.modules.core.interfaces.Package
5
+ import expo.modules.core.interfaces.ReactActivityLifecycleListener
6
+ import expo.modules.notifications.service.delegates.ExpoNotificationLifecycleListener
7
+
8
+ class NotificationsPackage : Package {
9
+ override fun createReactActivityLifecycleListeners(activityContext: Context): List<ReactActivityLifecycleListener?> {
10
+ return listOf(
11
+ ExpoNotificationLifecycleListener()
12
+ )
13
+ }
14
+ }
@@ -0,0 +1,121 @@
1
+ package expo.modules.notifications.notifications
2
+
3
+ import android.os.Bundle
4
+ import expo.modules.notifications.notifications.interfaces.NotificationListener
5
+ import expo.modules.notifications.notifications.model.Notification
6
+ import expo.modules.notifications.notifications.model.NotificationResponse
7
+ import expo.modules.notifications.service.delegates.ExpoHandlingDelegate
8
+
9
+ object NotificationManager {
10
+ /**
11
+ * Set of registered listeners. Used to check quickly whether given listener
12
+ * is already registered and to iterate over on new token.
13
+ */
14
+ private val listeners = mutableSetOf<NotificationListener>()
15
+ private val pendingNotificationResponses = mutableListOf<NotificationResponse>()
16
+ private val pendingNotificationResponsesFromExtras = mutableListOf<Bundle>()
17
+
18
+ init {
19
+ // TODO @vonovak there's a chain of listeners:
20
+ // ExpoHandlingDelegate -> NotificationManager -> NotificationsEmitter
21
+ // -> NotificationsHandler
22
+ // it seems it could be shorter?
23
+ // Registers this singleton instance in static ExpoHandlingDelegate listeners collection.
24
+ // Since it doesn't hold strong reference to the object this should be safe.
25
+ ExpoHandlingDelegate.addListener(this)
26
+ }
27
+
28
+ /**
29
+ * Registers a [NotificationListener] by adding it to the [listeners] set.
30
+ *
31
+ * @param listener Listener to be notified of new messages.
32
+ */
33
+ fun addListener(listener: NotificationListener) {
34
+ if (listeners.contains(listener)) {
35
+ return
36
+ }
37
+ listeners.add(listener)
38
+ if (pendingNotificationResponses.isNotEmpty()) {
39
+ for (pendingResponse in pendingNotificationResponses) {
40
+ listener.onNotificationResponseReceived(pendingResponse)
41
+ }
42
+ }
43
+ if (pendingNotificationResponsesFromExtras.isNotEmpty()) {
44
+ for (extras in pendingNotificationResponsesFromExtras) {
45
+ listener.onNotificationResponseIntentReceived(extras)
46
+ }
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Unregisters a [NotificationListener] by removing it from the [listeners] set.
52
+ *
53
+ * @param listener Listener previously registered with [addListener].
54
+ */
55
+ fun removeListener(listener: NotificationListener) {
56
+ listeners.remove(listener)
57
+ }
58
+
59
+ /**
60
+ * Used by [expo.modules.notifications.service.delegates.ExpoSchedulingDelegate] to notify of new messages.
61
+ * Calls [NotificationListener.onNotificationReceived] on all registered [listeners].
62
+ *
63
+ * In practice, that means calling [NotificationsEmitter] (just emits an event to JS) and
64
+ * [NotificationsHandler] which calls `handleNotification` in JS to determine the behavior.
65
+ * Then `SingleNotificationHandlerTask.processNotificationWithBehavior` may present it.
66
+ *
67
+ * @param notification Notification received
68
+ */
69
+ fun onNotificationReceived(notification: Notification) {
70
+ for (listener in listeners) {
71
+ listener.onNotificationReceived(notification)
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Used by [expo.modules.notifications.service.delegates.ExpoSchedulingDelegate] to notify of new notification responses.
77
+ * Calls [NotificationListener.onNotificationResponseReceived] on all registered [listeners].
78
+ *
79
+ * @param response Notification response received
80
+ */
81
+ fun onNotificationResponseReceived(response: NotificationResponse) {
82
+ if (listeners.isEmpty()) {
83
+ pendingNotificationResponses.add(response)
84
+ } else {
85
+ for (listener in listeners) {
86
+ listener.onNotificationResponseReceived(response)
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Used by [expo.modules.notifications.service.delegates.ExpoSchedulingDelegate] to notify of message deletion event.
93
+ * Calls [NotificationListener.onNotificationsDropped] on all registered [listeners].
94
+ */
95
+ fun onNotificationsDropped() {
96
+ for (listener in listeners) {
97
+ listener.onNotificationsDropped()
98
+ }
99
+ }
100
+
101
+ fun onNotificationResponseFromExtras(extras: Bundle) {
102
+ // We're going to be passed in extras from either
103
+ // a killed state (ExpoNotificationLifecycleListener::onCreate)
104
+ // OR a background state (ExpoNotificationLifecycleListener::onNewIntent)
105
+
106
+ // If we've just come from a background state, we'll have listeners set up
107
+ // - pass on the notification to them
108
+ if (listeners.isNotEmpty()) {
109
+ for (listener in listeners) {
110
+ listener.onNotificationResponseIntentReceived(extras)
111
+ }
112
+ } else {
113
+ // Otherwise, the app has been launched from a killed state, and our listeners
114
+ // haven't yet been setup. We'll add this to a list of pending notifications
115
+ // for them to process once they've been initialized.
116
+ if (pendingNotificationResponsesFromExtras.isEmpty()) {
117
+ pendingNotificationResponsesFromExtras.add(extras)
118
+ }
119
+ }
120
+ }
121
+ }
@@ -10,10 +10,9 @@ import expo.modules.kotlin.modules.ModuleDefinition
10
10
  import expo.modules.kotlin.records.Field
11
11
  import expo.modules.kotlin.records.Record
12
12
  import expo.modules.kotlin.records.Required
13
- import expo.modules.notifications.ModuleNotFoundException
14
13
  import expo.modules.notifications.ResultReceiverBody
15
14
  import expo.modules.notifications.createDefaultResultReceiver
16
- import expo.modules.notifications.notifications.categories.serializers.NotificationsCategoriesSerializer
15
+ import expo.modules.notifications.notifications.categories.serializers.ExpoNotificationsCategoriesSerializer
17
16
  import expo.modules.notifications.notifications.model.NotificationAction
18
17
  import expo.modules.notifications.notifications.model.NotificationCategory
19
18
  import expo.modules.notifications.notifications.model.TextInputNotificationAction
@@ -51,10 +50,7 @@ class NotificationActionRecord : Record {
51
50
 
52
51
  open class ExpoNotificationCategoriesModule : Module() {
53
52
 
54
- protected val serializer by lazy {
55
- appContext.legacyModule<NotificationsCategoriesSerializer>()
56
- ?: throw ModuleNotFoundException(NotificationsCategoriesSerializer::class)
57
- }
53
+ protected val serializer = ExpoNotificationsCategoriesSerializer()
58
54
 
59
55
  private val context: Context
60
56
  get() = appContext.reactContext ?: throw Exceptions.ReactContextLost()
@@ -2,10 +2,7 @@ package expo.modules.notifications.notifications.categories.serializers;
2
2
 
3
3
  import android.os.Bundle;
4
4
 
5
- import expo.modules.core.interfaces.InternalModule;
6
-
7
5
  import java.util.ArrayList;
8
- import java.util.Collections;
9
6
  import java.util.List;
10
7
 
11
8
  import androidx.annotation.NonNull;
@@ -14,12 +11,7 @@ import expo.modules.notifications.notifications.model.NotificationAction;
14
11
  import expo.modules.notifications.notifications.model.NotificationCategory;
15
12
  import expo.modules.notifications.notifications.model.TextInputNotificationAction;
16
13
 
17
- public class ExpoNotificationsCategoriesSerializer implements NotificationsCategoriesSerializer, InternalModule {
18
- @Override
19
- public List<? extends Class> getExportedInterfaces() {
20
- return Collections.singletonList(NotificationsCategoriesSerializer.class);
21
- }
22
-
14
+ public class ExpoNotificationsCategoriesSerializer implements NotificationsCategoriesSerializer {
23
15
  @Nullable
24
16
  @Override
25
17
  public Bundle toBundle(@Nullable NotificationCategory category) {
@@ -1,19 +1,26 @@
1
1
  package expo.modules.notifications.notifications.channels
2
2
 
3
- import android.content.Context
3
+ import expo.modules.kotlin.modules.Module
4
+ import expo.modules.kotlin.modules.ModuleDefinition
4
5
  import expo.modules.notifications.notifications.channels.managers.AndroidXNotificationsChannelGroupManager
5
6
  import expo.modules.notifications.notifications.channels.managers.AndroidXNotificationsChannelManager
6
7
  import expo.modules.notifications.notifications.channels.serializers.ExpoNotificationsChannelGroupSerializer
7
8
  import expo.modules.notifications.notifications.channels.serializers.ExpoNotificationsChannelSerializer
8
9
 
9
- class AndroidXNotificationsChannelsProvider(context: Context) : AbstractNotificationsChannelsProvider(context) {
10
+ const val NotificationsChannelsProviderName = "NotificationsChannelsProvider"
11
+
12
+ class AndroidXNotificationsChannelsProvider : Module(), NotificationsChannelsProvider {
13
+
14
+ override fun definition() = ModuleDefinition {
15
+ Name(NotificationsChannelsProviderName)
16
+ }
10
17
 
11
18
  override val groupManager by lazy {
12
- AndroidXNotificationsChannelGroupManager(context)
19
+ AndroidXNotificationsChannelGroupManager(appContext.reactContext)
13
20
  }
14
21
 
15
22
  override val channelManager by lazy {
16
- AndroidXNotificationsChannelManager(context, groupManager)
23
+ AndroidXNotificationsChannelManager(appContext.reactContext, groupManager)
17
24
  }
18
25
 
19
26
  override val channelSerializer by lazy {
@@ -5,27 +5,22 @@ import android.os.Bundle
5
5
  import expo.modules.core.arguments.ReadableArguments
6
6
  import expo.modules.kotlin.modules.Module
7
7
  import expo.modules.kotlin.modules.ModuleDefinition
8
- import expo.modules.notifications.ModuleNotFoundException
9
- import expo.modules.notifications.notifications.channels.managers.NotificationsChannelGroupManager
10
8
  import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelGroupSerializer
11
9
 
12
10
  /**
13
11
  * An exported module responsible for exposing methods for managing notification channel groups.
14
12
  */
15
- class NotificationChannelGroupManagerModule : Module() {
16
- private lateinit var groupManager: NotificationsChannelGroupManager
17
- private lateinit var groupSerializer: NotificationsChannelGroupSerializer
13
+ open class NotificationChannelGroupManagerModule : Module(), NotificationsChannelProviderAccessor {
14
+ private val groupManager by lazy {
15
+ getChannelProvider(appContext.registry).groupManager
16
+ }
17
+ private val groupSerializer by lazy {
18
+ getChannelProvider(appContext.registry).groupSerializer
19
+ }
18
20
 
19
21
  override fun definition() = ModuleDefinition {
20
22
  Name("ExpoNotificationChannelGroupManager")
21
23
 
22
- OnCreate {
23
- val provider = appContext.legacyModule<NotificationsChannelsProvider>()
24
- ?: throw ModuleNotFoundException(NotificationsChannelsProvider::class)
25
- groupManager = provider.groupManager
26
- groupSerializer = provider.groupSerializer
27
- }
28
-
29
24
  AsyncFunction("getNotificationChannelGroupAsync") { groupId: String ->
30
25
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
31
26
  val group = groupManager.getNotificationChannelGroup(groupId)
@@ -6,8 +6,6 @@ import androidx.annotation.RequiresApi
6
6
  import expo.modules.core.arguments.ReadableArguments
7
7
  import expo.modules.kotlin.modules.Module
8
8
  import expo.modules.kotlin.modules.ModuleDefinition
9
- import expo.modules.notifications.ModuleNotFoundException
10
- import expo.modules.notifications.notifications.channels.managers.NotificationsChannelManager
11
9
  import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelSerializer
12
10
  import expo.modules.notifications.notifications.enums.NotificationImportance
13
11
  import java.util.Objects
@@ -15,21 +13,17 @@ import java.util.Objects
15
13
  /**
16
14
  * An exported module responsible for exposing methods for managing notification channels.
17
15
  */
18
- open class NotificationChannelManagerModule : Module() {
19
- private lateinit var channelManager: NotificationsChannelManager
20
- private lateinit var channelSerializer: NotificationsChannelSerializer
16
+ open class NotificationChannelManagerModule : Module(), NotificationsChannelProviderAccessor {
17
+ private val channelManager by lazy {
18
+ getChannelProvider(appContext.registry).channelManager
19
+ }
20
+ private val channelSerializer by lazy {
21
+ getChannelProvider(appContext.registry).channelSerializer
22
+ }
21
23
 
22
24
  override fun definition() = ModuleDefinition {
23
25
  Name("ExpoNotificationChannelManager")
24
26
 
25
- OnCreate {
26
- val provider = appContext.legacyModule<NotificationsChannelsProvider>()
27
- ?: throw ModuleNotFoundException(NotificationsChannelsProvider::class)
28
-
29
- channelManager = provider.channelManager
30
- channelSerializer = provider.channelSerializer
31
- }
32
-
33
27
  AsyncFunction<List<Bundle?>>("getNotificationChannelsAsync") {
34
28
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
35
29
  return@AsyncFunction emptyList<Bundle>()
@@ -0,0 +1,9 @@
1
+ package expo.modules.notifications.notifications.channels
2
+
3
+ import expo.modules.kotlin.ModuleRegistry
4
+
5
+ internal interface NotificationsChannelProviderAccessor {
6
+ fun getChannelProvider(registry: ModuleRegistry): NotificationsChannelsProvider {
7
+ return registry.getModule(NotificationsChannelsProviderName) as NotificationsChannelsProvider
8
+ }
9
+ }
@@ -15,7 +15,6 @@ private const val NEW_RESPONSE_EVENT_NAME = "onDidReceiveNotificationResponse"
15
15
  private const val MESSAGES_DELETED_EVENT_NAME = "onNotificationsDeleted"
16
16
 
17
17
  open class NotificationsEmitter : Module(), NotificationListener {
18
- private lateinit var notificationManager: NotificationManager
19
18
  private var lastNotificationResponseBundle: Bundle? = null
20
19
 
21
20
  override fun definition() = ModuleDefinition {
@@ -28,14 +27,12 @@ open class NotificationsEmitter : Module(), NotificationListener {
28
27
  )
29
28
 
30
29
  OnCreate {
31
- // Register the module as a listener in NotificationManager singleton module.
32
- // Deregistration happens in onDestroy callback.
33
- notificationManager = requireNotNull(appContext.legacyModuleRegistry.getSingletonModule("NotificationManager", NotificationManager::class.java))
34
- notificationManager.addListener(this@NotificationsEmitter)
30
+ // Register the module as a listener in NotificationManager singleton.
31
+ NotificationManager.addListener(this@NotificationsEmitter)
35
32
  }
36
33
 
37
34
  OnDestroy {
38
- notificationManager.removeListener(this@NotificationsEmitter)
35
+ NotificationManager.removeListener(this@NotificationsEmitter)
39
36
  }
40
37
 
41
38
  Function<Bundle?>("getLastNotificationResponse") {
@@ -3,6 +3,10 @@ package expo.modules.notifications.notifications.enums;
3
3
  import androidx.core.app.NotificationManagerCompat;
4
4
 
5
5
  public enum NotificationImportance {
6
+ /**
7
+ * IMPORTANCE_UNSPECIFIED fails validation in com.android.server.notification.PreferencesHelper.createNotificationChannel
8
+ * and it should not be used
9
+ * */
6
10
  UNSPECIFIED(NotificationManagerCompat.IMPORTANCE_UNSPECIFIED, 1),
7
11
  NONE(NotificationManagerCompat.IMPORTANCE_NONE, 2),
8
12
  MIN(NotificationManagerCompat.IMPORTANCE_MIN, 3),
@@ -2,7 +2,6 @@ package expo.modules.notifications.notifications.handling
2
2
 
3
3
  import android.os.Handler
4
4
  import android.os.HandlerThread
5
- import expo.modules.core.ModuleRegistry
6
5
  import expo.modules.kotlin.Promise
7
6
  import expo.modules.kotlin.modules.Module
8
7
  import expo.modules.kotlin.modules.ModuleDefinition
@@ -23,9 +22,6 @@ import expo.modules.notifications.notifications.model.RemoteNotificationContent
23
22
  * for all of them and a proxy through which app responds with the behavior.
24
23
  */
25
24
  open class NotificationsHandler : Module(), NotificationListener {
26
- private lateinit var notificationManager: NotificationManager
27
- private lateinit var moduleRegistry: ModuleRegistry
28
-
29
25
  /**
30
26
  * [HandlerThread] which is the host to the notifications handler.
31
27
  */
@@ -47,19 +43,16 @@ open class NotificationsHandler : Module(), NotificationListener {
47
43
  )
48
44
 
49
45
  OnCreate {
50
- moduleRegistry = appContext.legacyModuleRegistry
51
-
52
- // Register the module as a listener in NotificationManager singleton module.
46
+ // Register the module as a listener in NotificationManager singleton.
53
47
  // Deregistration happens in onDestroy callback.
54
- notificationManager = requireNotNull(moduleRegistry.getSingletonModule("NotificationManager", NotificationManager::class.java))
55
- notificationManager.addListener(this@NotificationsHandler)
48
+ NotificationManager.addListener(this@NotificationsHandler)
56
49
  notificationsHandlerThread = HandlerThread("NotificationsHandlerThread - " + this.javaClass.toString())
57
50
  notificationsHandlerThread.start()
58
51
  handler = Handler(notificationsHandlerThread.looper)
59
52
  }
60
53
 
61
54
  OnDestroy {
62
- notificationManager.removeListener(this@NotificationsHandler)
55
+ NotificationManager.removeListener(this@NotificationsHandler)
63
56
 
64
57
  tasksMap.values.forEach(SingleNotificationHandlerTask::stop)
65
58
 
@@ -0,0 +1,53 @@
1
+ package expo.modules.notifications.service.delegates
2
+
3
+ import android.app.Activity
4
+ import android.content.Intent
5
+ import android.os.Bundle
6
+ import android.util.Log
7
+ import expo.modules.core.interfaces.ReactActivityLifecycleListener
8
+ import expo.modules.notifications.notifications.NotificationManager
9
+ import expo.modules.notifications.notifications.debug.DebugLogging
10
+ import expo.modules.notifications.service.NotificationsService.Companion.NOTIFICATION_RESPONSE_KEY
11
+ import expo.modules.notifications.service.NotificationsService.Companion.TEXT_INPUT_NOTIFICATION_RESPONSE_KEY
12
+
13
+ class ExpoNotificationLifecycleListener : ReactActivityLifecycleListener {
14
+
15
+ /**
16
+ * This will be triggered if the app is not running,
17
+ * and is started from clicking on a notification.
18
+ *
19
+ * Notification data will be in activity.intent.extras
20
+ */
21
+ override fun onCreate(activity: Activity, savedInstanceState: Bundle?) {
22
+ val extras = activity.intent?.extras ?: return
23
+ // only actions that have opensAppToForeground: true are handled here
24
+ if (extras.containsKey(NOTIFICATION_RESPONSE_KEY) || extras.containsKey(TEXT_INPUT_NOTIFICATION_RESPONSE_KEY)) {
25
+ Log.d("ReactNativeJS", "[native] ExpoNotificationLifecycleListener contains an unmarshalled notification response. Skipping.")
26
+ return
27
+ }
28
+ DebugLogging.logBundle("ExpoNotificationLifeCycleListener.onCreate:", extras)
29
+ NotificationManager.onNotificationResponseFromExtras(extras)
30
+ }
31
+
32
+ /**
33
+ * This will be triggered if the app is running and in the background,
34
+ * and the user clicks on a notification to open the app.
35
+ *
36
+ * Notification data will be in intent.extras
37
+ */
38
+ override fun onNewIntent(intent: Intent): Boolean {
39
+ val extras = intent.extras
40
+ if (extras != null) {
41
+ if (extras.containsKey(NOTIFICATION_RESPONSE_KEY) || extras.containsKey(TEXT_INPUT_NOTIFICATION_RESPONSE_KEY)) {
42
+ intent.removeExtra(NOTIFICATION_RESPONSE_KEY)
43
+ intent.removeExtra(TEXT_INPUT_NOTIFICATION_RESPONSE_KEY)
44
+ // response events are already handled by
45
+ // NotificationForwarderActivity -> NotificationsService.onReceiveNotificationResponse -> NotificationEmitter.onNotificationResponseReceived
46
+ return false
47
+ }
48
+ DebugLogging.logBundle("ExpoNotificationLifeCycleListener.onNewIntent:", extras)
49
+ NotificationManager.onNotificationResponseFromExtras(extras)
50
+ }
51
+ return false
52
+ }
53
+ }
@@ -21,12 +21,16 @@ class PushTokenModule : Module(), FirebaseTokenListener {
21
21
  * @param token New push token.
22
22
  */
23
23
  override fun onNewToken(token: String) {
24
- sendEvent(
25
- NEW_TOKEN_EVENT_NAME,
26
- mapOf(
27
- NEW_TOKEN_EVENT_TOKEN_KEY to token
24
+ runCatching {
25
+ // onNewToken is emitted asynchronously and the module may be destroyed by the time sendEvent is called
26
+ // that would result in an exception
27
+ sendEvent(
28
+ NEW_TOKEN_EVENT_NAME,
29
+ mapOf(
30
+ NEW_TOKEN_EVENT_TOKEN_KEY to token
31
+ )
28
32
  )
29
- )
33
+ }
30
34
  }
31
35
 
32
36
  override fun definition() = ModuleDefinition {
@@ -23,6 +23,9 @@ export declare enum AndroidAudioContentType {
23
23
  * */
24
24
  export declare enum AndroidImportance {
25
25
  UNKNOWN = 0,
26
+ /**
27
+ * Use `DEFAULT` instead. This value is present for compatibility reasons.
28
+ * */
26
29
  UNSPECIFIED = 1,
27
30
  NONE = 2,
28
31
  MIN = 3,
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationChannelManager.types.d.ts","sourceRoot":"","sources":["../src/NotificationChannelManager.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NotificationChannelManager.types.d.ts","sourceRoot":"","sources":["../src/NotificationChannelManager.types.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,9 @@ export var AndroidAudioContentType;
28
28
  export var AndroidImportance;
29
29
  (function (AndroidImportance) {
30
30
  AndroidImportance[AndroidImportance["UNKNOWN"] = 0] = "UNKNOWN";
31
+ /**
32
+ * Use `DEFAULT` instead. This value is present for compatibility reasons.
33
+ * */
31
34
  AndroidImportance[AndroidImportance["UNSPECIFIED"] = 1] = "UNSPECIFIED";
32
35
  AndroidImportance[AndroidImportance["NONE"] = 2] = "NONE";
33
36
  AndroidImportance[AndroidImportance["MIN"] = 3] = "MIN";
@@ -1 +1 @@
1
- {"version":3,"file":"NotificationChannelManager.types.js","sourceRoot":"","sources":["../src/NotificationChannelManager.types.ts"],"names":[],"mappings":"AAEA,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,6BAKX;AALD,WAAY,6BAA6B;IACvC,uFAAW,CAAA;IACX,qFAAU,CAAA;IACV,uFAAW,CAAA;IACX,qFAAU,CAAA;AACZ,CAAC,EALW,6BAA6B,KAA7B,6BAA6B,QAKxC;AAED,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,uBAMX;AAND,WAAY,uBAAuB;IACjC,2EAAW,CAAA;IACX,yEAAU,CAAA;IACV,uEAAS,CAAA;IACT,uEAAS,CAAA;IACT,qFAAgB,CAAA;AAClB,CAAC,EANW,uBAAuB,KAAvB,uBAAuB,QAMlC;AAED,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,iBASX;AATD,WAAY,iBAAiB;IAC3B,+DAAW,CAAA;IACX,uEAAe,CAAA;IACf,yDAAQ,CAAA;IACR,uDAAO,CAAA;IACP,uDAAO,CAAA;IACP,+DAAW,CAAA;IACX,yDAAQ,CAAA;IACR,uDAAO,CAAA;AACT,CAAC,EATW,iBAAiB,KAAjB,iBAAiB,QAS5B;AAED,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,iBAgBX;AAhBD,WAAY,iBAAiB;IAC3B,+DAAW,CAAA;IACX,2DAAS,CAAA;IACT,uFAAuB,CAAA;IACvB,6GAAkC,CAAA;IAClC,2DAAS,CAAA;IACT,yEAAgB,CAAA;IAChB,2FAAyB,CAAA;IACzB,qHAAsC,CAAA;IACtC,qHAAsC,CAAA;IACtC,qHAAsC,CAAA;IACtC,sFAAuB,CAAA;IACvB,kGAA6B,CAAA;IAC7B,8GAAmC,CAAA;IACnC,gGAA4B,CAAA;IAC5B,0DAAS,CAAA;AACX,CAAC,EAhBW,iBAAiB,KAAjB,iBAAiB,QAgB5B","sourcesContent":["import { ProxyNativeModule } from 'expo-modules-core';\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidNotificationVisibility {\n UNKNOWN = 0,\n PUBLIC = 1,\n PRIVATE = 2,\n SECRET = 3,\n}\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidAudioContentType {\n UNKNOWN = 0,\n SPEECH = 1,\n MUSIC = 2,\n MOVIE = 3,\n SONIFICATION = 4,\n}\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidImportance {\n UNKNOWN = 0,\n UNSPECIFIED = 1,\n NONE = 2,\n MIN = 3,\n LOW = 4,\n DEFAULT = 5,\n HIGH = 6,\n MAX = 7,\n}\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidAudioUsage {\n UNKNOWN = 0,\n MEDIA = 1,\n VOICE_COMMUNICATION = 2,\n VOICE_COMMUNICATION_SIGNALLING = 3,\n ALARM = 4,\n NOTIFICATION = 5,\n NOTIFICATION_RINGTONE = 6,\n NOTIFICATION_COMMUNICATION_REQUEST = 7,\n NOTIFICATION_COMMUNICATION_INSTANT = 8,\n NOTIFICATION_COMMUNICATION_DELAYED = 9,\n NOTIFICATION_EVENT = 10,\n ASSISTANCE_ACCESSIBILITY = 11,\n ASSISTANCE_NAVIGATION_GUIDANCE = 12,\n ASSISTANCE_SONIFICATION = 13,\n GAME = 14,\n}\n\n// @docsMissing\nexport interface AudioAttributes {\n usage: AndroidAudioUsage;\n contentType: AndroidAudioContentType;\n flags: {\n enforceAudibility: boolean;\n requestHardwareAudioVideoSynchronization: boolean;\n };\n}\n\n// We're making inner flags required to set intentionally.\n// Not providing `true` for a flag makes it false, it doesn't make sense\n// to let it be left undefined.\nexport type AudioAttributesInput = Partial<AudioAttributes>;\n\n/**\n * An object which represents a notification channel.\n * @platform android\n */\nexport interface NotificationChannel {\n id: string;\n name: string | null;\n importance: AndroidImportance;\n bypassDnd: boolean;\n description: string | null;\n groupId?: string | null;\n lightColor: string;\n lockscreenVisibility: AndroidNotificationVisibility;\n showBadge: boolean;\n sound: 'default' | 'custom' | null;\n audioAttributes: AudioAttributes;\n vibrationPattern: number[] | null;\n enableLights: boolean;\n enableVibrate: boolean;\n}\n\n/**\n * @hidden\n * */\nexport type RequiredBy<T, K extends keyof T> = Partial<Omit<T, K>> & Required<Pick<T, K>>;\n\n/**\n * An object which represents a notification channel to be set.\n * @platform android\n */\nexport type NotificationChannelInput = RequiredBy<\n Omit<\n NotificationChannel,\n | 'id' // id is handled separately as a function argument\n | 'audioAttributes' // need to make it AudioAttributesInput\n | 'sound'\n > & { audioAttributes?: AudioAttributesInput; sound?: string | null },\n 'name' | 'importance'\n>;\n\nexport interface NotificationChannelManager extends ProxyNativeModule {\n getNotificationChannelsAsync?: () => Promise<NotificationChannel[] | null>;\n getNotificationChannelAsync?: (channelId: string) => Promise<NotificationChannel | null>;\n setNotificationChannelAsync?: (\n channelId: string,\n channelConfiguration: NotificationChannelInput\n ) => Promise<NotificationChannel | null>;\n deleteNotificationChannelAsync?: (channelId: string) => Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"NotificationChannelManager.types.js","sourceRoot":"","sources":["../src/NotificationChannelManager.types.ts"],"names":[],"mappings":"AAEA,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,6BAKX;AALD,WAAY,6BAA6B;IACvC,uFAAW,CAAA;IACX,qFAAU,CAAA;IACV,uFAAW,CAAA;IACX,qFAAU,CAAA;AACZ,CAAC,EALW,6BAA6B,KAA7B,6BAA6B,QAKxC;AAED,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,uBAMX;AAND,WAAY,uBAAuB;IACjC,2EAAW,CAAA;IACX,yEAAU,CAAA;IACV,uEAAS,CAAA;IACT,uEAAS,CAAA;IACT,qFAAgB,CAAA;AAClB,CAAC,EANW,uBAAuB,KAAvB,uBAAuB,QAMlC;AAED,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,iBAYX;AAZD,WAAY,iBAAiB;IAC3B,+DAAW,CAAA;IACX;;SAEK;IACL,uEAAe,CAAA;IACf,yDAAQ,CAAA;IACR,uDAAO,CAAA;IACP,uDAAO,CAAA;IACP,+DAAW,CAAA;IACX,yDAAQ,CAAA;IACR,uDAAO,CAAA;AACT,CAAC,EAZW,iBAAiB,KAAjB,iBAAiB,QAY5B;AAED,eAAe;AACf;;KAEK;AACL,MAAM,CAAN,IAAY,iBAgBX;AAhBD,WAAY,iBAAiB;IAC3B,+DAAW,CAAA;IACX,2DAAS,CAAA;IACT,uFAAuB,CAAA;IACvB,6GAAkC,CAAA;IAClC,2DAAS,CAAA;IACT,yEAAgB,CAAA;IAChB,2FAAyB,CAAA;IACzB,qHAAsC,CAAA;IACtC,qHAAsC,CAAA;IACtC,qHAAsC,CAAA;IACtC,sFAAuB,CAAA;IACvB,kGAA6B,CAAA;IAC7B,8GAAmC,CAAA;IACnC,gGAA4B,CAAA;IAC5B,0DAAS,CAAA;AACX,CAAC,EAhBW,iBAAiB,KAAjB,iBAAiB,QAgB5B","sourcesContent":["import { ProxyNativeModule } from 'expo-modules-core';\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidNotificationVisibility {\n UNKNOWN = 0,\n PUBLIC = 1,\n PRIVATE = 2,\n SECRET = 3,\n}\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidAudioContentType {\n UNKNOWN = 0,\n SPEECH = 1,\n MUSIC = 2,\n MOVIE = 3,\n SONIFICATION = 4,\n}\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidImportance {\n UNKNOWN = 0,\n /**\n * Use `DEFAULT` instead. This value is present for compatibility reasons.\n * */\n UNSPECIFIED = 1,\n NONE = 2,\n MIN = 3,\n LOW = 4,\n DEFAULT = 5,\n HIGH = 6,\n MAX = 7,\n}\n\n// @docsMissing\n/**\n * @platform android\n * */\nexport enum AndroidAudioUsage {\n UNKNOWN = 0,\n MEDIA = 1,\n VOICE_COMMUNICATION = 2,\n VOICE_COMMUNICATION_SIGNALLING = 3,\n ALARM = 4,\n NOTIFICATION = 5,\n NOTIFICATION_RINGTONE = 6,\n NOTIFICATION_COMMUNICATION_REQUEST = 7,\n NOTIFICATION_COMMUNICATION_INSTANT = 8,\n NOTIFICATION_COMMUNICATION_DELAYED = 9,\n NOTIFICATION_EVENT = 10,\n ASSISTANCE_ACCESSIBILITY = 11,\n ASSISTANCE_NAVIGATION_GUIDANCE = 12,\n ASSISTANCE_SONIFICATION = 13,\n GAME = 14,\n}\n\n// @docsMissing\nexport interface AudioAttributes {\n usage: AndroidAudioUsage;\n contentType: AndroidAudioContentType;\n flags: {\n enforceAudibility: boolean;\n requestHardwareAudioVideoSynchronization: boolean;\n };\n}\n\n// We're making inner flags required to set intentionally.\n// Not providing `true` for a flag makes it false, it doesn't make sense\n// to let it be left undefined.\nexport type AudioAttributesInput = Partial<AudioAttributes>;\n\n/**\n * An object which represents a notification channel.\n * @platform android\n */\nexport interface NotificationChannel {\n id: string;\n name: string | null;\n importance: AndroidImportance;\n bypassDnd: boolean;\n description: string | null;\n groupId?: string | null;\n lightColor: string;\n lockscreenVisibility: AndroidNotificationVisibility;\n showBadge: boolean;\n sound: 'default' | 'custom' | null;\n audioAttributes: AudioAttributes;\n vibrationPattern: number[] | null;\n enableLights: boolean;\n enableVibrate: boolean;\n}\n\n/**\n * @hidden\n * */\nexport type RequiredBy<T, K extends keyof T> = Partial<Omit<T, K>> & Required<Pick<T, K>>;\n\n/**\n * An object which represents a notification channel to be set.\n * @platform android\n */\nexport type NotificationChannelInput = RequiredBy<\n Omit<\n NotificationChannel,\n | 'id' // id is handled separately as a function argument\n | 'audioAttributes' // need to make it AudioAttributesInput\n | 'sound'\n > & { audioAttributes?: AudioAttributesInput; sound?: string | null },\n 'name' | 'importance'\n>;\n\nexport interface NotificationChannelManager extends ProxyNativeModule {\n getNotificationChannelsAsync?: () => Promise<NotificationChannel[] | null>;\n getNotificationChannelAsync?: (channelId: string) => Promise<NotificationChannel | null>;\n setNotificationChannelAsync?: (\n channelId: string,\n channelConfiguration: NotificationChannelInput\n ) => Promise<NotificationChannel | null>;\n deleteNotificationChannelAsync?: (channelId: string) => Promise<void>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"setNotificationChannelAsync.android.d.ts","sourceRoot":"","sources":["../src/setNotificationChannelAsync.android.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAEnG,wBAA8B,2BAA2B,CACvD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAMrC"}
1
+ {"version":3,"file":"setNotificationChannelAsync.android.d.ts","sourceRoot":"","sources":["../src/setNotificationChannelAsync.android.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EAEpB,MAAM,oCAAoC,CAAC;AAE5C,wBAA8B,2BAA2B,CACvD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAarC"}
@@ -1,9 +1,15 @@
1
1
  import { UnavailabilityError } from 'expo-modules-core';
2
2
  import NotificationChannelManager from './NotificationChannelManager';
3
+ import { AndroidImportance, } from './NotificationChannelManager.types';
3
4
  export default async function setNotificationChannelAsync(channelId, channel) {
4
5
  if (!NotificationChannelManager.setNotificationChannelAsync) {
5
6
  throw new UnavailabilityError('Notifications', 'setNotificationChannelAsync');
6
7
  }
8
+ if (channel?.importance === AndroidImportance.UNSPECIFIED) {
9
+ console.warn(`Warning: You are setting the importance of the notification channel "${channelId}" to "UNSPECIFIED". ` +
10
+ `This may lead to errors on some Android versions. ` +
11
+ `It's recommended to instead use AndroidImportance.DEFAULT.`);
12
+ }
7
13
  return await NotificationChannelManager.setNotificationChannelAsync(channelId, channel);
8
14
  }
9
15
  //# sourceMappingURL=setNotificationChannelAsync.android.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"setNotificationChannelAsync.android.js","sourceRoot":"","sources":["../src/setNotificationChannelAsync.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,0BAA0B,MAAM,8BAA8B,CAAC;AAGtE,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,2BAA2B,CACvD,SAAiB,EACjB,OAAiC;IAEjC,IAAI,CAAC,0BAA0B,CAAC,2BAA2B,EAAE,CAAC;QAC5D,MAAM,IAAI,mBAAmB,CAAC,eAAe,EAAE,6BAA6B,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,MAAM,0BAA0B,CAAC,2BAA2B,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1F,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport NotificationChannelManager from './NotificationChannelManager';\nimport { NotificationChannelInput, NotificationChannel } from './NotificationChannelManager.types';\n\nexport default async function setNotificationChannelAsync(\n channelId: string,\n channel: NotificationChannelInput\n): Promise<NotificationChannel | null> {\n if (!NotificationChannelManager.setNotificationChannelAsync) {\n throw new UnavailabilityError('Notifications', 'setNotificationChannelAsync');\n }\n\n return await NotificationChannelManager.setNotificationChannelAsync(channelId, channel);\n}\n"]}
1
+ {"version":3,"file":"setNotificationChannelAsync.android.js","sourceRoot":"","sources":["../src/setNotificationChannelAsync.android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,0BAA0B,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAGL,iBAAiB,GAClB,MAAM,oCAAoC,CAAC;AAE5C,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,2BAA2B,CACvD,SAAiB,EACjB,OAAiC;IAEjC,IAAI,CAAC,0BAA0B,CAAC,2BAA2B,EAAE,CAAC;QAC5D,MAAM,IAAI,mBAAmB,CAAC,eAAe,EAAE,6BAA6B,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,OAAO,EAAE,UAAU,KAAK,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAC1D,OAAO,CAAC,IAAI,CACV,wEAAwE,SAAS,sBAAsB;YACrG,oDAAoD;YACpD,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,0BAA0B,CAAC,2BAA2B,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1F,CAAC","sourcesContent":["import { UnavailabilityError } from 'expo-modules-core';\n\nimport NotificationChannelManager from './NotificationChannelManager';\nimport {\n NotificationChannelInput,\n NotificationChannel,\n AndroidImportance,\n} from './NotificationChannelManager.types';\n\nexport default async function setNotificationChannelAsync(\n channelId: string,\n channel: NotificationChannelInput\n): Promise<NotificationChannel | null> {\n if (!NotificationChannelManager.setNotificationChannelAsync) {\n throw new UnavailabilityError('Notifications', 'setNotificationChannelAsync');\n }\n\n if (channel?.importance === AndroidImportance.UNSPECIFIED) {\n console.warn(\n `Warning: You are setting the importance of the notification channel \"${channelId}\" to \"UNSPECIFIED\". ` +\n `This may lead to errors on some Android versions. ` +\n `It's recommended to instead use AndroidImportance.DEFAULT.`\n );\n }\n return await NotificationChannelManager.setNotificationChannelAsync(channelId, channel);\n}\n"]}
@@ -28,12 +28,13 @@
28
28
  "expo.modules.notifications.notifications.presentation.ExpoNotificationPresentationModule",
29
29
  "expo.modules.notifications.notifications.scheduling.NotificationScheduler",
30
30
  "expo.modules.notifications.serverregistration.ServerRegistrationModule",
31
- "expo.modules.notifications.tokens.PushTokenModule"
31
+ "expo.modules.notifications.tokens.PushTokenModule",
32
+ "expo.modules.notifications.notifications.channels.AndroidXNotificationsChannelsProvider"
32
33
  ],
33
34
  "publication": {
34
35
  "groupId": "host.exp.exponent",
35
36
  "artifactId": "expo.modules.notifications",
36
- "version": "1.0.0-canary-20251216-3f01dbf",
37
+ "version": "1.0.0-canary-20251230-fc48ddc",
37
38
  "repository": "local-maven-repo"
38
39
  }
39
40
  }
@@ -0,0 +1 @@
1
+ 3fe203e8c1c35d49611c938915f170a0a47dbb968c52547b11d641a714035d1269d9d39de745d24fbfeb6260f62132b9e725ce77b60ba74c87b69b34679749a3