trigger events on android

pull/340/head
Lucas Nogueira 2 years ago
parent cf47c8ef6d
commit cd6bf51e6e
No known key found for this signature in database
GPG Key ID: FFEA6C72E73482F1

@ -29,7 +29,7 @@ class Notification {
var attachments: List<NotificationAttachment>? = null
var schedule: NotificationSchedule? = null
var channelId: String? = null
var source: String? = null
var source: JSObject? = null
var visibility: Int? = null
var number: Int? = null
@ -104,7 +104,7 @@ class Notification {
fun fromJSObject(jsonObject: JSObject): Notification {
val notification = Notification()
notification.source = jsonObject.toString()
notification.source = jsonObject
notification.id = jsonObject.getInteger("id") ?: throw Exception("Missing notification identifier")
notification.body = jsonObject.getString("body", null)
notification.largeBody = jsonObject.getString("largeBody", null)

@ -34,7 +34,17 @@ class NotificationPlugin(private val activity: Activity): Plugin(activity) {
private lateinit var notificationStorage: NotificationStorage
private var channelManager = ChannelManager(activity)
companion object {
var instance: NotificationPlugin? = null
fun triggerNotification(notification: JSObject) {
instance?.trigger("notification", notification)
}
}
override fun load(webView: WebView) {
instance = this
super.load(webView)
this.webView = webView
notificationStorage = NotificationStorage(activity)
@ -59,7 +69,7 @@ class NotificationPlugin(private val activity: Activity): Plugin(activity) {
}
val dataJson = manager.handleNotificationActionPerformed(intent, notificationStorage)
if (dataJson != null) {
// TODO trigger("actionPerformed", dataJson, true)
trigger("actionPerformed", dataJson)
}
}

@ -1,8 +1,8 @@
package app.tauri.notification
import android.annotation.SuppressLint
import android.text.format.DateUtils
import app.tauri.plugin.JSObject
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
@ -36,6 +36,7 @@ sealed class ScheduleKind {
class Every(val interval: NotificationInterval, val count: Int): ScheduleKind()
}
@SuppressLint("SimpleDateFormat")
class NotificationSchedule(val scheduleObj: JSObject) {
val kind: ScheduleKind
// Schedule this notification to fire even if app is idled (Doze)

@ -10,19 +10,15 @@ import java.text.ParseException
private const val NOTIFICATION_STORE_ID = "NOTIFICATION_STORE"
// Key used to save action types
private const val ACTION_TYPES_ID = "ACTION_TYPE_STORE"
private const val ID_KEY = "notificationIds"
class NotificationStorage(private val context: Context) {
/**
* Persist the id of currently scheduled notification
*/
fun appendNotifications(localNotifications: List<Notification>) {
val storage = getStorage(NOTIFICATION_STORE_ID)
val editor = storage.edit()
for (request in localNotifications) {
if (request.isScheduled) {
val key: String = request.id.toString()
editor.putString(key, request.source)
editor.putString(key, request.source.toString())
}
}
editor.apply()
@ -96,28 +92,16 @@ class NotificationStorage(private val context: Context) {
return notification
}
/**
* Remove the stored notifications
*/
fun deleteNotification(id: String?) {
val editor = getStorage(NOTIFICATION_STORE_ID).edit()
editor.remove(id)
editor.apply()
}
/**
* Shared private preferences for the application.
*/
private fun getStorage(key: String): SharedPreferences {
return context.getSharedPreferences(key, Context.MODE_PRIVATE)
}
/**
* Writes new action types (actions that being displayed in notification) to storage.
* Write will override previous data.
*
* @param typesMap - map with groupId and actionArray assigned to group
*/
fun writeActionGroup(typesMap: Map<String, List<NotificationAction>>) {
for ((id, notificationActions) in typesMap) {
val editor = getStorage(ACTION_TYPES_ID + id).edit()
@ -132,15 +116,10 @@ class NotificationStorage(private val context: Context) {
}
}
/**
* Retrieve array of notification actions per ActionTypeId
*
* @param forId - id of the group
*/
fun getActionGroup(forId: String): Array<NotificationAction?> {
val storage = getStorage(ACTION_TYPES_ID + forId)
val count = storage.getInt("count", 0)
val actions: Array<NotificationAction?> = arrayOfNulls<NotificationAction>(count)
val actions: Array<NotificationAction?> = arrayOfNulls(count)
for (i in 0 until count) {
val id = storage.getString("id$i", "")
val title = storage.getString("title$i", "")

@ -44,9 +44,6 @@ class TauriNotificationManager(
private var defaultSoundID: Int = AssetUtils.RESOURCE_ID_ZERO_VALUE
private var defaultSmallIconID: Int = AssetUtils.RESOURCE_ID_ZERO_VALUE
/**
* Method extecuted when notification is launched by user from the notification bar.
*/
fun handleNotificationActionPerformed(
data: Intent,
notificationStorage: NotificationStorage
@ -89,7 +86,7 @@ class TauriNotificationManager(
fun createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (SDK_INT >= Build.VERSION_CODES.O) {
val name: CharSequence = "Default"
val description = "Default"
val importance = NotificationManager.IMPORTANCE_DEFAULT
@ -212,16 +209,15 @@ class TauriNotificationManager(
if (notification.isScheduled) {
triggerScheduledNotification(buildNotification, notification)
} else {
notificationManager.notify(notification.id, buildNotification)
try {
// TODO notify
// val notificationJson = JSObject(notification.source ?: "")
NotificationPlugin.triggerNotification(notification.source ?: JSObject())
} catch (_: JSONException) {
}
notificationManager.notify(notification.id, buildNotification)
}
}
// Create intents for open/dissmis actions
// Create intents for open/dismiss actions
private fun createActionIntents(
notification: Notification,
mBuilder: NotificationCompat.Builder
@ -229,7 +225,7 @@ class TauriNotificationManager(
// Open intent
val intent = buildIntent(notification, DEFAULT_PRESS_ACTION)
var flags = PendingIntent.FLAG_CANCEL_CURRENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (SDK_INT >= Build.VERSION_CODES.S) {
flags = flags or PendingIntent.FLAG_MUTABLE
}
val pendingIntent = PendingIntent.getActivity(context, notification.id, intent, flags)
@ -297,7 +293,7 @@ class TauriNotificationManager(
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.putExtra(NOTIFICATION_INTENT_KEY, notification.id)
intent.putExtra(ACTION_INTENT_KEY, action)
intent.putExtra(NOTIFICATION_OBJ_INTENT_KEY, notification.source)
intent.putExtra(NOTIFICATION_OBJ_INTENT_KEY, notification.source.toString())
val schedule = notification.schedule
intent.putExtra(NOTIFICATION_IS_REMOVABLE_KEY, schedule == null || schedule.isRemovable())
return intent
@ -486,8 +482,10 @@ class TimedNotificationPublisher : BroadcastReceiver() {
Logger.error(Logger.tags("Notification"), "No valid id supplied", null)
}
val storage = NotificationStorage(context)
// TODO notify
// val notificationJson = storage.getSavedNotificationAsJSObject(id.toString())
val notificationJson = storage.getSavedNotificationAsJSObject(id.toString())
if (notificationJson != null) {
NotificationPlugin.triggerNotification(notificationJson)
}
notificationManager.notify(id, notification)
if (!rescheduleNotificationIfNeeded(context, intent, id)) {
storage.deleteNotification(id.toString())
@ -508,11 +506,11 @@ class TimedNotificationPublisher : BroadcastReceiver() {
val trigger = date.nextTrigger(Date())
val clone = intent.clone() as Intent
var flags = PendingIntent.FLAG_CANCEL_CURRENT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (SDK_INT >= Build.VERSION_CODES.S) {
flags = flags or PendingIntent.FLAG_MUTABLE
}
val pendingIntent = PendingIntent.getBroadcast(context, id, clone, flags)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !alarmManager.canScheduleExactAlarms()) {
if (SDK_INT >= Build.VERSION_CODES.S && !alarmManager.canScheduleExactAlarms()) {
alarmManager[AlarmManager.RTC, trigger] = pendingIntent
} else {
alarmManager.setExact(AlarmManager.RTC, trigger, pendingIntent)

@ -24,7 +24,7 @@
* @module
*/
import { invoke } from '@tauri-apps/api/tauri'
import { invoke, transformCallback } from '@tauri-apps/api/tauri'
/**
* Options to send a notification.
@ -548,6 +548,39 @@ async function channels(): Promise<Channel[]> {
return invoke('plugin:notification|getActive')
}
class EventChannel {
id: number
unregisterFn: (channel: EventChannel) => Promise<void>
constructor(id: number, unregisterFn: (channel: EventChannel) => Promise<void>) {
this.id = id
this.unregisterFn = unregisterFn
}
toJSON(): string {
return `__CHANNEL__:${this.id}`
}
async unregister(): Promise<void> {
return this.unregisterFn(this)
}
}
// TODO: use addPluginListener API on @tauri-apps/api/tauri 2.0.0-alpha.4
async function onNotificationReceived(cb: (notification: Options) => void): Promise<EventChannel> {
const channelId = transformCallback(cb)
const handler = new EventChannel(channelId, (channel) => invoke('plugin:notification|remove_listener', { event: 'notification', channelId: channel.id }))
return invoke('plugin:notification|register_listener', { event: 'notification', handler }).then(() => handler)
}
// TODO: use addPluginListener API on @tauri-apps/api/tauri 2.0.0-alpha.4
async function onAction(cb: (notification: Options) => void): Promise<EventChannel> {
const channelId = transformCallback(cb)
const handler = new EventChannel(channelId, (channel) => invoke('plugin:notification|remove_listener', { event: 'actionPerformed', channelId: channel.id }))
return invoke('plugin:notification|register_listener', { event: 'actionPerformed', handler }).then(() => handler)
}
export type { Attachment, Options, Permission, Action, ActionType, PendingNotification, ActiveNotification, Channel }
export {
@ -565,5 +598,8 @@ export {
removeAllActive,
createChannel,
removeChannel,
channels
channels,
onNotificationReceived,
onAction
}

Loading…
Cancel
Save