Single-instance app, talker info in notification
- MainActivity singleTask, SplashActivity singleTop: re-launching from launcher or notification never creates a second instance - Splash skips the 4s animation when the main screen is already open - Foreground notification shows 'Говорит: CALLSIGN' / 'Последний: CALLSIGN'; tapping it brings the app back to the front
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
<activity
|
||||
android:name=".SplashActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.SvxRemote">
|
||||
<intent-filter>
|
||||
@@ -39,6 +40,7 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="false"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden" />
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ class MainActivity : Activity(), SvxService.Listener {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
SplashActivity.mainAlive = true
|
||||
setContentView(R.layout.activity_main)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
checkForUpdates()
|
||||
@@ -174,6 +175,7 @@ class MainActivity : Activity(), SvxService.Listener {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
SplashActivity.mainAlive = false
|
||||
svc?.listener = null
|
||||
unbindService(svcConn)
|
||||
}
|
||||
|
||||
@@ -9,15 +9,23 @@ import android.view.animation.AccelerateDecelerateInterpolator
|
||||
/** Красивая заставка с плавным появлением логотипа. */
|
||||
class SplashActivity : Activity() {
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
var mainAlive = false
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (mainAlive) {
|
||||
openMain()
|
||||
return
|
||||
}
|
||||
setContentView(R.layout.activity_splash)
|
||||
|
||||
val title = findViewById<View>(R.id.splash_title)
|
||||
val subtitle = findViewById<View>(R.id.splash_subtitle)
|
||||
val line = findViewById<View>(R.id.splash_line)
|
||||
|
||||
val baseAlpha = title.alpha
|
||||
title.alpha = 0f
|
||||
subtitle.alpha = 0f
|
||||
line.alpha = 0f
|
||||
@@ -44,10 +52,19 @@ class SplashActivity : Activity() {
|
||||
.start()
|
||||
|
||||
window.decorView.postDelayed({
|
||||
openMain()
|
||||
}, 4000)
|
||||
}
|
||||
|
||||
private fun openMain() {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK or
|
||||
Intent.FLAG_ACTIVITY_CLEAR_TOP or
|
||||
Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
)
|
||||
startActivity(intent)
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
|
||||
finish()
|
||||
}, 4000)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package ru.ua1zbe.svxremote
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.Binder
|
||||
@@ -53,11 +54,22 @@ class SvxService : Service(), ReflectorClient.Callbacks {
|
||||
nm.createNotificationChannel(
|
||||
NotificationChannel("svx", "SVXRemote", NotificationManager.IMPORTANCE_LOW)
|
||||
)
|
||||
updateNotification(getString(R.string.notif_connected))
|
||||
}
|
||||
|
||||
private fun updateNotification(text: String) {
|
||||
val contentIntent = PendingIntent.getActivity(
|
||||
this, 0,
|
||||
Intent(this, MainActivity::class.java)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
val n = Notification.Builder(this, "svx")
|
||||
.setContentTitle("SVXRemote")
|
||||
.setContentText(getString(R.string.notif_connected))
|
||||
.setContentText(text)
|
||||
.setSmallIcon(android.R.drawable.ic_menu_call)
|
||||
.setOngoing(true)
|
||||
.setContentIntent(contentIntent)
|
||||
.build()
|
||||
startForeground(1, n)
|
||||
}
|
||||
@@ -86,7 +98,10 @@ class SvxService : Service(), ReflectorClient.Callbacks {
|
||||
|
||||
override fun onState(state: Int, detail: String?) {
|
||||
when (state) {
|
||||
ReflectorClient.STATE_READY -> engine.startDecoder()
|
||||
ReflectorClient.STATE_READY -> {
|
||||
updateNotification(getString(R.string.notif_connected))
|
||||
engine.startDecoder()
|
||||
}
|
||||
ReflectorClient.STATE_DISCONNECTED -> {
|
||||
engine.stopDecoder()
|
||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||
@@ -100,10 +115,12 @@ class SvxService : Service(), ReflectorClient.Callbacks {
|
||||
}
|
||||
|
||||
override fun onTalkerStart(tg: Long, callsign: String) {
|
||||
updateNotification(getString(R.string.notif_talking, callsign))
|
||||
listener?.onTalkerStart(tg, callsign)
|
||||
}
|
||||
|
||||
override fun onTalkerStop(tg: Long, callsign: String) {
|
||||
updateNotification(getString(R.string.notif_last_talker, callsign))
|
||||
listener?.onTalkerStop(tg, callsign)
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
<string name="status_auth_failed">Ошибка авторизации</string>
|
||||
<string name="status_error">Ошибка: %1$s</string>
|
||||
<string name="notif_connected">Соединение с рефлектором активно</string>
|
||||
<string name="notif_talking">Говорит: %1$s</string>
|
||||
<string name="notif_last_talker">Последний: %1$s</string>
|
||||
|
||||
<string name="btn_connect">Подключиться</string>
|
||||
<string name="btn_disconnect">Отключиться</string>
|
||||
|
||||
Reference in New Issue
Block a user