added session time stamp and online/offline state

This commit is contained in:
oxidiert
2025-09-26 12:28:11 +02:00
parent bf33501b69
commit cfcb689ffc
7 changed files with 255 additions and 182 deletions

View File

@ -1,6 +1,10 @@
package com.dano.test1
import android.content.res.Configuration
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Bundle
import android.view.View
import android.widget.EditText
@ -19,15 +23,16 @@ class MainActivity : AppCompatActivity() {
private var progress: ProgressBar? = null
// LIVE: Network-Callback (wird in onResume registriert, in onPause deregistriert)
private var netCb: ConnectivityManager.NetworkCallback? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Zeige sofort Login-Dialog; erst NACH erfolgreichem Login + Download initialisieren wir den Opening Screen
// Login-Dialog -> Login -> Auto-Download -> OpeningScreen
showLoginThenDownload()
}
private fun showLoginThenDownload() {
// UI mit Username/Passwort
val container = LinearLayout(this).apply {
orientation = LinearLayout.VERTICAL
setPadding(dp(20), dp(8), dp(20), 0)
@ -42,8 +47,7 @@ class MainActivity : AppCompatActivity() {
inputType = android.text.InputType.TYPE_CLASS_TEXT or
android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
}
container.addView(etUser)
container.addView(etPass)
container.addView(etUser); container.addView(etPass)
val dialog = AlertDialog.Builder(this)
.setTitle("Login erforderlich")
@ -58,14 +62,12 @@ class MainActivity : AppCompatActivity() {
return@setPositiveButton
}
showBusy(true)
// Login -> Token -> Auto-Download -> OpeningScreen init
LoginManager.loginUserWithCredentials(
context = this,
username = user,
password = pass,
onSuccess = { token ->
// optional speichern
TokenStore.save(this, user, token)
// Token & Login-Timestamp werden in TokenStore gespeichert (siehe LoginManager/TokenStore).
DatabaseDownloader.downloadAndReplaceDatabase(
context = this,
token = token
@ -74,22 +76,20 @@ class MainActivity : AppCompatActivity() {
if (!ok) {
Toast.makeText(this, "Download fehlgeschlagen", Toast.LENGTH_LONG).show()
}
// Jetzt erst die Start-UI hochziehen
openingScreenHandler = HandlerOpeningScreen(this)
openingScreenHandler.init()
// Ersten Status sofort anzeigen
openingScreenHandler.refreshHeaderStatusLive()
}
},
onError = { msg ->
showBusy(false)
Toast.makeText(this, msg, Toast.LENGTH_LONG).show()
// erneut anbieten
showLoginThenDownload()
}
)
}
.setNegativeButton("Beenden") { _, _ ->
finishAffinity()
}
.setNegativeButton("Beenden") { _, _ -> finishAffinity() }
.create()
dialog.show()
@ -100,14 +100,7 @@ class MainActivity : AppCompatActivity() {
if (progress == null) {
progress = ProgressBar(this).apply {
isIndeterminate = true
// simpler Vollbild-Overlay
val content = window?.decorView as? android.view.ViewGroup
content?.addView(this, android.view.ViewGroup.LayoutParams(
android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
android.view.ViewGroup.LayoutParams.WRAP_CONTENT
))
this.x = (resources.displayMetrics.widthPixels / 2f) - width / 2f
this.y = (resources.displayMetrics.heightPixels / 2f) - height / 2f
(window?.decorView as? android.view.ViewGroup)?.addView(this)
}
}
progress?.visibility = View.VISIBLE
@ -118,7 +111,62 @@ class MainActivity : AppCompatActivity() {
private fun dp(v: Int): Int = (v * resources.displayMetrics.density).toInt()
// Wichtig: Keine Neu-Initialisierung bei Rotation
// --- LIVE NETZSTATUS ---
override fun onResume() {
super.onResume()
registerNetworkCallback()
// Falls die Startseite schon steht: Status jetzt gleich ziehen
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
openingScreenHandler.refreshHeaderStatusLive()
}
}
override fun onPause() {
super.onPause()
unregisterNetworkCallback()
}
private fun registerNetworkCallback() {
if (netCb != null) return // schon aktiv
val cm = getSystemService(ConnectivityManager::class.java)
val req = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
netCb = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
runOnUiThread {
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
openingScreenHandler.refreshHeaderStatusLive()
}
}
}
override fun onLost(network: Network) {
runOnUiThread {
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
openingScreenHandler.refreshHeaderStatusLive()
}
}
}
// Optional: auch auf „nicht validiert“ reagieren
override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
runOnUiThread {
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
openingScreenHandler.refreshHeaderStatusLive()
}
}
}
}
cm.registerNetworkCallback(req, netCb!!)
}
private fun unregisterNetworkCallback() {
val cb = netCb ?: return
val cm = getSystemService(ConnectivityManager::class.java)
cm.unregisterNetworkCallback(cb)
netCb = null
}
// --- /LIVE NETZSTATUS ---
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
}