229 lines
8.6 KiB
Kotlin
229 lines
8.6 KiB
Kotlin
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
|
|
import android.widget.LinearLayout
|
|
import android.widget.ProgressBar
|
|
import android.widget.Toast
|
|
import androidx.appcompat.app.AlertDialog
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import java.io.File
|
|
|
|
class MainActivity : AppCompatActivity() {
|
|
|
|
private lateinit var openingScreenHandler: HandlerOpeningScreen
|
|
|
|
var isInQuestionnaire: Boolean = false
|
|
var isFirstQuestionnairePage: Boolean = false
|
|
|
|
private var progress: ProgressBar? = null
|
|
|
|
// LIVE: Network-Callback (optional für Statusleiste)
|
|
private var netCb: ConnectivityManager.NetworkCallback? = null
|
|
|
|
// Wir kennen hier (vor dem OpeningScreen) noch keine Nutzerwahl → Deutsch als Startsprache.
|
|
private val bootLanguageId: String get() = "GERMAN"
|
|
private fun t(key: String): String = LanguageManager.getText(bootLanguageId, key)
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
|
|
// === Offline-Start ermöglichen ===
|
|
// Bedingung: gespeicherter User/Token UND lokale DB vorhanden -> direkt OpeningScreen
|
|
val hasCreds = !TokenStore.getUsername(this).isNullOrBlank() && !TokenStore.getToken(this).isNullOrBlank()
|
|
val hasDb = hasLocalDb()
|
|
if (hasCreds && hasDb) {
|
|
openingScreenHandler = HandlerOpeningScreen(this)
|
|
openingScreenHandler.init()
|
|
return
|
|
}
|
|
|
|
// Sonst: Login-Dialog -> Login -> DB (einmalig) laden -> OpeningScreen
|
|
showLoginThenDownload()
|
|
}
|
|
|
|
/** Prüft, ob die lokale DB-Datei vorhanden ist. */
|
|
private fun hasLocalDb(): Boolean {
|
|
val dbFile = getDatabasePath("questionnaire_database")
|
|
return dbFile != null && dbFile.exists() && dbFile.length() > 0
|
|
}
|
|
|
|
/** Zeigt den Login-Dialog an, führt Login aus und lädt danach einmalig die DB. */
|
|
private fun showLoginThenDownload() {
|
|
val container = LinearLayout(this).apply {
|
|
orientation = LinearLayout.VERTICAL
|
|
setPadding(dp(20), dp(8), dp(20), 0)
|
|
}
|
|
val etUser = EditText(this).apply {
|
|
hint = t("username_hint")
|
|
setSingleLine()
|
|
}
|
|
val etPass = EditText(this).apply {
|
|
hint = t("password_hint")
|
|
setSingleLine()
|
|
inputType = android.text.InputType.TYPE_CLASS_TEXT or
|
|
android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD
|
|
}
|
|
container.addView(etUser)
|
|
container.addView(etPass)
|
|
|
|
val dialog = AlertDialog.Builder(this)
|
|
.setTitle(t("login_required_title"))
|
|
.setView(container)
|
|
.setCancelable(false)
|
|
.setPositiveButton(t("login_btn")) { _, _ ->
|
|
val user = etUser.text.toString().trim()
|
|
val pass = etPass.text.toString()
|
|
if (user.isEmpty() || pass.isEmpty()) {
|
|
Toast.makeText(this, t("please_username_password"), Toast.LENGTH_SHORT).show()
|
|
showLoginThenDownload()
|
|
return@setPositiveButton
|
|
}
|
|
showBusy(true)
|
|
LoginManager.loginUserWithCredentials(
|
|
context = this,
|
|
username = user,
|
|
password = pass,
|
|
onSuccess = { token ->
|
|
// Nach erfolgreichem Login: einmalig komplette DB ziehen
|
|
DatabaseDownloader.downloadAndReplaceDatabase(
|
|
context = this,
|
|
token = token
|
|
) { ok ->
|
|
showBusy(false)
|
|
|
|
// Wenn Download fehlgeschlagen ist, aber evtl. schon eine DB lokal liegt,
|
|
// lassen wir den Nutzer trotzdem weiterarbeiten (Offline).
|
|
if (!ok && !hasLocalDb()) {
|
|
Toast.makeText(this, t("download_failed_no_local_db"), Toast.LENGTH_LONG).show()
|
|
// Zurück zum Login, damit man es erneut probieren kann
|
|
showLoginThenDownload()
|
|
return@downloadAndReplaceDatabase
|
|
}
|
|
|
|
if (!ok) {
|
|
Toast.makeText(this, t("download_failed_use_offline"), Toast.LENGTH_LONG).show()
|
|
}
|
|
|
|
// Opening-Screen starten
|
|
openingScreenHandler = HandlerOpeningScreen(this)
|
|
openingScreenHandler.init()
|
|
openingScreenHandler.refreshHeaderStatusLive()
|
|
}
|
|
},
|
|
onError = { msg ->
|
|
showBusy(false)
|
|
val txt = t("login_failed_with_reason").replace("{reason}", msg ?: "")
|
|
Toast.makeText(this, txt, Toast.LENGTH_LONG).show()
|
|
showLoginThenDownload()
|
|
}
|
|
)
|
|
}
|
|
.setNegativeButton(t("exit_btn")) { _, _ -> finishAffinity() }
|
|
.create()
|
|
|
|
dialog.show()
|
|
}
|
|
|
|
private fun showBusy(show: Boolean) {
|
|
if (show) {
|
|
if (progress == null) {
|
|
progress = ProgressBar(this).apply {
|
|
isIndeterminate = true
|
|
(window?.decorView as? android.view.ViewGroup)?.addView(this)
|
|
}
|
|
}
|
|
progress?.visibility = View.VISIBLE
|
|
} else {
|
|
progress?.visibility = View.GONE
|
|
}
|
|
}
|
|
|
|
private fun dp(v: Int): Int = (v * resources.displayMetrics.density).toInt()
|
|
|
|
// --- LIVE NETZSTATUS (optional, für deine Status-Leiste) ---
|
|
override fun onResume() {
|
|
super.onResume()
|
|
registerNetworkCallback()
|
|
if (::openingScreenHandler.isInitialized && !isInQuestionnaire) {
|
|
openingScreenHandler.refreshHeaderStatusLive()
|
|
}
|
|
}
|
|
|
|
override fun onPause() {
|
|
super.onPause()
|
|
unregisterNetworkCallback()
|
|
}
|
|
|
|
private fun registerNetworkCallback() {
|
|
if (netCb != null) return
|
|
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()
|
|
}
|
|
}
|
|
}
|
|
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)
|
|
}
|
|
|
|
fun startQuestionnaire(questionnaire: QuestionnaireBase<*>, languageID: String) {
|
|
isInQuestionnaire = true
|
|
isFirstQuestionnairePage = true
|
|
questionnaire.attach(this, languageID)
|
|
questionnaire.startQuestionnaire()
|
|
}
|
|
|
|
override fun onBackPressed() {
|
|
if (!::openingScreenHandler.isInitialized || !openingScreenHandler.onBackPressed()) {
|
|
super.onBackPressed()
|
|
}
|
|
}
|
|
|
|
fun finishQuestionnaire() {
|
|
isInQuestionnaire = false
|
|
isFirstQuestionnairePage = false
|
|
if (::openingScreenHandler.isInitialized) {
|
|
openingScreenHandler.init()
|
|
}
|
|
}
|
|
}
|