removed error: Toast.makeText(activity, "Fehlende View: $name", Toast.LENGTH_LONG).show()
This commit is contained in:
@ -17,7 +17,6 @@ import org.json.JSONArray
|
||||
import java.io.File
|
||||
import java.nio.charset.Charset
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
import org.apache.poi.ss.usermodel.Row
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook
|
||||
|
||||
@ -89,7 +88,7 @@ class DatabaseButtonHandler(
|
||||
uiScope.launch {
|
||||
try {
|
||||
progress.visibility = View.VISIBLE
|
||||
val savedUri = exportHeadersForAllClients() // => speichert NUR in Downloads
|
||||
val savedUri = exportHeadersForAllClients() // -> speichert NUR in Downloads
|
||||
progress.visibility = View.GONE
|
||||
|
||||
if (savedUri != null) {
|
||||
@ -101,10 +100,6 @@ class DatabaseButtonHandler(
|
||||
} else {
|
||||
Toast.makeText(activity, "Export fehlgeschlagen.", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
} catch (e: SecurityException) {
|
||||
progress.visibility = View.GONE
|
||||
Log.e(tag, "Berechtigungsfehler beim Schreiben nach Downloads: ${e.message}", e)
|
||||
Toast.makeText(activity, "Fehlende Speicherberechtigung (ältere Android-Version).", Toast.LENGTH_LONG).show()
|
||||
} catch (e: Exception) {
|
||||
progress.visibility = View.GONE
|
||||
Log.e(tag, "Download Header Fehler: ${e.message}", e)
|
||||
@ -114,13 +109,11 @@ class DatabaseButtonHandler(
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine Excel-Datei (ClientHeaders.xlsx) und speichert sie AUSSCHLIESSLICH
|
||||
* im öffentlichen Geräte-Ordner „Downloads“.
|
||||
*
|
||||
* Hinweis zu alten Geräten (Android 9 und älter):
|
||||
* - Füge ggf. in der AndroidManifest.xml hinzu:
|
||||
* <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
* und frage die Laufzeitberechtigung ab, falls dein targetSdk das erfordert.
|
||||
* Erzeugt eine Excel-Datei (ClientHeaders.xlsx) mit:
|
||||
* - Zeile 1: Spalten-IDs (header_order.json / header_order.xlsx)
|
||||
* - Zeile 2: ENGLISCHE Fragen/Beschriftungen zu jeder ID (rein EN, keine IDs mehr)
|
||||
* - Ab Zeile 3: pro Client die Werte ("Done"/"Not Done"/Antwort oder "None")
|
||||
* - Speichert AUSSCHLIESSLICH in den öffentlichen Geräte-Ordner "Downloads"
|
||||
*/
|
||||
private suspend fun exportHeadersForAllClients(): Uri? {
|
||||
val orderedIds = loadOrderedIds()
|
||||
@ -168,7 +161,7 @@ class DatabaseButtonHandler(
|
||||
id in questionnaireIdSet -> if (statusMap[id] == true) "Done" else "Not Done"
|
||||
else -> answerMap[id]?.takeIf { it.isNotBlank() } ?: "None"
|
||||
}
|
||||
val out = localizeForExportEn(id, raw) // Export immer EN (Done/Not Done/None bleiben)
|
||||
val out = localizeForExportEn(id, raw) // Export immer EN
|
||||
row.createCell(c++).setCellValue(out)
|
||||
}
|
||||
}
|
||||
@ -179,38 +172,39 @@ class DatabaseButtonHandler(
|
||||
}
|
||||
wb.close()
|
||||
|
||||
// NUR Downloads speichern
|
||||
val uri = saveToDownloads(
|
||||
// -> nur in Downloads speichern (Q+ via MediaStore, sonst Public Downloads)
|
||||
return saveToDownloads(
|
||||
filename = "ClientHeaders.xlsx",
|
||||
mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
bytes = bytes
|
||||
)
|
||||
|
||||
return uri
|
||||
}
|
||||
|
||||
// Speichert Bytes nach „Downloads“ (Android 10+ via MediaStore, sonst klassisch).
|
||||
/** Speichert Bytes nach "Downloads". */
|
||||
private fun saveToDownloads(filename: String, mimeType: String, bytes: ByteArray): Uri? {
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
// Android 10+ (Scoped Storage)
|
||||
val resolver = activity.contentResolver
|
||||
val values = ContentValues().apply {
|
||||
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
|
||||
put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
|
||||
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
|
||||
// optional: put(MediaStore.MediaColumns.IS_PENDING, 1)
|
||||
}
|
||||
val collection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
|
||||
val uri = resolver.insert(collection, values)
|
||||
if (uri != null) {
|
||||
resolver.openOutputStream(uri)?.use { it.write(bytes) } ?: return null
|
||||
// optional: values.clear(); values.put(MediaStore.MediaColumns.IS_PENDING, 0); resolver.update(uri, values, null, null)
|
||||
uri
|
||||
} else null
|
||||
} else {
|
||||
// Android 9 (API 28) und älter: öffentliches Downloads-Verzeichnis
|
||||
// Android 9 und älter – public Downloads (WRITE_EXTERNAL_STORAGE kann nötig sein)
|
||||
val downloadsDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
if (!downloadsDir.exists()) downloadsDir.mkdirs()
|
||||
val outFile = File(downloadsDir, filename)
|
||||
outFile.writeBytes(bytes)
|
||||
// Im System sichtbar machen
|
||||
// im System sichtbar machen
|
||||
MediaScannerConnection.scanFile(
|
||||
activity,
|
||||
arrayOf(outFile.absolutePath),
|
||||
@ -261,7 +255,7 @@ class DatabaseButtonHandler(
|
||||
private fun openClientOverviewScreen(clientCode: String) {
|
||||
activity.setContentView(R.layout.client_overview_screen)
|
||||
|
||||
val title: TextView = requireView(R.id.titleQuestionnaireDetail, "titleQuestionnaireDetail")
|
||||
val title: TextView = requireView(R.id.titleClientOverview, "titleClientOverview")
|
||||
val tableQ: TableLayout = requireView(R.id.tableQuestionnaires, "tableQuestionnaires")
|
||||
val progress: ProgressBar = requireView(R.id.progressBarClient, "progressBarClient")
|
||||
val emptyView: TextView = requireView(R.id.emptyViewClient, "emptyViewClient")
|
||||
@ -534,10 +528,9 @@ class DatabaseButtonHandler(
|
||||
|
||||
private fun localizeEnglishNoBrackets(key: String): String? {
|
||||
val t = try { LanguageManager.getText("ENGLISH", key) } catch (_: Exception) { null }
|
||||
if (t == null) return null
|
||||
val m = Regex("^\\[(.*)]$").matchEntire(t.trim())
|
||||
val m = Regex("^\\[(.*)]$").matchEntire(t?.trim() ?: "")
|
||||
val stripped = m?.groupValues?.get(1) ?: t
|
||||
if (stripped.isBlank() || stripped.equals(key, ignoreCase = true)) return null
|
||||
if (stripped == null || stripped.isBlank() || stripped.equals(key, ignoreCase = true)) return null
|
||||
return stripped
|
||||
}
|
||||
|
||||
@ -593,7 +586,7 @@ class DatabaseButtonHandler(
|
||||
val row = TableRow(activity).apply {
|
||||
isClickable = true
|
||||
isFocusable = true
|
||||
setBackgroundResource(android.R.drawable.list_selector_background)
|
||||
setBackgroundColor(android.graphics.Color.TRANSPARENT)
|
||||
setOnClickListener { onClick() }
|
||||
}
|
||||
cells.forEachIndexed { index, text ->
|
||||
|
||||
Reference in New Issue
Block a user