Add RuStore Push integration (project_id placeholder)

This commit is contained in:
ua1zbe
2026-09-23 09:17:43 +03:00
parent db81f6a51e
commit d52382ca5b
8 changed files with 160 additions and 2 deletions

View File

@@ -55,4 +55,8 @@ kotlin {
compilerOptions {
jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)
}
}
dependencies {
implementation("ru.rustore.sdk:pushclient:7.4.0")
}

View File

@@ -1,10 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
@@ -12,6 +15,22 @@
android:supportsRtl="true"
android:theme="@style/Theme.APRS.Main">
<service
android:name=".PushMessagingService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="ru.rustore.sdk.pushclient.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_icon"
android:resource="@drawable/ic_launcher_foreground" />
<meta-data
android:name="ru.rustore.sdk.pushclient.default_notification_channel_id"
android:value="@string/push_channel_id" />
<activity
android:name=".SplashActivity"
android:exported="true"

View File

@@ -0,0 +1,60 @@
package ru.ua1zbe.aprsmap
import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.util.Log
import ru.rustore.sdk.pushclient.RuStorePushClient
class App : Application() {
override fun onCreate() {
super.onCreate()
createPushChannel()
initRuStorePush()
}
private fun createPushChannel() {
getSystemService(NotificationManager::class.java).createNotificationChannel(
NotificationChannel(
PushMessagingService.CHANNEL_ID,
getString(R.string.push_channel_name),
NotificationManager.IMPORTANCE_HIGH
)
)
}
private fun initRuStorePush() {
if (RUSTORE_PROJECT_ID.isBlank()) {
Log.w(TAG, "RuStore project_id not set yet, init skipped")
return
}
try {
RuStorePushClient.init(application = this, projectId = RUSTORE_PROJECT_ID)
RuStorePushClient.getToken()
.addOnSuccessListener { token ->
Log.i(TAG, "push token: $token")
saveToken(token)
RuStorePushClient.subscribeToTopic(PUSH_TOPIC)
.addOnSuccessListener { Log.i(TAG, "subscribed to $PUSH_TOPIC") }
.addOnFailureListener { e -> Log.w(TAG, "subscribe failed", e) }
}
.addOnFailureListener { e -> Log.w(TAG, "getToken failed", e) }
} catch (e: Exception) {
Log.w(TAG, "init failed", e)
}
}
private fun saveToken(token: String) {
getSharedPreferences(PREFS, MODE_PRIVATE)
.edit().putString("push_token", token).apply()
}
companion object {
private const val TAG = "RuStorePush"
private const val RUSTORE_PROJECT_ID = ""
private const val PUSH_TOPIC = "aprsmap"
const val PREFS = "aprsmap"
}
}

View File

@@ -1,9 +1,11 @@
package ru.ua1zbe.aprsmap
import android.annotation.SuppressLint
import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
@@ -104,10 +106,24 @@ class MainActivity : Activity() {
root.addView(progress)
setContentView(root)
requestNotificationPermission()
webView.loadUrl(getString(R.string.map_url))
checkForUpdates()
}
private fun requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) !=
PackageManager.PERMISSION_GRANTED
) {
requestPermissions(
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
REQ_NOTIFICATIONS
)
}
}
private fun checkForUpdates() {
Thread {
val version = try {
@@ -237,5 +253,6 @@ class MainActivity : Activity() {
companion object {
private const val TAG = "APRSmap"
private const val REQ_NOTIFICATIONS = 100
}
}

View File

@@ -0,0 +1,55 @@
package ru.ua1zbe.aprsmap
import android.app.Notification
import android.app.NotificationManager
import android.content.Context
import android.util.Log
import ru.rustore.sdk.pushclient.messaging.exception.RuStorePushClientException
import ru.rustore.sdk.pushclient.messaging.model.RemoteMessage
import ru.rustore.sdk.pushclient.messaging.service.RuStoreMessagingService
class PushMessagingService : RuStoreMessagingService() {
override fun onNewToken(token: String) {
Log.i(TAG, "onNewToken: $token")
getSharedPreferences(App.PREFS, Context.MODE_PRIVATE)
.edit().putString("push_token", token).apply()
}
override fun onMessageReceived(message: RemoteMessage) {
if (message.notification != null) {
Log.i(TAG, "push displayed by SDK: ${message.data}")
return
}
val title = message.data["title"] ?: getString(R.string.app_name)
val body = message.data["body"] ?: ""
if (title.isNotEmpty() || body.isNotEmpty()) {
showPush(title, body)
}
}
override fun onDeletedMessages() {
Log.i(TAG, "onDeletedMessages")
}
override fun onError(errors: List<RuStorePushClientException>) {
errors.forEach { Log.w(TAG, "error", it) }
}
private fun showPush(title: String, body: String) {
val nm = getSystemService(NotificationManager::class.java)
val n = Notification.Builder(this, CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setAutoCancel(true)
.build()
nm.notify(NOTIFICATION_ID, n)
}
companion object {
private const val TAG = "RuStorePush"
const val CHANNEL_ID = "aprs_push"
private const val NOTIFICATION_ID = 2
}
}

View File

@@ -2,6 +2,8 @@
<resources>
<string name="app_name">APRS RadioRubka</string>
<string name="map_url">https://aprs.radiorubka.org/?center=67.5096,32.8271&amp;zoom=8</string>
<string name="push_channel_id">aprs_push</string>
<string name="push_channel_name">Пуш-уведомления</string>
<string name="update_available_title">Доступно обновление</string>
<string name="update_available_msg">Версия %1$s уже вышла. Обновить приложение?</string>
<string name="update_btn">Обновить</string>

View File

@@ -6,4 +6,4 @@ org.gradle.parallel=false
org.gradle.caching=false
kotlin.compiler.execution.strategy=in-process
android.nonTransitiveRClass=true
android.useAndroidX=false
android.useAndroidX=true

View File

@@ -11,6 +11,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://nexus-external.rustore.ru/repository/maven-rustore-exposed/")
}
}