expo-notifications 0.24.1 → 0.24.2
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.
- package/CHANGELOG.md +4 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/notifications/badge/BadgeHelper.kt +24 -0
- package/android/src/main/java/expo/modules/notifications/badge/BadgeModule.kt +2 -19
- package/android/src/main/java/expo/modules/notifications/notifications/background/ExpoBackgroundNotificationTasksModule.kt +44 -0
- package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelGroupManagerModule.kt +77 -0
- package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelManagerModule.kt +89 -0
- package/android/src/main/java/expo/modules/notifications/notifications/emitting/NotificationsEmitter.kt +77 -0
- package/android/src/main/java/expo/modules/notifications/notifications/handling/NotificationsHandler.kt +113 -0
- package/android/src/main/java/expo/modules/notifications/notifications/handling/SingleNotificationHandlerTask.java +1 -1
- package/android/src/main/java/expo/modules/notifications/serverregistration/ServerRegistrationModule.kt +29 -0
- package/android/src/main/java/expo/modules/notifications/tokens/PushTokenModule.kt +98 -0
- package/package.json +2 -2
- package/android/src/main/java/expo/modules/notifications/notifications/background/ExpoBackgroundNotificationTasksModule.java +0 -50
- package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelGroupManagerModule.java +0 -98
- package/android/src/main/java/expo/modules/notifications/notifications/channels/NotificationChannelManagerModule.java +0 -109
- package/android/src/main/java/expo/modules/notifications/notifications/emitting/NotificationsEmitter.java +0 -98
- package/android/src/main/java/expo/modules/notifications/notifications/handling/NotificationsHandler.java +0 -136
- package/android/src/main/java/expo/modules/notifications/serverregistration/ServerRegistrationModule.java +0 -41
- package/android/src/main/java/expo/modules/notifications/tokens/PushTokenModule.java +0 -116
package/CHANGELOG.md
CHANGED
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '0.24.
|
|
6
|
+
version = '0.24.2'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -70,7 +70,7 @@ android {
|
|
|
70
70
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
71
71
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
72
72
|
versionCode 21
|
|
73
|
-
versionName '0.24.
|
|
73
|
+
versionName '0.24.2'
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
lintOptions {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package expo.modules.notifications.badge
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import me.leolin.shortcutbadger.ShortcutBadgeException
|
|
6
|
+
import me.leolin.shortcutbadger.ShortcutBadger
|
|
7
|
+
|
|
8
|
+
object BadgeHelper {
|
|
9
|
+
var badgeCount = 0
|
|
10
|
+
get() = synchronized(this) { field }
|
|
11
|
+
private set(value) = synchronized(this) { field = value }
|
|
12
|
+
|
|
13
|
+
fun setBadgeCount(context: Context, badgeCount: Int): Boolean {
|
|
14
|
+
return try {
|
|
15
|
+
ShortcutBadger.applyCountOrThrow(context.applicationContext, badgeCount)
|
|
16
|
+
BadgeHelper.badgeCount = badgeCount
|
|
17
|
+
true
|
|
18
|
+
} catch (e: ShortcutBadgeException) {
|
|
19
|
+
Log.d("expo-notifications", "Could not have set badge count: ${e.message}", e)
|
|
20
|
+
e.printStackTrace()
|
|
21
|
+
false
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1,37 +1,20 @@
|
|
|
1
1
|
package expo.modules.notifications.badge
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
|
-
import android.util.Log
|
|
5
4
|
import expo.modules.core.ExportedModule
|
|
6
5
|
import expo.modules.core.Promise
|
|
7
6
|
import expo.modules.core.interfaces.ExpoMethod
|
|
8
|
-
import me.leolin.shortcutbadger.ShortcutBadgeException
|
|
9
|
-
import me.leolin.shortcutbadger.ShortcutBadger
|
|
10
7
|
|
|
11
8
|
class BadgeModule(context: Context) : ExportedModule(context) {
|
|
12
9
|
override fun getName(): String = "ExpoBadgeModule"
|
|
13
10
|
|
|
14
11
|
@ExpoMethod
|
|
15
12
|
fun getBadgeCountAsync(promise: Promise) {
|
|
16
|
-
promise.resolve(badgeCount)
|
|
13
|
+
promise.resolve(BadgeHelper.badgeCount)
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
@ExpoMethod
|
|
20
17
|
fun setBadgeCountAsync(badgeCount: Int, promise: Promise) {
|
|
21
|
-
|
|
22
|
-
ShortcutBadger.applyCountOrThrow(context.applicationContext, badgeCount)
|
|
23
|
-
BadgeModule.badgeCount = badgeCount
|
|
24
|
-
promise.resolve(true)
|
|
25
|
-
} catch (e: ShortcutBadgeException) {
|
|
26
|
-
Log.d("expo-notifications", "Could not have set badge count: ${e.message}", e)
|
|
27
|
-
e.printStackTrace()
|
|
28
|
-
promise.resolve(false)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
companion object {
|
|
33
|
-
var badgeCount = 0
|
|
34
|
-
get() = synchronized(this) { field }
|
|
35
|
-
set(value) = synchronized(this) { field = value }
|
|
18
|
+
promise.resolve(BadgeHelper.setBadgeCount(context, badgeCount))
|
|
36
19
|
}
|
|
37
20
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
package expo.modules.notifications.notifications.background
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import expo.modules.core.ExportedModule
|
|
5
|
+
import expo.modules.core.ModuleRegistry
|
|
6
|
+
import expo.modules.core.Promise
|
|
7
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
8
|
+
import expo.modules.interfaces.taskManager.TaskManagerInterface
|
|
9
|
+
|
|
10
|
+
class ExpoBackgroundNotificationTasksModule(context: Context?) : ExportedModule(context) {
|
|
11
|
+
private lateinit var taskManager: TaskManagerInterface
|
|
12
|
+
override fun getName(): String = "ExpoBackgroundNotificationTasksModule"
|
|
13
|
+
|
|
14
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
15
|
+
taskManager = moduleRegistry.getModule(TaskManagerInterface::class.java)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@ExpoMethod
|
|
19
|
+
fun registerTaskAsync(taskName: String?, promise: Promise) {
|
|
20
|
+
try {
|
|
21
|
+
taskManager.registerTask(
|
|
22
|
+
taskName,
|
|
23
|
+
BackgroundRemoteNotificationTaskConsumer::class.java,
|
|
24
|
+
emptyMap()
|
|
25
|
+
)
|
|
26
|
+
promise.resolve(null)
|
|
27
|
+
} catch (e: Exception) {
|
|
28
|
+
promise.reject(e)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@ExpoMethod
|
|
33
|
+
fun unregisterTaskAsync(taskName: String?, promise: Promise) {
|
|
34
|
+
try {
|
|
35
|
+
taskManager.unregisterTask(
|
|
36
|
+
taskName,
|
|
37
|
+
BackgroundRemoteNotificationTaskConsumer::class.java
|
|
38
|
+
)
|
|
39
|
+
promise.resolve(null)
|
|
40
|
+
} catch (e: Exception) {
|
|
41
|
+
promise.reject(e)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
package expo.modules.notifications.notifications.channels
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Build
|
|
5
|
+
import expo.modules.core.ExportedModule
|
|
6
|
+
import expo.modules.core.ModuleRegistry
|
|
7
|
+
import expo.modules.core.Promise
|
|
8
|
+
import expo.modules.core.arguments.ReadableArguments
|
|
9
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
10
|
+
import expo.modules.notifications.notifications.channels.managers.NotificationsChannelGroupManager
|
|
11
|
+
import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelGroupSerializer
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* An exported module responsible for exposing methods for managing notification channel groups.
|
|
15
|
+
*/
|
|
16
|
+
class NotificationChannelGroupManagerModule(context: Context) : ExportedModule(context) {
|
|
17
|
+
private lateinit var groupManager: NotificationsChannelGroupManager
|
|
18
|
+
private lateinit var groupSerializer: NotificationsChannelGroupSerializer
|
|
19
|
+
|
|
20
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
21
|
+
val provider = moduleRegistry.getModule(NotificationsChannelsProvider::class.java)
|
|
22
|
+
groupManager = provider.groupManager
|
|
23
|
+
groupSerializer = provider.groupSerializer
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override fun getName(): String = "ExpoNotificationChannelGroupManager"
|
|
27
|
+
|
|
28
|
+
@ExpoMethod
|
|
29
|
+
fun getNotificationChannelGroupAsync(groupId: String, promise: Promise) {
|
|
30
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
31
|
+
promise.resolve(null)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
val group = groupManager.getNotificationChannelGroup(groupId)
|
|
35
|
+
promise.resolve(groupSerializer.toBundle(group))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ExpoMethod
|
|
39
|
+
fun getNotificationChannelGroupsAsync(promise: Promise) {
|
|
40
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
41
|
+
promise.resolve(null)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
val serializedChannels = groupManager
|
|
45
|
+
.notificationChannelGroups
|
|
46
|
+
.map(groupSerializer::toBundle)
|
|
47
|
+
promise.resolve(serializedChannels)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@ExpoMethod
|
|
51
|
+
fun setNotificationChannelGroupAsync(groupId: String, groupOptions: ReadableArguments, promise: Promise) {
|
|
52
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
53
|
+
promise.resolve(null)
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
val group = groupManager.createNotificationChannelGroup(
|
|
57
|
+
groupId,
|
|
58
|
+
getNameFromOptions(groupOptions),
|
|
59
|
+
groupOptions
|
|
60
|
+
)
|
|
61
|
+
promise.resolve(groupSerializer.toBundle(group))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@ExpoMethod
|
|
65
|
+
fun deleteNotificationChannelGroupAsync(groupId: String, promise: Promise) {
|
|
66
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
67
|
+
promise.resolve(null)
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
groupManager.deleteNotificationChannelGroup(groupId)
|
|
71
|
+
promise.resolve(null)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private fun getNameFromOptions(groupOptions: ReadableArguments): String {
|
|
75
|
+
return groupOptions.getString(NotificationsChannelGroupSerializer.NAME_KEY)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
package expo.modules.notifications.notifications.channels
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Build
|
|
5
|
+
import androidx.annotation.RequiresApi
|
|
6
|
+
import expo.modules.core.ExportedModule
|
|
7
|
+
import expo.modules.core.ModuleRegistry
|
|
8
|
+
import expo.modules.core.Promise
|
|
9
|
+
import expo.modules.core.arguments.ReadableArguments
|
|
10
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
11
|
+
import expo.modules.notifications.notifications.channels.managers.NotificationsChannelManager
|
|
12
|
+
import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelSerializer
|
|
13
|
+
import expo.modules.notifications.notifications.enums.NotificationImportance
|
|
14
|
+
import java.util.Collections
|
|
15
|
+
import java.util.Objects
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* An exported module responsible for exposing methods for managing notification channels.
|
|
19
|
+
*/
|
|
20
|
+
open class NotificationChannelManagerModule(context: Context?) : ExportedModule(context) {
|
|
21
|
+
private lateinit var channelManager: NotificationsChannelManager
|
|
22
|
+
private lateinit var channelSerializer: NotificationsChannelSerializer
|
|
23
|
+
|
|
24
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
25
|
+
val provider = moduleRegistry.getModule(NotificationsChannelsProvider::class.java)
|
|
26
|
+
channelManager = provider.channelManager
|
|
27
|
+
channelSerializer = provider.channelSerializer
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
override fun getName(): String = "ExpoNotificationChannelManager"
|
|
31
|
+
|
|
32
|
+
@ExpoMethod
|
|
33
|
+
fun getNotificationChannelAsync(channelId: String, promise: Promise) {
|
|
34
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
35
|
+
promise.resolve(null)
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
val notificationChannel = channelManager.getNotificationChannel(channelId)
|
|
39
|
+
promise.resolve(channelSerializer.toBundle(notificationChannel))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@ExpoMethod
|
|
43
|
+
fun getNotificationChannelsAsync(promise: Promise) {
|
|
44
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
45
|
+
promise.resolve(Collections.EMPTY_LIST)
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
val serializedChannels = channelManager
|
|
49
|
+
.notificationChannels
|
|
50
|
+
.map(channelSerializer::toBundle)
|
|
51
|
+
promise.resolve(serializedChannels)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@ExpoMethod
|
|
55
|
+
fun setNotificationChannelAsync(channelId: String, channelOptions: ReadableArguments, promise: Promise) {
|
|
56
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
57
|
+
promise.resolve(null)
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
val channel = channelManager.createNotificationChannel(
|
|
61
|
+
channelId,
|
|
62
|
+
getNameFromOptions(channelOptions),
|
|
63
|
+
getImportanceFromOptions(channelOptions),
|
|
64
|
+
channelOptions
|
|
65
|
+
)
|
|
66
|
+
promise.resolve(channelSerializer.toBundle(channel))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@ExpoMethod
|
|
70
|
+
fun deleteNotificationChannelAsync(channelId: String, promise: Promise) {
|
|
71
|
+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
|
72
|
+
promise.resolve(null)
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
channelManager.deleteNotificationChannel(channelId)
|
|
76
|
+
promise.resolve(null)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private fun getNameFromOptions(channelOptions: ReadableArguments): CharSequence {
|
|
80
|
+
return channelOptions.getString(NotificationsChannelSerializer.NAME_KEY)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
84
|
+
private fun getImportanceFromOptions(channelOptions: ReadableArguments): Int {
|
|
85
|
+
val enumValue = channelOptions.getInt(NotificationsChannelSerializer.IMPORTANCE_KEY, NotificationImportance.DEFAULT.enumValue)
|
|
86
|
+
val importance = Objects.requireNonNull(NotificationImportance.fromEnumValue(enumValue))
|
|
87
|
+
return importance.nativeValue
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
package expo.modules.notifications.notifications.emitting
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import expo.modules.core.ExportedModule
|
|
6
|
+
import expo.modules.core.ModuleRegistry
|
|
7
|
+
import expo.modules.core.Promise
|
|
8
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
9
|
+
import expo.modules.core.interfaces.services.EventEmitter
|
|
10
|
+
import expo.modules.notifications.notifications.NotificationSerializer
|
|
11
|
+
import expo.modules.notifications.notifications.interfaces.NotificationListener
|
|
12
|
+
import expo.modules.notifications.notifications.interfaces.NotificationManager
|
|
13
|
+
import expo.modules.notifications.notifications.model.Notification
|
|
14
|
+
import expo.modules.notifications.notifications.model.NotificationResponse
|
|
15
|
+
|
|
16
|
+
private const val NEW_MESSAGE_EVENT_NAME = "onDidReceiveNotification"
|
|
17
|
+
private const val NEW_RESPONSE_EVENT_NAME = "onDidReceiveNotificationResponse"
|
|
18
|
+
private const val MESSAGES_DELETED_EVENT_NAME = "onNotificationsDeleted"
|
|
19
|
+
|
|
20
|
+
open class NotificationsEmitter(context: Context) : ExportedModule(context), NotificationListener {
|
|
21
|
+
private lateinit var notificationManager: NotificationManager
|
|
22
|
+
private var lastNotificationResponse: NotificationResponse? = null
|
|
23
|
+
private var eventEmitter: EventEmitter? = null
|
|
24
|
+
override fun getName(): String = "ExpoNotificationsEmitter"
|
|
25
|
+
|
|
26
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
27
|
+
eventEmitter = moduleRegistry.getModule(EventEmitter::class.java)
|
|
28
|
+
|
|
29
|
+
// Register the module as a listener in NotificationManager singleton module.
|
|
30
|
+
// Deregistration happens in onDestroy callback.
|
|
31
|
+
notificationManager = requireNotNull(moduleRegistry.getSingletonModule("NotificationManager", NotificationManager::class.java))
|
|
32
|
+
notificationManager.addListener(this)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun onDestroy() {
|
|
36
|
+
notificationManager.removeListener(this)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@ExpoMethod
|
|
40
|
+
fun getLastNotificationResponseAsync(promise: Promise) {
|
|
41
|
+
promise.resolve(lastNotificationResponse?.let(NotificationSerializer::toBundle))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Callback called when [NotificationManager] gets notified of a new notification.
|
|
46
|
+
* Emits a [NEW_MESSAGE_EVENT_NAME] event.
|
|
47
|
+
*
|
|
48
|
+
* @param notification Notification received
|
|
49
|
+
*/
|
|
50
|
+
override fun onNotificationReceived(notification: Notification) {
|
|
51
|
+
eventEmitter?.emit(NEW_MESSAGE_EVENT_NAME, NotificationSerializer.toBundle(notification))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Callback called when [NotificationManager] gets notified of a new notification response.
|
|
56
|
+
* Emits a [NEW_RESPONSE_EVENT_NAME] event.
|
|
57
|
+
*
|
|
58
|
+
* @param response Notification response received
|
|
59
|
+
* @return Whether notification has been handled
|
|
60
|
+
*/
|
|
61
|
+
override fun onNotificationResponseReceived(response: NotificationResponse): Boolean {
|
|
62
|
+
lastNotificationResponse = response
|
|
63
|
+
eventEmitter?.let {
|
|
64
|
+
it.emit(NEW_RESPONSE_EVENT_NAME, NotificationSerializer.toBundle(response))
|
|
65
|
+
return true
|
|
66
|
+
}
|
|
67
|
+
return false
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Callback called when [NotificationManager] gets informed of the fact of message dropping.
|
|
72
|
+
* Emits a [MESSAGES_DELETED_EVENT_NAME] event.
|
|
73
|
+
*/
|
|
74
|
+
override fun onNotificationsDropped() {
|
|
75
|
+
eventEmitter?.emit(MESSAGES_DELETED_EVENT_NAME, Bundle.EMPTY)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package expo.modules.notifications.notifications.handling
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Handler
|
|
5
|
+
import android.os.HandlerThread
|
|
6
|
+
import expo.modules.core.ExportedModule
|
|
7
|
+
import expo.modules.core.ModuleRegistry
|
|
8
|
+
import expo.modules.core.Promise
|
|
9
|
+
import expo.modules.core.arguments.ReadableArguments
|
|
10
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
11
|
+
import expo.modules.notifications.notifications.interfaces.NotificationListener
|
|
12
|
+
import expo.modules.notifications.notifications.interfaces.NotificationManager
|
|
13
|
+
import expo.modules.notifications.notifications.model.Notification
|
|
14
|
+
import expo.modules.notifications.notifications.model.NotificationBehavior
|
|
15
|
+
|
|
16
|
+
private const val SHOULD_SHOW_ALERT_KEY = "shouldShowAlert"
|
|
17
|
+
private const val SHOULD_PLAY_SOUND_KEY = "shouldPlaySound"
|
|
18
|
+
private const val SHOULD_SET_BADGE_KEY = "shouldSetBadge"
|
|
19
|
+
private const val PRIORITY_KEY = "priority"
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* [NotificationListener] responsible for managing app's reaction to incoming
|
|
23
|
+
* notification.
|
|
24
|
+
*
|
|
25
|
+
*
|
|
26
|
+
* It is responsible for managing lifecycles of [SingleNotificationHandlerTask]s
|
|
27
|
+
* which are responsible: one for each notification. This module serves as holder
|
|
28
|
+
* for all of them and a proxy through which app responds with the behavior.
|
|
29
|
+
*/
|
|
30
|
+
open class NotificationsHandler(context: Context) : ExportedModule(context), NotificationListener {
|
|
31
|
+
private lateinit var notificationManager: NotificationManager
|
|
32
|
+
private lateinit var moduleRegistry: ModuleRegistry
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* [HandlerThread] which is the host to the notifications handler.
|
|
36
|
+
*/
|
|
37
|
+
private lateinit var notificationsHandlerThread: HandlerThread
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* [Handler] on which lifecycle events are executed.
|
|
41
|
+
*/
|
|
42
|
+
private lateinit var handler: Handler
|
|
43
|
+
|
|
44
|
+
private val tasksMap = mutableMapOf<String, SingleNotificationHandlerTask>()
|
|
45
|
+
|
|
46
|
+
override fun getName(): String = "ExpoNotificationsHandlerModule"
|
|
47
|
+
|
|
48
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
49
|
+
this.moduleRegistry = moduleRegistry
|
|
50
|
+
|
|
51
|
+
// Register the module as a listener in NotificationManager singleton module.
|
|
52
|
+
// Deregistration happens in onDestroy callback.
|
|
53
|
+
notificationManager = requireNotNull(moduleRegistry.getSingletonModule("NotificationManager", NotificationManager::class.java))
|
|
54
|
+
notificationManager.addListener(this)
|
|
55
|
+
notificationsHandlerThread = HandlerThread("NotificationsHandlerThread - " + this.javaClass.toString())
|
|
56
|
+
notificationsHandlerThread.start()
|
|
57
|
+
handler = Handler(notificationsHandlerThread.looper)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override fun onDestroy() {
|
|
61
|
+
notificationManager.removeListener(this)
|
|
62
|
+
|
|
63
|
+
tasksMap.values.forEach(SingleNotificationHandlerTask::stop)
|
|
64
|
+
|
|
65
|
+
// We don't have to use `quitSafely` here, cause all tasks were stopped
|
|
66
|
+
notificationsHandlerThread.quit()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Called by the app with [ReadableArguments] representing requested behavior
|
|
71
|
+
* that should be applied to the notification.
|
|
72
|
+
*
|
|
73
|
+
* @param identifier Identifier of the task which asked for behavior.
|
|
74
|
+
* @param behavior Behavior to apply to the notification.
|
|
75
|
+
* @param promise Promise to resolve once the notification is successfully presented
|
|
76
|
+
* or fails to be presented.
|
|
77
|
+
*/
|
|
78
|
+
@ExpoMethod
|
|
79
|
+
fun handleNotificationAsync(identifier: String, behavior: ReadableArguments, promise: Promise) {
|
|
80
|
+
val task = tasksMap[identifier]
|
|
81
|
+
if (task == null) {
|
|
82
|
+
promise.reject("ERR_NOTIFICATION_HANDLED", "Failed to handle notification $identifier, it has already been handled.")
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
val shouldShowAlert = behavior.getBoolean(SHOULD_SHOW_ALERT_KEY)
|
|
86
|
+
val shouldPlaySound = behavior.getBoolean(SHOULD_PLAY_SOUND_KEY)
|
|
87
|
+
val shouldSetBadge = behavior.getBoolean(SHOULD_SET_BADGE_KEY)
|
|
88
|
+
val priorityOverride = behavior.getString(PRIORITY_KEY)
|
|
89
|
+
task.handleResponse(NotificationBehavior(shouldShowAlert, shouldPlaySound, shouldSetBadge, priorityOverride), promise)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Callback called by [NotificationManager] to inform its listeners of new messages.
|
|
94
|
+
* Starts up a new [SingleNotificationHandlerTask] which will take it on from here.
|
|
95
|
+
*
|
|
96
|
+
* @param notification Notification received
|
|
97
|
+
*/
|
|
98
|
+
override fun onNotificationReceived(notification: Notification) {
|
|
99
|
+
val task = SingleNotificationHandlerTask(context, handler, moduleRegistry, notification, this)
|
|
100
|
+
tasksMap[task.identifier] = task
|
|
101
|
+
task.start()
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Callback called once [SingleNotificationHandlerTask] finishes.
|
|
106
|
+
* A cue for removal of the task.
|
|
107
|
+
*
|
|
108
|
+
* @param task Task that just fulfilled its responsibility.
|
|
109
|
+
*/
|
|
110
|
+
fun onTaskFinished(task: SingleNotificationHandlerTask) {
|
|
111
|
+
tasksMap.remove(task.identifier)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -17,7 +17,7 @@ import expo.modules.notifications.service.NotificationsService;
|
|
|
17
17
|
/**
|
|
18
18
|
* A "task" responsible for managing response to a single notification.
|
|
19
19
|
*/
|
|
20
|
-
|
|
20
|
+
public class SingleNotificationHandlerTask {
|
|
21
21
|
/**
|
|
22
22
|
* Name of the event asking the delegate for behavior.
|
|
23
23
|
*/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package expo.modules.notifications.serverregistration
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import expo.modules.core.ExportedModule
|
|
5
|
+
import expo.modules.core.Promise
|
|
6
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
7
|
+
|
|
8
|
+
open class ServerRegistrationModule(context: Context) : ExportedModule(context) {
|
|
9
|
+
protected val installationId = InstallationId(context)
|
|
10
|
+
private val mRegistrationInfo = RegistrationInfo(context)
|
|
11
|
+
|
|
12
|
+
override fun getName(): String = "NotificationsServerRegistrationModule"
|
|
13
|
+
|
|
14
|
+
@ExpoMethod
|
|
15
|
+
open fun getInstallationIdAsync(promise: Promise) {
|
|
16
|
+
promise.resolve(installationId.orCreateUUID)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@ExpoMethod
|
|
20
|
+
fun getRegistrationInfoAsync(promise: Promise) {
|
|
21
|
+
promise.resolve(mRegistrationInfo.get())
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@ExpoMethod
|
|
25
|
+
fun setRegistrationInfoAsync(registrationInfo: String?, promise: Promise) {
|
|
26
|
+
mRegistrationInfo.set(registrationInfo)
|
|
27
|
+
promise.resolve(null)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
package expo.modules.notifications.tokens
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.os.Bundle
|
|
5
|
+
import com.google.firebase.messaging.FirebaseMessaging
|
|
6
|
+
import expo.modules.core.ExportedModule
|
|
7
|
+
import expo.modules.core.ModuleRegistry
|
|
8
|
+
import expo.modules.core.Promise
|
|
9
|
+
import expo.modules.core.interfaces.ExpoMethod
|
|
10
|
+
import expo.modules.core.interfaces.services.EventEmitter
|
|
11
|
+
import expo.modules.notifications.tokens.interfaces.PushTokenListener
|
|
12
|
+
import expo.modules.notifications.tokens.interfaces.PushTokenManager
|
|
13
|
+
|
|
14
|
+
private const val NEW_TOKEN_EVENT_NAME = "onDevicePushToken"
|
|
15
|
+
private const val NEW_TOKEN_EVENT_TOKEN_KEY = "devicePushToken"
|
|
16
|
+
private const val REGISTRATION_FAIL_CODE = "E_REGISTRATION_FAILED"
|
|
17
|
+
private const val UNREGISTER_FOR_NOTIFICATIONS_FAIL_CODE = "E_UNREGISTER_FOR_NOTIFICATIONS_FAILED"
|
|
18
|
+
|
|
19
|
+
class PushTokenModule(context: Context) : ExportedModule(context), PushTokenListener {
|
|
20
|
+
private lateinit var tokenManager: PushTokenManager
|
|
21
|
+
private var eventEmitter: EventEmitter? = null
|
|
22
|
+
override fun getName(): String = "ExpoPushTokenManager"
|
|
23
|
+
|
|
24
|
+
override fun onCreate(moduleRegistry: ModuleRegistry) {
|
|
25
|
+
eventEmitter = moduleRegistry.getModule(EventEmitter::class.java)
|
|
26
|
+
|
|
27
|
+
// Register the module as a listener in PushTokenManager singleton module.
|
|
28
|
+
// Deregistration happens in onDestroy callback.
|
|
29
|
+
tokenManager = requireNotNull(
|
|
30
|
+
moduleRegistry.getSingletonModule("PushTokenManager", PushTokenManager::class.java)
|
|
31
|
+
)
|
|
32
|
+
tokenManager.addListener(this)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun onDestroy() {
|
|
36
|
+
tokenManager.removeListener(this)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Fetches Firebase push token and resolves the promise.
|
|
41
|
+
*
|
|
42
|
+
* @param promise Promise to be resolved with the token.
|
|
43
|
+
*/
|
|
44
|
+
@ExpoMethod
|
|
45
|
+
fun getDevicePushTokenAsync(promise: Promise) {
|
|
46
|
+
FirebaseMessaging.getInstance().token
|
|
47
|
+
.addOnCompleteListener { task ->
|
|
48
|
+
if (!task.isSuccessful) {
|
|
49
|
+
val exception = task.exception
|
|
50
|
+
if (exception == null) {
|
|
51
|
+
promise.reject(REGISTRATION_FAIL_CODE, "Fetching the token failed.")
|
|
52
|
+
} else {
|
|
53
|
+
promise.reject(REGISTRATION_FAIL_CODE, "Fetching the token failed: ${exception.message}", exception)
|
|
54
|
+
}
|
|
55
|
+
return@addOnCompleteListener
|
|
56
|
+
}
|
|
57
|
+
val token = task.result
|
|
58
|
+
if (token == null) {
|
|
59
|
+
promise.reject(REGISTRATION_FAIL_CODE, "Fetching the token failed. Invalid token.")
|
|
60
|
+
return@addOnCompleteListener
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
promise.resolve(token)
|
|
64
|
+
onNewToken(token)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@ExpoMethod
|
|
69
|
+
fun unregisterForNotificationsAsync(promise: Promise) {
|
|
70
|
+
FirebaseMessaging.getInstance().deleteToken()
|
|
71
|
+
.addOnCompleteListener { task ->
|
|
72
|
+
if (!task.isSuccessful) {
|
|
73
|
+
val exception = task.exception
|
|
74
|
+
if (exception == null) {
|
|
75
|
+
promise.reject(UNREGISTER_FOR_NOTIFICATIONS_FAIL_CODE, "Unregistering for notifications failed.")
|
|
76
|
+
} else {
|
|
77
|
+
promise.reject(UNREGISTER_FOR_NOTIFICATIONS_FAIL_CODE, "Unregistering for notifications failed: ${exception.message}", exception)
|
|
78
|
+
}
|
|
79
|
+
return@addOnCompleteListener
|
|
80
|
+
}
|
|
81
|
+
promise.resolve(null)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Callback called when [PushTokenManager] gets notified of a new token.
|
|
87
|
+
* Emits a [NEW_TOKEN_EVENT_NAME] event.
|
|
88
|
+
*
|
|
89
|
+
* @param token New push token.
|
|
90
|
+
*/
|
|
91
|
+
override fun onNewToken(token: String) {
|
|
92
|
+
eventEmitter?.let {
|
|
93
|
+
val eventBody = Bundle()
|
|
94
|
+
eventBody.putString(NEW_TOKEN_EVENT_TOKEN_KEY, token)
|
|
95
|
+
it.emit(NEW_TOKEN_EVENT_NAME, eventBody)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-notifications",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
4
4
|
"description": "Notifications module",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"expo": "*"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "62f76105dfb436f7144440d6e6077d4ff3263842"
|
|
61
61
|
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.notifications.background;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
|
|
5
|
-
import expo.modules.core.ExportedModule;
|
|
6
|
-
import expo.modules.core.ModuleRegistry;
|
|
7
|
-
import expo.modules.core.Promise;
|
|
8
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
9
|
-
import expo.modules.interfaces.taskManager.TaskManagerInterface;
|
|
10
|
-
|
|
11
|
-
import java.util.Collections;
|
|
12
|
-
|
|
13
|
-
public class ExpoBackgroundNotificationTasksModule extends ExportedModule {
|
|
14
|
-
private TaskManagerInterface mTaskManager;
|
|
15
|
-
|
|
16
|
-
public ExpoBackgroundNotificationTasksModule(Context context) {
|
|
17
|
-
super(context);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
@Override
|
|
21
|
-
public String getName() {
|
|
22
|
-
return "ExpoBackgroundNotificationTasksModule";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@Override
|
|
26
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
27
|
-
mTaskManager = moduleRegistry.getModule(TaskManagerInterface.class);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@ExpoMethod
|
|
31
|
-
public void registerTaskAsync(String taskName, final Promise promise) {
|
|
32
|
-
try {
|
|
33
|
-
mTaskManager.registerTask(
|
|
34
|
-
taskName, BackgroundRemoteNotificationTaskConsumer.class, Collections.emptyMap());
|
|
35
|
-
promise.resolve(null);
|
|
36
|
-
} catch (Exception e) {
|
|
37
|
-
promise.reject(e);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@ExpoMethod
|
|
42
|
-
public void unregisterTaskAsync(String taskName, final Promise promise) {
|
|
43
|
-
try {
|
|
44
|
-
mTaskManager.unregisterTask(taskName, BackgroundRemoteNotificationTaskConsumer.class);
|
|
45
|
-
promise.resolve(null);
|
|
46
|
-
} catch (Exception e) {
|
|
47
|
-
promise.reject(e);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.notifications.channels;
|
|
2
|
-
|
|
3
|
-
import android.app.NotificationChannelGroup;
|
|
4
|
-
import android.content.Context;
|
|
5
|
-
import android.os.Bundle;
|
|
6
|
-
|
|
7
|
-
import expo.modules.core.ExportedModule;
|
|
8
|
-
import expo.modules.core.ModuleRegistry;
|
|
9
|
-
import expo.modules.core.Promise;
|
|
10
|
-
import expo.modules.core.arguments.ReadableArguments;
|
|
11
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
12
|
-
|
|
13
|
-
import java.util.ArrayList;
|
|
14
|
-
import java.util.List;
|
|
15
|
-
|
|
16
|
-
import expo.modules.notifications.notifications.channels.managers.NotificationsChannelGroupManager;
|
|
17
|
-
import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelGroupSerializer;
|
|
18
|
-
|
|
19
|
-
import static expo.modules.notifications.notifications.channels.serializers.NotificationsChannelGroupSerializer.NAME_KEY;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* An exported module responsible for exposing methods for managing notification channel groups.
|
|
23
|
-
*/
|
|
24
|
-
public class NotificationChannelGroupManagerModule extends ExportedModule {
|
|
25
|
-
private final static String EXPORTED_NAME = "ExpoNotificationChannelGroupManager";
|
|
26
|
-
|
|
27
|
-
private NotificationsChannelGroupManager mGroupManager;
|
|
28
|
-
private NotificationsChannelGroupSerializer mGroupSerializer;
|
|
29
|
-
|
|
30
|
-
public NotificationChannelGroupManagerModule(Context context) {
|
|
31
|
-
super(context);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
@Override
|
|
35
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
36
|
-
NotificationsChannelsProvider provider = moduleRegistry.getModule(NotificationsChannelsProvider.class);
|
|
37
|
-
mGroupManager = provider.getGroupManager();
|
|
38
|
-
mGroupSerializer = provider.getGroupSerializer();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@Override
|
|
42
|
-
public String getName() {
|
|
43
|
-
return EXPORTED_NAME;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@ExpoMethod
|
|
47
|
-
public void getNotificationChannelGroupAsync(String groupId, Promise promise) {
|
|
48
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
49
|
-
promise.resolve(null);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
NotificationChannelGroup group = mGroupManager.getNotificationChannelGroup(groupId);
|
|
54
|
-
promise.resolve(mGroupSerializer.toBundle(group));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
@ExpoMethod
|
|
58
|
-
public void getNotificationChannelGroupsAsync(Promise promise) {
|
|
59
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
60
|
-
promise.resolve(null);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
List<NotificationChannelGroup> existingChannels = mGroupManager.getNotificationChannelGroups();
|
|
65
|
-
List<Bundle> serializedChannels = new ArrayList<>(existingChannels.size());
|
|
66
|
-
for (NotificationChannelGroup channelGroup : existingChannels) {
|
|
67
|
-
serializedChannels.add(mGroupSerializer.toBundle(channelGroup));
|
|
68
|
-
}
|
|
69
|
-
promise.resolve(serializedChannels);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
@ExpoMethod
|
|
73
|
-
public void setNotificationChannelGroupAsync(String groupId, ReadableArguments groupOptions, Promise promise) {
|
|
74
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
75
|
-
promise.resolve(null);
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
NotificationChannelGroup group = mGroupManager.createNotificationChannelGroup(groupId, getNameFromOptions(groupOptions), groupOptions);
|
|
80
|
-
promise.resolve(mGroupSerializer.toBundle(group));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
@ExpoMethod
|
|
84
|
-
public void deleteNotificationChannelGroupAsync(String groupId, Promise promise) {
|
|
85
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
86
|
-
promise.resolve(null);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
mGroupManager.deleteNotificationChannelGroup(groupId);
|
|
91
|
-
promise.resolve(null);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
protected CharSequence getNameFromOptions(ReadableArguments groupOptions) {
|
|
96
|
-
return groupOptions.getString(NAME_KEY);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.notifications.channels;
|
|
2
|
-
|
|
3
|
-
import android.app.NotificationChannel;
|
|
4
|
-
import android.content.Context;
|
|
5
|
-
import android.os.Build;
|
|
6
|
-
import android.os.Bundle;
|
|
7
|
-
|
|
8
|
-
import expo.modules.core.ExportedModule;
|
|
9
|
-
import expo.modules.core.ModuleRegistry;
|
|
10
|
-
import expo.modules.core.Promise;
|
|
11
|
-
import expo.modules.core.arguments.ReadableArguments;
|
|
12
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
13
|
-
|
|
14
|
-
import java.util.ArrayList;
|
|
15
|
-
import java.util.Collections;
|
|
16
|
-
import java.util.List;
|
|
17
|
-
import java.util.Objects;
|
|
18
|
-
|
|
19
|
-
import androidx.annotation.RequiresApi;
|
|
20
|
-
import expo.modules.notifications.notifications.channels.managers.NotificationsChannelManager;
|
|
21
|
-
import expo.modules.notifications.notifications.channels.serializers.NotificationsChannelSerializer;
|
|
22
|
-
import expo.modules.notifications.notifications.enums.NotificationImportance;
|
|
23
|
-
|
|
24
|
-
import static expo.modules.notifications.notifications.channels.serializers.NotificationsChannelSerializer.IMPORTANCE_KEY;
|
|
25
|
-
import static expo.modules.notifications.notifications.channels.serializers.NotificationsChannelSerializer.NAME_KEY;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* An exported module responsible for exposing methods for managing notification channels.
|
|
29
|
-
*/
|
|
30
|
-
public class NotificationChannelManagerModule extends ExportedModule {
|
|
31
|
-
private final static String EXPORTED_NAME = "ExpoNotificationChannelManager";
|
|
32
|
-
|
|
33
|
-
private NotificationsChannelManager mChannelManager;
|
|
34
|
-
private NotificationsChannelSerializer mChannelSerializer;
|
|
35
|
-
|
|
36
|
-
public NotificationChannelManagerModule(Context context) {
|
|
37
|
-
super(context);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
@Override
|
|
41
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
42
|
-
NotificationsChannelsProvider provider = moduleRegistry.getModule(NotificationsChannelsProvider.class);
|
|
43
|
-
mChannelManager = provider.getChannelManager();
|
|
44
|
-
mChannelSerializer = provider.getChannelSerializer();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@Override
|
|
48
|
-
public String getName() {
|
|
49
|
-
return EXPORTED_NAME;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@ExpoMethod
|
|
53
|
-
public void getNotificationChannelAsync(String channelId, Promise promise) {
|
|
54
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
55
|
-
promise.resolve(null);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
promise.resolve(mChannelSerializer.toBundle(mChannelManager.getNotificationChannel(channelId)));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
@ExpoMethod
|
|
63
|
-
public void getNotificationChannelsAsync(Promise promise) {
|
|
64
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
65
|
-
promise.resolve(Collections.EMPTY_LIST);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
List<NotificationChannel> existingChannels = mChannelManager.getNotificationChannels();
|
|
70
|
-
List<Bundle> serializedChannels = new ArrayList<>(existingChannels.size());
|
|
71
|
-
for (NotificationChannel channel : existingChannels) {
|
|
72
|
-
serializedChannels.add(mChannelSerializer.toBundle(channel));
|
|
73
|
-
}
|
|
74
|
-
promise.resolve(serializedChannels);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
@ExpoMethod
|
|
78
|
-
public void setNotificationChannelAsync(String channelId, ReadableArguments channelOptions, Promise promise) {
|
|
79
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
80
|
-
promise.resolve(null);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
NotificationChannel channel = mChannelManager.createNotificationChannel(channelId, getNameFromOptions(channelOptions), getImportanceFromOptions(channelOptions), channelOptions);
|
|
85
|
-
promise.resolve(mChannelSerializer.toBundle(channel));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@ExpoMethod
|
|
89
|
-
public void deleteNotificationChannelAsync(String channelId, Promise promise) {
|
|
90
|
-
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
|
|
91
|
-
promise.resolve(null);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
mChannelManager.deleteNotificationChannel(channelId);
|
|
96
|
-
promise.resolve(null);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
protected CharSequence getNameFromOptions(ReadableArguments channelOptions) {
|
|
100
|
-
return channelOptions.getString(NAME_KEY);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
@RequiresApi(api = Build.VERSION_CODES.N)
|
|
104
|
-
protected int getImportanceFromOptions(ReadableArguments channelOptions) {
|
|
105
|
-
int enumValue = channelOptions.getInt(IMPORTANCE_KEY, NotificationImportance.DEFAULT.getEnumValue());
|
|
106
|
-
NotificationImportance importance = Objects.requireNonNull(NotificationImportance.fromEnumValue(enumValue));
|
|
107
|
-
return importance.getNativeValue();
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.notifications.emitting;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.os.Bundle;
|
|
5
|
-
|
|
6
|
-
import expo.modules.core.ExportedModule;
|
|
7
|
-
import expo.modules.core.ModuleRegistry;
|
|
8
|
-
import expo.modules.core.Promise;
|
|
9
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
10
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
11
|
-
|
|
12
|
-
import expo.modules.notifications.notifications.NotificationSerializer;
|
|
13
|
-
import expo.modules.notifications.notifications.interfaces.NotificationListener;
|
|
14
|
-
import expo.modules.notifications.notifications.interfaces.NotificationManager;
|
|
15
|
-
import expo.modules.notifications.notifications.model.Notification;
|
|
16
|
-
import expo.modules.notifications.notifications.model.NotificationResponse;
|
|
17
|
-
|
|
18
|
-
public class NotificationsEmitter extends ExportedModule implements NotificationListener {
|
|
19
|
-
private final static String EXPORTED_NAME = "ExpoNotificationsEmitter";
|
|
20
|
-
|
|
21
|
-
private final static String NEW_MESSAGE_EVENT_NAME = "onDidReceiveNotification";
|
|
22
|
-
private final static String NEW_RESPONSE_EVENT_NAME = "onDidReceiveNotificationResponse";
|
|
23
|
-
private final static String MESSAGES_DELETED_EVENT_NAME = "onNotificationsDeleted";
|
|
24
|
-
|
|
25
|
-
private NotificationManager mNotificationManager;
|
|
26
|
-
private NotificationResponse mLastNotificationResponse;
|
|
27
|
-
private EventEmitter mEventEmitter;
|
|
28
|
-
|
|
29
|
-
public NotificationsEmitter(Context context) {
|
|
30
|
-
super(context);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@Override
|
|
34
|
-
public String getName() {
|
|
35
|
-
return EXPORTED_NAME;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
@Override
|
|
39
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
40
|
-
mEventEmitter = moduleRegistry.getModule(EventEmitter.class);
|
|
41
|
-
|
|
42
|
-
// Register the module as a listener in NotificationManager singleton module.
|
|
43
|
-
// Deregistration happens in onDestroy callback.
|
|
44
|
-
mNotificationManager = moduleRegistry.getSingletonModule("NotificationManager", NotificationManager.class);
|
|
45
|
-
mNotificationManager.addListener(this);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
@Override
|
|
49
|
-
public void onDestroy() {
|
|
50
|
-
mNotificationManager.removeListener(this);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@ExpoMethod
|
|
54
|
-
public void getLastNotificationResponseAsync(Promise promise) {
|
|
55
|
-
promise.resolve(mLastNotificationResponse != null ? NotificationSerializer.toBundle(mLastNotificationResponse) : null);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Callback called when {@link NotificationManager} gets notified of a new notification.
|
|
60
|
-
* Emits a {@link NotificationsEmitter#NEW_MESSAGE_EVENT_NAME} event.
|
|
61
|
-
*
|
|
62
|
-
* @param notification Notification received
|
|
63
|
-
*/
|
|
64
|
-
@Override
|
|
65
|
-
public void onNotificationReceived(Notification notification) {
|
|
66
|
-
if (mEventEmitter != null) {
|
|
67
|
-
mEventEmitter.emit(NEW_MESSAGE_EVENT_NAME, NotificationSerializer.toBundle(notification));
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Callback called when {@link NotificationManager} gets notified of a new notification response.
|
|
73
|
-
* Emits a {@link NotificationsEmitter#NEW_RESPONSE_EVENT_NAME} event.
|
|
74
|
-
*
|
|
75
|
-
* @param response Notification response received
|
|
76
|
-
* @return Whether notification has been handled
|
|
77
|
-
*/
|
|
78
|
-
@Override
|
|
79
|
-
public boolean onNotificationResponseReceived(NotificationResponse response) {
|
|
80
|
-
mLastNotificationResponse = response;
|
|
81
|
-
if (mEventEmitter != null) {
|
|
82
|
-
mEventEmitter.emit(NEW_RESPONSE_EVENT_NAME, NotificationSerializer.toBundle(response));
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Callback called when {@link NotificationManager} gets informed of the fact of message dropping.
|
|
90
|
-
* Emits a {@link NotificationsEmitter#MESSAGES_DELETED_EVENT_NAME} event.
|
|
91
|
-
*/
|
|
92
|
-
@Override
|
|
93
|
-
public void onNotificationsDropped() {
|
|
94
|
-
if (mEventEmitter != null) {
|
|
95
|
-
mEventEmitter.emit(MESSAGES_DELETED_EVENT_NAME, Bundle.EMPTY);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.notifications.handling;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.os.Handler;
|
|
5
|
-
import android.os.HandlerThread;
|
|
6
|
-
|
|
7
|
-
import expo.modules.core.ExportedModule;
|
|
8
|
-
import expo.modules.core.ModuleRegistry;
|
|
9
|
-
import expo.modules.core.Promise;
|
|
10
|
-
import expo.modules.core.arguments.ReadableArguments;
|
|
11
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
12
|
-
|
|
13
|
-
import java.util.Collection;
|
|
14
|
-
import java.util.HashMap;
|
|
15
|
-
import java.util.Map;
|
|
16
|
-
|
|
17
|
-
import expo.modules.notifications.notifications.emitting.NotificationsEmitter;
|
|
18
|
-
import expo.modules.notifications.notifications.interfaces.NotificationListener;
|
|
19
|
-
import expo.modules.notifications.notifications.interfaces.NotificationManager;
|
|
20
|
-
import expo.modules.notifications.notifications.model.Notification;
|
|
21
|
-
import expo.modules.notifications.notifications.model.NotificationBehavior;
|
|
22
|
-
import expo.modules.notifications.notifications.model.NotificationResponse;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* {@link NotificationListener} responsible for managing app's reaction to incoming
|
|
26
|
-
* notification.
|
|
27
|
-
* <p>
|
|
28
|
-
* It is responsible for managing lifecycles of {@link SingleNotificationHandlerTask}s
|
|
29
|
-
* which are responsible: one for each notification. This module serves as holder
|
|
30
|
-
* for all of them and a proxy through which app responds with the behavior.
|
|
31
|
-
*/
|
|
32
|
-
public class NotificationsHandler extends ExportedModule implements NotificationListener {
|
|
33
|
-
private final static String EXPORTED_NAME = "ExpoNotificationsHandlerModule";
|
|
34
|
-
|
|
35
|
-
private static final String SHOULD_SHOW_ALERT_KEY = "shouldShowAlert";
|
|
36
|
-
private static final String SHOULD_PLAY_SOUND_KEY = "shouldPlaySound";
|
|
37
|
-
private static final String SHOULD_SET_BADGE_KEY = "shouldSetBadge";
|
|
38
|
-
private static final String PRIORITY_KEY = "priority";
|
|
39
|
-
|
|
40
|
-
private NotificationManager mNotificationManager;
|
|
41
|
-
private ModuleRegistry mModuleRegistry;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* {@link HandlerThread} which is the host to the notifications handler.
|
|
45
|
-
*/
|
|
46
|
-
private HandlerThread mNotificationsHandlerThread = null;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* {@link Handler} on which lifecycle events are executed.
|
|
50
|
-
*/
|
|
51
|
-
private Handler mHandler = null;
|
|
52
|
-
|
|
53
|
-
private Map<String, SingleNotificationHandlerTask> mTasksMap = new HashMap<>();
|
|
54
|
-
|
|
55
|
-
public NotificationsHandler(Context context) {
|
|
56
|
-
super(context);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@Override
|
|
60
|
-
public String getName() {
|
|
61
|
-
return EXPORTED_NAME;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@Override
|
|
65
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
66
|
-
mModuleRegistry = moduleRegistry;
|
|
67
|
-
|
|
68
|
-
// Register the module as a listener in NotificationManager singleton module.
|
|
69
|
-
// Deregistration happens in onDestroy callback.
|
|
70
|
-
mNotificationManager = moduleRegistry.getSingletonModule("NotificationManager", NotificationManager.class);
|
|
71
|
-
mNotificationManager.addListener(this);
|
|
72
|
-
|
|
73
|
-
mNotificationsHandlerThread = new HandlerThread("NotificationsHandlerThread - " + this.getClass().toString());
|
|
74
|
-
mNotificationsHandlerThread.start();
|
|
75
|
-
mHandler = new Handler(mNotificationsHandlerThread.getLooper());
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@Override
|
|
79
|
-
public void onDestroy() {
|
|
80
|
-
mNotificationManager.removeListener(this);
|
|
81
|
-
Collection<SingleNotificationHandlerTask> tasks = mTasksMap.values();
|
|
82
|
-
for (SingleNotificationHandlerTask task : tasks) {
|
|
83
|
-
task.stop();
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// We don't have to use `quitSafely` here, cause all tasks were stopped
|
|
87
|
-
mNotificationsHandlerThread.quit();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Called by the app with {@link ReadableArguments} representing requested behavior
|
|
92
|
-
* that should be applied to the notification.
|
|
93
|
-
*
|
|
94
|
-
* @param identifier Identifier of the task which asked for behavior.
|
|
95
|
-
* @param behavior Behavior to apply to the notification.
|
|
96
|
-
* @param promise Promise to resolve once the notification is successfully presented
|
|
97
|
-
* or fails to be presented.
|
|
98
|
-
*/
|
|
99
|
-
@ExpoMethod
|
|
100
|
-
public void handleNotificationAsync(String identifier, final ReadableArguments behavior, Promise promise) {
|
|
101
|
-
SingleNotificationHandlerTask task = mTasksMap.get(identifier);
|
|
102
|
-
if (task == null) {
|
|
103
|
-
String message = String.format("Failed to handle notification %s, it has already been handled.", identifier);
|
|
104
|
-
promise.reject("ERR_NOTIFICATION_HANDLED", message);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
boolean shouldShowAlert = behavior.getBoolean(SHOULD_SHOW_ALERT_KEY);
|
|
108
|
-
boolean shouldPlaySound = behavior.getBoolean(SHOULD_PLAY_SOUND_KEY);
|
|
109
|
-
boolean shouldSetBadge = behavior.getBoolean(SHOULD_SET_BADGE_KEY);
|
|
110
|
-
String priorityOverride = behavior.getString(PRIORITY_KEY);
|
|
111
|
-
task.handleResponse(new NotificationBehavior(shouldShowAlert, shouldPlaySound, shouldSetBadge, priorityOverride), promise);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Callback called by {@link NotificationManager} to inform its listeners of new messages.
|
|
116
|
-
* Starts up a new {@link SingleNotificationHandlerTask} which will take it on from here.
|
|
117
|
-
*
|
|
118
|
-
* @param notification Notification received
|
|
119
|
-
*/
|
|
120
|
-
@Override
|
|
121
|
-
public void onNotificationReceived(Notification notification) {
|
|
122
|
-
SingleNotificationHandlerTask task = new SingleNotificationHandlerTask(getContext(), mHandler, mModuleRegistry, notification, this);
|
|
123
|
-
mTasksMap.put(task.getIdentifier(), task);
|
|
124
|
-
task.start();
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Callback called once {@link SingleNotificationHandlerTask} finishes.
|
|
129
|
-
* A cue for removal of the task.
|
|
130
|
-
*
|
|
131
|
-
* @param task Task that just fulfilled its responsibility.
|
|
132
|
-
*/
|
|
133
|
-
void onTaskFinished(SingleNotificationHandlerTask task) {
|
|
134
|
-
mTasksMap.remove(task.getIdentifier());
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.serverregistration;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
|
|
5
|
-
import expo.modules.core.ExportedModule;
|
|
6
|
-
import expo.modules.core.Promise;
|
|
7
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
8
|
-
|
|
9
|
-
public class ServerRegistrationModule extends ExportedModule {
|
|
10
|
-
private static final String EXPORTED_NAME = "NotificationsServerRegistrationModule";
|
|
11
|
-
|
|
12
|
-
protected InstallationId mInstallationId;
|
|
13
|
-
private RegistrationInfo mRegistrationInfo;
|
|
14
|
-
|
|
15
|
-
public ServerRegistrationModule(Context context) {
|
|
16
|
-
super(context);
|
|
17
|
-
mInstallationId = new InstallationId(context);
|
|
18
|
-
mRegistrationInfo = new RegistrationInfo(context);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
@Override
|
|
22
|
-
public String getName() {
|
|
23
|
-
return EXPORTED_NAME;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@ExpoMethod
|
|
27
|
-
public void getInstallationIdAsync(Promise promise) {
|
|
28
|
-
promise.resolve(mInstallationId.getOrCreateUUID());
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
@ExpoMethod
|
|
32
|
-
public void getRegistrationInfoAsync(Promise promise) {
|
|
33
|
-
promise.resolve(mRegistrationInfo.get());
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@ExpoMethod
|
|
37
|
-
public void setRegistrationInfoAsync(String registrationInfo, Promise promise) {
|
|
38
|
-
mRegistrationInfo.set(registrationInfo);
|
|
39
|
-
promise.resolve(null);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
package expo.modules.notifications.tokens;
|
|
2
|
-
|
|
3
|
-
import android.content.Context;
|
|
4
|
-
import android.os.Bundle;
|
|
5
|
-
|
|
6
|
-
import com.google.android.gms.tasks.OnCompleteListener;
|
|
7
|
-
import com.google.android.gms.tasks.Task;
|
|
8
|
-
import com.google.firebase.messaging.FirebaseMessaging;
|
|
9
|
-
|
|
10
|
-
import expo.modules.core.ExportedModule;
|
|
11
|
-
import expo.modules.core.ModuleRegistry;
|
|
12
|
-
import expo.modules.core.Promise;
|
|
13
|
-
import expo.modules.core.interfaces.ExpoMethod;
|
|
14
|
-
import expo.modules.core.interfaces.services.EventEmitter;
|
|
15
|
-
|
|
16
|
-
import androidx.annotation.NonNull;
|
|
17
|
-
import expo.modules.notifications.tokens.interfaces.PushTokenListener;
|
|
18
|
-
import expo.modules.notifications.tokens.interfaces.PushTokenManager;
|
|
19
|
-
|
|
20
|
-
public class PushTokenModule extends ExportedModule implements PushTokenListener {
|
|
21
|
-
private final static String EXPORTED_NAME = "ExpoPushTokenManager";
|
|
22
|
-
|
|
23
|
-
private final static String NEW_TOKEN_EVENT_NAME = "onDevicePushToken";
|
|
24
|
-
private final static String NEW_TOKEN_EVENT_TOKEN_KEY = "devicePushToken";
|
|
25
|
-
|
|
26
|
-
private final static String REGISTRATION_FAIL_CODE = "E_REGISTRATION_FAILED";
|
|
27
|
-
private final static String UNREGISTER_FOR_NOTIFICATIONS_FAIL_CODE = "E_UNREGISTER_FOR_NOTIFICATIONS_FAILED";
|
|
28
|
-
|
|
29
|
-
private PushTokenManager mPushTokenManager;
|
|
30
|
-
private EventEmitter mEventEmitter;
|
|
31
|
-
|
|
32
|
-
public PushTokenModule(Context context) {
|
|
33
|
-
super(context);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@Override
|
|
37
|
-
public String getName() {
|
|
38
|
-
return EXPORTED_NAME;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@Override
|
|
43
|
-
public void onCreate(ModuleRegistry moduleRegistry) {
|
|
44
|
-
mEventEmitter = moduleRegistry.getModule(EventEmitter.class);
|
|
45
|
-
|
|
46
|
-
// Register the module as a listener in PushTokenManager singleton module.
|
|
47
|
-
// Deregistration happens in onDestroy callback.
|
|
48
|
-
mPushTokenManager = moduleRegistry.getSingletonModule("PushTokenManager", PushTokenManager.class);
|
|
49
|
-
mPushTokenManager.addListener(this);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@Override
|
|
53
|
-
public void onDestroy() {
|
|
54
|
-
mPushTokenManager.removeListener(this);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Fetches Firebase push token and resolves the promise.
|
|
59
|
-
*
|
|
60
|
-
* @param promise Promise to be resolved with the token.
|
|
61
|
-
*/
|
|
62
|
-
@ExpoMethod
|
|
63
|
-
public void getDevicePushTokenAsync(final Promise promise) {
|
|
64
|
-
FirebaseMessaging.getInstance().getToken()
|
|
65
|
-
.addOnCompleteListener(new OnCompleteListener<String>() {
|
|
66
|
-
@Override
|
|
67
|
-
public void onComplete(@NonNull Task<String> task) {
|
|
68
|
-
if (!task.isSuccessful() || task.getResult() == null) {
|
|
69
|
-
if (task.getException() == null) {
|
|
70
|
-
promise.reject(REGISTRATION_FAIL_CODE, "Fetching the token failed.");
|
|
71
|
-
} else {
|
|
72
|
-
promise.reject(REGISTRATION_FAIL_CODE, "Fetching the token failed: " + task.getException().getMessage(), task.getException());
|
|
73
|
-
}
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
String token = task.getResult();
|
|
78
|
-
|
|
79
|
-
promise.resolve(token);
|
|
80
|
-
onNewToken(token);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@ExpoMethod
|
|
86
|
-
public void unregisterForNotificationsAsync(final Promise promise) {
|
|
87
|
-
FirebaseMessaging.getInstance().deleteToken()
|
|
88
|
-
.addOnCompleteListener(task -> {
|
|
89
|
-
if (!task.isSuccessful()) {
|
|
90
|
-
if (task.getException() == null) {
|
|
91
|
-
promise.reject(UNREGISTER_FOR_NOTIFICATIONS_FAIL_CODE, "Unregistering for notifications failed.");
|
|
92
|
-
} else {
|
|
93
|
-
promise.reject(UNREGISTER_FOR_NOTIFICATIONS_FAIL_CODE, "Unregistering for notifications failed: " + task.getException().getMessage(), task.getException());
|
|
94
|
-
}
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
promise.resolve(null);
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Callback called when {@link PushTokenManager} gets notified of a new token.
|
|
104
|
-
* Emits a {@link PushTokenModule#NEW_TOKEN_EVENT_NAME} event.
|
|
105
|
-
*
|
|
106
|
-
* @param token New push token.
|
|
107
|
-
*/
|
|
108
|
-
@Override
|
|
109
|
-
public void onNewToken(String token) {
|
|
110
|
-
if (mEventEmitter != null) {
|
|
111
|
-
Bundle eventBody = new Bundle();
|
|
112
|
-
eventBody.putString(NEW_TOKEN_EVENT_TOKEN_KEY, token);
|
|
113
|
-
mEventEmitter.emit(NEW_TOKEN_EVENT_NAME, eventBody);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|