Коммит de09e41b создал по автору Radch-enko's avatar Radch-enko
Просмотр файлов

Feature: integrate Firebase Messaging and add kiosk mode functionality

- Implemented `ServerMessagingService` for handling Firebase push notifications and integrated the `firebaseTopicsModule` for topic subscriptions.
- Added kiosk mode support in `AppActivity` with device admin and lock task mode setup.
- Updated `AndroidManifest.xml` with required service and permissions declarations.
- Enabled Firebase dependencies in Gradle (`firebase-messaging-ktx`, `google-services`) and added signing configurations for debug and release builds.
- Updated `App` setup to subscribe to Firebase topics dynamically.
владелец ccedbf13
...@@ -77,4 +77,5 @@ coverage/ ...@@ -77,4 +77,5 @@ coverage/
/backend/app/src/main/resources/google-credentials.json /backend/app/src/main/resources/google-credentials.json
/oldBackendExample /oldBackendExample
/scripts /scripts
/backend/app/src/main/resources/firebase-credentials.json /backend/app/src/main/resources/firebase-credentials.json
\ No newline at end of file /keystore/
...@@ -31,4 +31,5 @@ dependencies { ...@@ -31,4 +31,5 @@ dependencies {
// implementation("com.android.library:com.android.library.gradle.plugin:8.9.1") // implementation("com.android.library:com.android.library.gradle.plugin:8.9.1")
implementation("org.jetbrains.compose:org.jetbrains.compose.gradle.plugin:1.8.1") implementation("org.jetbrains.compose:org.jetbrains.compose.gradle.plugin:1.8.1")
implementation("com.arkivanov.parcelize.darwin:gradle-plugin:0.2.4") implementation("com.arkivanov.parcelize.darwin:gradle-plugin:0.2.4")
implementation("com.google.gms:google-services:4.4.3")
} }
\ No newline at end of file
...@@ -7,6 +7,7 @@ plugins { ...@@ -7,6 +7,7 @@ plugins {
id("com.android.application") id("com.android.application")
id("org.jetbrains.kotlin.plugin.serialization") version "2.1.21" id("org.jetbrains.kotlin.plugin.serialization") version "2.1.21"
alias(libs.plugins.buildkonfig) alias(libs.plugins.buildkonfig)
id("com.google.gms.google-services") version "4.4.3"
} }
kotlin { kotlin {
...@@ -54,6 +55,7 @@ kotlin { ...@@ -54,6 +55,7 @@ kotlin {
implementation(libs.androidx.activityCompose) implementation(libs.androidx.activityCompose)
implementation(libs.koin.android) implementation(libs.koin.android)
implementation("org.slf4j:slf4j-android:1.7.36") implementation("org.slf4j:slf4j-android:1.7.36")
implementation(libs.firebase.messaging.ktx)
} }
} }
} }
...@@ -66,7 +68,7 @@ android { ...@@ -66,7 +68,7 @@ android {
minSdk = libs.versions.android.minSdk.get().toInt() minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt() targetSdk = libs.versions.android.targetSdk.get().toInt()
applicationId = "band.effective.office.tablet.androidApp" applicationId = "band.effective.office.tablet"
versionCode = 1 versionCode = 1
versionName = "1.0.0" versionName = "1.0.0"
...@@ -80,6 +82,33 @@ android { ...@@ -80,6 +82,33 @@ android {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
} }
signingConfigs {
getByName("debug") {
keyAlias = "androiddebugkey"
keyPassword = "android"
storeFile = file("${rootDir}/keystore/debug.keystore")
storePassword = "android"
}
create("release") {
keyAlias = System.getenv()["OFFICE_ELEVATOR_RELEASE_ALIAS"]
keyPassword = System.getenv()["OFFICE_ELEVATOR_RELEASE_KEY_PASSWORD"]
storeFile = file("${rootDir}/keystore/main.keystore")
storePassword = System.getenv()["OFFICE_ELEVATOR_RELEASE_STORE_PASSWORD"]
}
}
buildTypes {
getByName("debug") {
signingConfig = signingConfigs.getByName("debug")
isDebuggable = true
}
getByName("release") {
signingConfig = signingConfigs.getByName("debug")
isDebuggable = false
isMinifyEnabled = false
}
}
} }
packaging { packaging {
......
...@@ -32,6 +32,13 @@ ...@@ -32,6 +32,13 @@
<action android:name="android.intent.action.PROFILE_PROVISIONING_COMPLETE" /> <action android:name="android.intent.action.PROFILE_PROVISIONING_COMPLETE" />
</intent-filter> </intent-filter>
</receiver> </receiver>
<service
android:name=".ServerMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application> </application>
</manifest> </manifest>
\ No newline at end of file
package band.effective.office.tablet package band.effective.office.tablet
import android.app.ActivityOptions
import android.app.admin.DevicePolicyManager
import android.content.Intent
import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresApi
import band.effective.office.tablet.root.RootComponent import band.effective.office.tablet.root.RootComponent
import com.arkivanov.decompose.defaultComponentContext import com.arkivanov.decompose.defaultComponentContext
class AppActivity : ComponentActivity() { class AppActivity : ComponentActivity() {
companion object{
var isRunKioskMode = false
}
@RequiresApi(Build.VERSION_CODES.P)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
runKioskMode()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
val root = RootComponent(componentContext = defaultComponentContext()) val root = RootComponent(componentContext = defaultComponentContext())
setContent { App(root) } setContent { App(root) }
} }
@RequiresApi(Build.VERSION_CODES.P)
private fun runKioskMode(){
val context = this
val dpm = context.getSystemService(DEVICE_POLICY_SERVICE)
as DevicePolicyManager
val adminName = AdminReceiver.getComponentName(context)
val KIOSK_PACKAGE = "band.effective.office.tablet"
val APP_PACKAGES = arrayOf(KIOSK_PACKAGE)
if (isRunKioskMode || !dpm.isDeviceOwnerApp(adminName.packageName)) return
val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN).apply {
putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminName)
putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"")
}
startActivityForResult(intent, 1)
dpm.setLockTaskPackages(adminName, APP_PACKAGES)
// Set an option to turn on lock task mode when starting the activity.
val options = ActivityOptions.makeBasic()
options.setLockTaskEnabled(true)
isRunKioskMode = true
// Start our kiosk app's main activity with our lock task mode option.
val packageManager = context.packageManager
val launchIntent = packageManager.getLaunchIntentForPackage(KIOSK_PACKAGE)
if (launchIntent != null) {
context.startActivity(launchIntent, options.toBundle())
}
}
} }
...@@ -3,7 +3,10 @@ package band.effective.office.tablet ...@@ -3,7 +3,10 @@ package band.effective.office.tablet
import android.app.Application import android.app.Application
import band.effective.office.tablet.core.domain.model.SettingsManager import band.effective.office.tablet.core.domain.model.SettingsManager
import band.effective.office.tablet.di.KoinInitializer import band.effective.office.tablet.di.KoinInitializer
import com.google.firebase.messaging.FirebaseMessaging
import com.russhwolf.settings.SharedPreferencesSettings import com.russhwolf.settings.SharedPreferencesSettings
import org.koin.android.ext.android.get
import org.koin.core.qualifier.named
class App : Application() { class App : Application() {
...@@ -19,5 +22,13 @@ class App : Application() { ...@@ -19,5 +22,13 @@ class App : Application() {
) )
) )
) )
subscribeOnFirebaseTopics()
}
private fun subscribeOnFirebaseTopics() {
val topicNameList: List<String> = get(qualifier = named("FireBaseTopics"))
topicNameList.forEach { topic ->
FirebaseMessaging.getInstance().subscribeToTopic(topic)
}
} }
} }
\ No newline at end of file
package band.effective.office.tablet
import android.util.Log
import band.effective.office.tablet.core.data.api.Collector
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class ServerMessagingService() :
FirebaseMessagingService(), KoinComponent {
private val collector: Collector<String> by inject()
override fun onMessageReceived(message: RemoteMessage) {
Log.i("ReceivedMessage", message.toString())
collector.emit(message.from?.substringAfter("topics/")?.replace("-test", "") ?: "")
}
}
\ No newline at end of file
package band.effective.office.tablet.di
import org.koin.core.qualifier.named
import org.koin.dsl.module
val firebaseTopicsModule = module {
single(named("FireBaseTopics")) { listOf("workspace", "user", "booking") }
}
\ No newline at end of file
...@@ -10,6 +10,7 @@ class KoinInitializer { ...@@ -10,6 +10,7 @@ class KoinInitializer {
startKoin { startKoin {
modules( modules(
appModule, appModule,
firebaseTopicsModule,
dataModule, dataModule,
domainModule, domainModule,
mainScreenModule, mainScreenModule,
......
...@@ -76,6 +76,7 @@ essenty-ios = "0.2.4" ...@@ -76,6 +76,7 @@ essenty-ios = "0.2.4"
## Settings ## Settings
settings = "1.3.0" settings = "1.3.0"
firebaseMessagingKtx = "24.1.2"
[libraries] [libraries]
# Common # Common
...@@ -188,6 +189,7 @@ essenty-darwin-runtime = { module = "com.arkivanov.parcelize.darwin:runtime", ve ...@@ -188,6 +189,7 @@ essenty-darwin-runtime = { module = "com.arkivanov.parcelize.darwin:runtime", ve
## Settings ## Settings
settings = { module = "com.russhwolf:multiplatform-settings", version.ref = "settings" } settings = { module = "com.russhwolf:multiplatform-settings", version.ref = "settings" }
firebase-messaging-ktx = { group = "com.google.firebase", name = "firebase-messaging-ktx", version.ref = "firebaseMessagingKtx" }
[plugins] [plugins]
# Common # Common
......
Поддерживает Markdown
0% или .
You are about to add 0 people to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Пожалуйста, зарегистрируйтесь или чтобы прокомментировать