WIP: UnifiedPush
This commit is contained in:
parent
2387f2ce6c
commit
94e595110d
10 changed files with 341 additions and 13 deletions
150
app/schemas/io.heckel.ntfy.data.Database/5.json
Normal file
150
app/schemas/io.heckel.ntfy.data.Database/5.json
Normal file
|
@ -0,0 +1,150 @@
|
|||
{
|
||||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 5,
|
||||
"identityHash": "d72d045ad4ad20db887b4c6aed3da27b",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "Subscription",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `upAppId` TEXT NOT NULL, `upConnectorToken` TEXT NOT NULL, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "baseUrl",
|
||||
"columnName": "baseUrl",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "topic",
|
||||
"columnName": "topic",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "instant",
|
||||
"columnName": "instant",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "mutedUntil",
|
||||
"columnName": "mutedUntil",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "upAppId",
|
||||
"columnName": "upAppId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "upConnectorToken",
|
||||
"columnName": "upConnectorToken",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [
|
||||
{
|
||||
"name": "index_Subscription_baseUrl_topic",
|
||||
"unique": true,
|
||||
"columnNames": [
|
||||
"baseUrl",
|
||||
"topic"
|
||||
],
|
||||
"createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Subscription_baseUrl_topic` ON `${TABLE_NAME}` (`baseUrl`, `topic`)"
|
||||
}
|
||||
],
|
||||
"foreignKeys": []
|
||||
},
|
||||
{
|
||||
"tableName": "Notification",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `deleted` INTEGER NOT NULL, PRIMARY KEY(`id`, `subscriptionId`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
"columnName": "id",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "subscriptionId",
|
||||
"columnName": "subscriptionId",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "timestamp",
|
||||
"columnName": "timestamp",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "title",
|
||||
"columnName": "title",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "message",
|
||||
"columnName": "message",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "notificationId",
|
||||
"columnName": "notificationId",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "priority",
|
||||
"columnName": "priority",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true,
|
||||
"defaultValue": "3"
|
||||
},
|
||||
{
|
||||
"fieldPath": "tags",
|
||||
"columnName": "tags",
|
||||
"affinity": "TEXT",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "deleted",
|
||||
"columnName": "deleted",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
"columnNames": [
|
||||
"id",
|
||||
"subscriptionId"
|
||||
],
|
||||
"autoGenerate": false
|
||||
},
|
||||
"indices": [],
|
||||
"foreignKeys": []
|
||||
}
|
||||
],
|
||||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd72d045ad4ad20db887b4c6aed3da27b')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -64,6 +64,14 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Broadcast receiver for UnifiedPush; must match https://github.com/UnifiedPush/UP-spec/blob/main/specifications.md -->
|
||||
<receiver android:name=".up.BroadcastReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.android.distributor.REGISTER" />
|
||||
<action android:name="org.unifiedpush.android.distributor.UNREGISTER" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Firebase messaging (note that this is empty in the F-Droid flavor) -->
|
||||
<service
|
||||
android:name=".firebase.FirebaseService"
|
||||
|
|
|
@ -13,13 +13,15 @@ data class Subscription(
|
|||
@ColumnInfo(name = "topic") val topic: String,
|
||||
@ColumnInfo(name = "instant") val instant: Boolean,
|
||||
@ColumnInfo(name = "mutedUntil") val mutedUntil: Long, // TODO notificationSound, notificationSchedule
|
||||
@ColumnInfo(name = "upAppId") val upAppId: String,
|
||||
@ColumnInfo(name = "upConnectorToken") val upConnectorToken: String,
|
||||
@Ignore val totalCount: Int = 0, // Total notifications
|
||||
@Ignore val newCount: Int = 0, // New notifications
|
||||
@Ignore val lastActive: Long = 0, // Unix timestamp
|
||||
@Ignore val state: ConnectionState = ConnectionState.NOT_APPLICABLE
|
||||
) {
|
||||
constructor(id: Long, baseUrl: String, topic: String, instant: Boolean, mutedUntil: Long) :
|
||||
this(id, baseUrl, topic, instant, mutedUntil, 0, 0, 0, ConnectionState.NOT_APPLICABLE)
|
||||
constructor(id: Long, baseUrl: String, topic: String, instant: Boolean, mutedUntil: Long, upAppId: String, upConnectorToken: String) :
|
||||
this(id, baseUrl, topic, instant, mutedUntil, upAppId, upConnectorToken, 0, 0, 0, ConnectionState.NOT_APPLICABLE)
|
||||
}
|
||||
|
||||
enum class ConnectionState {
|
||||
|
@ -32,6 +34,8 @@ data class SubscriptionWithMetadata(
|
|||
val topic: String,
|
||||
val instant: Boolean,
|
||||
val mutedUntil: Long,
|
||||
val upAppId: String,
|
||||
val upConnectorToken: String,
|
||||
val totalCount: Int,
|
||||
val newCount: Int,
|
||||
val lastActive: Long
|
||||
|
@ -50,7 +54,7 @@ data class Notification(
|
|||
@ColumnInfo(name = "deleted") val deleted: Boolean,
|
||||
)
|
||||
|
||||
@androidx.room.Database(entities = [Subscription::class, Notification::class], version = 4)
|
||||
@androidx.room.Database(entities = [Subscription::class, Notification::class], version = 5)
|
||||
abstract class Database : RoomDatabase() {
|
||||
abstract fun subscriptionDao(): SubscriptionDao
|
||||
abstract fun notificationDao(): NotificationDao
|
||||
|
@ -66,6 +70,7 @@ abstract class Database : RoomDatabase() {
|
|||
.addMigrations(MIGRATION_1_2)
|
||||
.addMigrations(MIGRATION_2_3)
|
||||
.addMigrations(MIGRATION_3_4)
|
||||
.addMigrations(MIGRATION_4_5)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
this.instance = instance
|
||||
|
@ -102,6 +107,13 @@ abstract class Database : RoomDatabase() {
|
|||
db.execSQL("ALTER TABLE Notification_New RENAME TO Notification")
|
||||
}
|
||||
}
|
||||
|
||||
private val MIGRATION_4_5 = object : Migration(3, 4) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
db.execSQL("ALTER TABLE Subscription ADD COLUMN upAppId TEXT NOT NULL DEFAULT('')")
|
||||
db.execSQL("ALTER TABLE Subscription ADD COLUMN upConnectorToken TEXT NOT NULL DEFAULT('')")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +121,7 @@ abstract class Database : RoomDatabase() {
|
|||
interface SubscriptionDao {
|
||||
@Query("""
|
||||
SELECT
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil,
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.upAppId, s.upConnectorToken,
|
||||
COUNT(n.id) totalCount,
|
||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||
|
@ -122,7 +134,7 @@ interface SubscriptionDao {
|
|||
|
||||
@Query("""
|
||||
SELECT
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil,
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.upAppId, s.upConnectorToken,
|
||||
COUNT(n.id) totalCount,
|
||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||
|
@ -135,7 +147,7 @@ interface SubscriptionDao {
|
|||
|
||||
@Query("""
|
||||
SELECT
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil,
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.upAppId, s.upConnectorToken,
|
||||
COUNT(n.id) totalCount,
|
||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||
|
@ -148,7 +160,7 @@ interface SubscriptionDao {
|
|||
|
||||
@Query("""
|
||||
SELECT
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil,
|
||||
s.id, s.baseUrl, s.topic, s.instant, s.mutedUntil, s.upAppId, s.upConnectorToken,
|
||||
COUNT(n.id) totalCount,
|
||||
COUNT(CASE n.notificationId WHEN 0 THEN NULL ELSE n.id END) newCount,
|
||||
IFNULL(MAX(n.timestamp),0) AS lastActive
|
||||
|
|
|
@ -92,9 +92,9 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
|||
val detailsVisible = detailViewSubscriptionId.get() == notification.subscriptionId
|
||||
val muted = isMuted(notification.subscriptionId)
|
||||
val notify = !detailsVisible && !muted
|
||||
return NotificationAddResult(notify = notify, broadcast = true, muted = muted)
|
||||
return NotificationAddResult(notification = notification, notify = notify, broadcast = true, muted = muted)
|
||||
}
|
||||
return NotificationAddResult(notify = false, broadcast = false, muted = false)
|
||||
return NotificationAddResult(notification = notification, notify = false, broadcast = false, forward = false, muted = false)
|
||||
}
|
||||
|
||||
@Suppress("RedundantSuspendModifier")
|
||||
|
@ -177,6 +177,8 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
|||
topic = s.topic,
|
||||
instant = s.instant,
|
||||
mutedUntil = s.mutedUntil,
|
||||
upAppId = s.upAppId,
|
||||
upConnectorToken = s.upConnectorToken,
|
||||
totalCount = s.totalCount,
|
||||
newCount = s.newCount,
|
||||
lastActive = s.lastActive,
|
||||
|
@ -195,6 +197,8 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
|||
topic = s.topic,
|
||||
instant = s.instant,
|
||||
mutedUntil = s.mutedUntil,
|
||||
upAppId = s.upAppId,
|
||||
upConnectorToken = s.upConnectorToken,
|
||||
totalCount = s.totalCount,
|
||||
newCount = s.newCount,
|
||||
lastActive = s.lastActive,
|
||||
|
@ -225,8 +229,10 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
|
|||
}
|
||||
|
||||
data class NotificationAddResult(
|
||||
val notification: Notification,
|
||||
val notify: Boolean,
|
||||
val broadcast: Boolean,
|
||||
val forward: Boolean, // Forward to UnifiedPush connector
|
||||
val muted: Boolean,
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package io.heckel.ntfy.msg
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.TaskStackBuilder
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.media.RingtoneManager
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import io.heckel.ntfy.R
|
||||
import io.heckel.ntfy.data.Notification
|
||||
import io.heckel.ntfy.data.Subscription
|
||||
import io.heckel.ntfy.ui.DetailActivity
|
||||
import io.heckel.ntfy.ui.MainActivity
|
||||
import io.heckel.ntfy.util.formatMessage
|
||||
import io.heckel.ntfy.util.formatTitle
|
||||
|
||||
class NotificationDispatcher(val context: Context) {
|
||||
fun dispatch(subscription: Subscription, notification: Notification) {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "NtfyNotificationDispatcher"
|
||||
}
|
||||
}
|
|
@ -20,12 +20,9 @@ import io.heckel.ntfy.R
|
|||
import io.heckel.ntfy.app.Application
|
||||
import io.heckel.ntfy.data.Subscription
|
||||
import io.heckel.ntfy.util.topicShortUrl
|
||||
import io.heckel.ntfy.msg.ApiService
|
||||
import io.heckel.ntfy.msg.NotificationService
|
||||
import io.heckel.ntfy.work.PollWorker
|
||||
import io.heckel.ntfy.firebase.FirebaseMessenger
|
||||
import io.heckel.ntfy.msg.BroadcastService
|
||||
import io.heckel.ntfy.msg.SubscriberService
|
||||
import io.heckel.ntfy.msg.*
|
||||
import io.heckel.ntfy.util.fadeStatusBarColor
|
||||
import io.heckel.ntfy.util.formatDateShort
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -54,6 +51,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
|||
// Other stuff
|
||||
private var actionMode: ActionMode? = null
|
||||
private var workManager: WorkManager? = null // Context-dependent
|
||||
private var dispatcher: NotificationDispatcher? = null // Context-dependent
|
||||
private var notifier: NotificationService? = null // Context-dependent
|
||||
private var broadcaster: BroadcastService? = null // Context-dependent
|
||||
private var subscriberManager: SubscriberManager? = null // Context-dependent
|
||||
|
@ -67,6 +65,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
|||
|
||||
// Dependencies that depend on Context
|
||||
workManager = WorkManager.getInstance(this)
|
||||
dispatcher = NotificationDispatcher(this)
|
||||
notifier = NotificationService(this)
|
||||
broadcaster = BroadcastService(this)
|
||||
subscriberManager = SubscriberManager(this)
|
||||
|
@ -288,6 +287,8 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
|||
topic = topic,
|
||||
instant = instant,
|
||||
mutedUntil = 0,
|
||||
upAppId = "",
|
||||
upConnectorToken = "",
|
||||
totalCount = 0,
|
||||
newCount = 0,
|
||||
lastActive = Date().time/1000
|
||||
|
@ -342,6 +343,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
|
|||
newNotificationsCount++
|
||||
val notificationWithId = notification.copy(notificationId = Random.nextInt())
|
||||
val result = repository.addNotification(notificationWithId)
|
||||
dispatcher?.dispatch()
|
||||
if (result.notify) {
|
||||
notifier?.send(subscription, notificationWithId)
|
||||
}
|
||||
|
|
62
app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt
Normal file
62
app/src/main/java/io/heckel/ntfy/up/BroadcastReceiver.kt
Normal file
|
@ -0,0 +1,62 @@
|
|||
package io.heckel.ntfy.up
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import io.heckel.ntfy.R
|
||||
import io.heckel.ntfy.app.Application
|
||||
import io.heckel.ntfy.data.Subscription
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import kotlin.random.Random
|
||||
|
||||
class BroadcastReceiver : android.content.BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
when (intent!!.action) {
|
||||
ACTION_REGISTER -> {
|
||||
val appId = intent.getStringExtra(EXTRA_APPLICATION) ?: ""
|
||||
val connectorToken = intent.getStringExtra(EXTRA_TOKEN) ?: ""
|
||||
Log.d(TAG, "Register: app=$appId, connectorToken=$connectorToken")
|
||||
if (appId.isBlank()) {
|
||||
Log.w(TAG, "Trying to register an app without packageName")
|
||||
return
|
||||
}
|
||||
|
||||
val baseUrl = context!!.getString(R.string.app_base_url) // FIXME
|
||||
val topic = connectorToken // FIXME
|
||||
val app = context!!.applicationContext as Application
|
||||
val repository = app.repository
|
||||
val subscription = Subscription(
|
||||
id = Random.nextLong(),
|
||||
baseUrl = baseUrl,
|
||||
topic = topic,
|
||||
instant = true,
|
||||
mutedUntil = 0,
|
||||
upAppId = appId,
|
||||
upConnectorToken = connectorToken,
|
||||
totalCount = 0,
|
||||
newCount = 0,
|
||||
lastActive = Date().time/1000
|
||||
)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
repository.addSubscription(subscription)
|
||||
}
|
||||
|
||||
sendEndpoint(context!!, appId, connectorToken)
|
||||
// XXXXXXXXX
|
||||
}
|
||||
ACTION_UNREGISTER -> {
|
||||
val connectorToken = intent.getStringExtra(EXTRA_TOKEN) ?: ""
|
||||
Log.d(TAG, "Unregister: connectorToken=$connectorToken")
|
||||
// XXXXXXX
|
||||
sendUnregistered(context!!, "org.unifiedpush.example", connectorToken)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "NtfyUpBroadcastRecv"
|
||||
}
|
||||
}
|
22
app/src/main/java/io/heckel/ntfy/up/Constants.kt
Normal file
22
app/src/main/java/io/heckel/ntfy/up/Constants.kt
Normal file
|
@ -0,0 +1,22 @@
|
|||
package io.heckel.ntfy.up
|
||||
|
||||
/**
|
||||
* Constants as defined on the specs
|
||||
* https://github.com/UnifiedPush/UP-spec/blob/main/specifications.md
|
||||
*/
|
||||
|
||||
const val ACTION_NEW_ENDPOINT = "org.unifiedpush.android.connector.NEW_ENDPOINT"
|
||||
const val ACTION_REGISTRATION_FAILED = "org.unifiedpush.android.connector.REGISTRATION_FAILED"
|
||||
const val ACTION_REGISTRATION_REFUSED = "org.unifiedpush.android.connector.REGISTRATION_REFUSED"
|
||||
const val ACTION_UNREGISTERED = "org.unifiedpush.android.connector.UNREGISTERED"
|
||||
const val ACTION_MESSAGE = "org.unifiedpush.android.connector.MESSAGE"
|
||||
|
||||
const val ACTION_REGISTER = "org.unifiedpush.android.distributor.REGISTER"
|
||||
const val ACTION_UNREGISTER = "org.unifiedpush.android.distributor.UNREGISTER"
|
||||
const val ACTION_MESSAGE_ACK = "org.unifiedpush.android.distributor.MESSAGE_ACK"
|
||||
|
||||
const val EXTRA_APPLICATION = "application"
|
||||
const val EXTRA_TOKEN = "token"
|
||||
const val EXTRA_ENDPOINT = "endpoint"
|
||||
const val EXTRA_MESSAGE = "message"
|
||||
const val EXTRA_MESSAGE_ID = "id"
|
34
app/src/main/java/io/heckel/ntfy/up/DistributorUtils.kt
Normal file
34
app/src/main/java/io/heckel/ntfy/up/DistributorUtils.kt
Normal file
|
@ -0,0 +1,34 @@
|
|||
package io.heckel.ntfy.up
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import io.heckel.ntfy.R
|
||||
import io.heckel.ntfy.util.topicUrlUp
|
||||
|
||||
fun sendMessage(context: Context, app: String, token: String, message: String) {
|
||||
val broadcastIntent = Intent()
|
||||
broadcastIntent.`package` = app
|
||||
broadcastIntent.action = ACTION_MESSAGE
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, token)
|
||||
broadcastIntent.putExtra(EXTRA_MESSAGE, message)
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun sendEndpoint(context: Context, app: String, token: String) {
|
||||
val appBaseUrl = context.getString(R.string.app_base_url)
|
||||
val broadcastIntent = Intent()
|
||||
broadcastIntent.`package` = app
|
||||
broadcastIntent.action = ACTION_NEW_ENDPOINT
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, token)
|
||||
broadcastIntent.putExtra(EXTRA_ENDPOINT, topicUrlUp(appBaseUrl, token))
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
||||
fun sendUnregistered(context: Context, app: String, token: String) {
|
||||
val broadcastIntent = Intent()
|
||||
broadcastIntent.`package` = app
|
||||
broadcastIntent.action = ACTION_UNREGISTERED
|
||||
broadcastIntent.putExtra(EXTRA_TOKEN, token)
|
||||
context.sendBroadcast(broadcastIntent)
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import java.text.DateFormat
|
|||
import java.util.*
|
||||
|
||||
fun topicUrl(baseUrl: String, topic: String) = "${baseUrl}/${topic}"
|
||||
fun topicUrlUp(baseUrl: String, topic: String) = "${baseUrl}/${topic}?up=1" // UnifiedPush
|
||||
fun topicUrlJson(baseUrl: String, topic: String, since: String) = "${topicUrl(baseUrl, topic)}/json?since=$since"
|
||||
fun topicUrlJsonPoll(baseUrl: String, topic: String) = "${topicUrl(baseUrl, topic)}/json?poll=1"
|
||||
fun topicShortUrl(baseUrl: String, topic: String) =
|
||||
|
|
Loading…
Reference in a new issue