Попытка понять жизненный цикл активности Android [закрыто]Android

Форум для тех, кто программирует под Android
Anonymous
Попытка понять жизненный цикл активности Android [закрыто]

Сообщение Anonymous »

Я пишу простое приложение для Android с датчиком давления, которое использует Android 13+. Приложение ощущает давление и отслеживает его в текстовом файле.
Невозможно понять, использует ли оно Java awt для управления своими внутренними зависимостями Kotlin. Я знаю, что этот вопрос кажется общим, и он требует более подробной информации.
На данный момент Google Chatgpt смог дать некоторые ответы, но они кажутся немного повторяющимися. кажется, что он понимает контекст и работает с повторяющейся переменной ловушки-отладки (подход переменной TRAP), где LLM повторного использования кода заменяются или переходят к подходам ИЗВЕСТНЫЙ-ОТВЕТ

в многоуровневых стеках.
Например, JAR-файлы с обратной разработкой, похоже, предоставляют 3 или 4 ответа на вопросы сортировки, сравнения или поиска. Однако, хотя они чрезвычайно полезны, реальные интерфейсы функциональность-функция редко раскрываются. Например: можно было бы опубликовать фактическую функцию графика активности Android или интерфейсов awt, который обеспечивает анализ вопроса.
некоторое понимание этого было бы полезно, не обращаясь слишком много к книгам.
Следующее является основным действием:
package com.example.noisecounter

import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.MotionEvent
import android.widget.Button
import android.widget.ProgressBar
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.io.File
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {

private val counters = mutableMapOf()
private val totalCounters = mutableMapOf()
private lateinit var weeklyFile: File
private lateinit var totalFile: File
private val TAG = "NoiseCounter"
private var groupMode = false
private val groupBuffer = mutableListOf()
val buttonPressure = mutableMapOf()
private var isGroupOn = false // track GRP ON/OFF state
private var bltState = 0 // 0 = not_present, 1 = present

private val handler = Handler(Looper.getMainLooper())

private val saveRunnable = object : Runnable {
override fun run() {
saveCounters()
saveTotal()
handler.postDelayed(this, 5000) // 5-second save interval
}
}

private val keys = listOf(
"L1","L2","L3","L4","L5","L6","L7","L8","L9","L10","L11","L12",
"R1","R2","R3","R4","R5","R6","R7","R8","R9","R10","R11","R12",
"P1","P2","P3","P4","P5","P6",
"O1","O2","O3","O4",
"LN1","RM1","LM1","RN1","LH1","RH1","LH2","RH2","LH3","RH3","LE1","RE1",
"LTH9","LTH10","LTH11",
"RTH9","RTH10","RTH11"
)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val baseDir = File(getExternalFilesDir(null), "NoiseCounter")
if (!baseDir.exists()) baseDir.mkdirs()

totalFile = File(baseDir, "total.txt")

val calendar = Calendar.getInstance()
val week = calendar.get(Calendar.WEEK_OF_YEAR)
val year = calendar.get(Calendar.YEAR)
weeklyFile = File(baseDir, "weekly_${year}_W${week}.txt")

keys.forEach { key ->
counters[key] = 0
totalCounters[key] = 0
}

loadCounters(weeklyFile, counters)
loadCounters(totalFile, totalCounters)

val buttonMap = mutableMapOf()
keys.forEach { key ->
val id = resources.getIdentifier("button$key", "id", packageName)
val btn = findViewById(id)
btn?.let {
buttonMap[key] = it

// -------------------------
// BUTTON PRESS & HOLD LOGIC
// -------------------------
it.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
// record start time
buttonPressure[key] = 0
v.tag = System.currentTimeMillis()
v.alpha = 0.6f
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
// compute duration
val startTime = v.tag as? Long ?: System.currentTimeMillis()
val durationMs = System.currentTimeMillis() - startTime

// map duration to pressure (0..1000)
val maxHoldMs = 3000L // 3 sec = max pressure
var pressure = ((durationMs.toFloat() / maxHoldMs) * 1000).toInt()
if (pressure > 1000) pressure = 1000
if (pressure < 1) pressure = 1
buttonPressure[key] = pressure

// reset alpha for UX
v.alpha = 1f

onButtonPress(key)

// reset pressure after press
buttonPressure[key] = 0
}
}
true
}
}
}

// -------------------------
// PRESSURE PROGRESSBAR
// -------------------------
val progressPressure = findViewById(R.id.progressPressure)
val textPressureValue = findViewById(R.id.textPressureValue)

// Update visual feedback
handler.post(object : Runnable {
override fun run() {
val currentPressure = buttonPressure.values.maxOrNull() ?: 0
progressPressure.progress = currentPressure
textPressureValue.text = currentPressure.toString()

// change color green -> red
val green = Color.GREEN
val red = Color.RED
val ratio = currentPressure / 1000f
val blended = blendColors(green, red, ratio)
progressPressure.progressDrawable.setTint(blended)

handler.postDelayed(this, 50)
}
})

// -------------------------
// GRP BUTTON SETUP
// -------------------------
val grpBtn = findViewById(R.id.buttonGrpOn)
grpBtn.setOnClickListener {
isGroupOn = !isGroupOn
groupMode = isGroupOn // sync with groupMode

grpBtn.text = if (isGroupOn) "GRP ON" else "GRP OFF"
grpBtn.setBackgroundColor(if (isGroupOn) Color.GREEN else Color.LTGRAY)

val sdf = SimpleDateFormat("dd-MM-yyyy :: HH:mm:ss", Locale.getDefault())
val timeStr = sdf.format(Date())

if (!isGroupOn && groupBuffer.isNotEmpty()) {
// --- capture actual pressures and BLT states ---
val pressuresAndBlt = groupBuffer.map { key ->
val pressure = buttonPressure[key] ?: 416
val blt = bltState
"$key$pressureblt:$blt"
}

val groupStr = groupBuffer.joinToString(", ") // 3 spaces after comma
val pressuresStr = pressuresAndBlt.joinToString(", ") // 3 spaces after comma

logMessage(">> $timeStr :: GRP_ON [$groupStr] :: ($pressuresStr) GRP_OFF")
groupBuffer.clear()
} else if (isGroupOn) {
logMessage(">> $timeStr :: GRP_ON started")
groupBuffer.clear()
}
}

// -------------------------
// BLT BUTTON SETUP
// -------------------------
val bltBtn = findViewById(R.id.buttonBlt)
bltBtn.setOnClickListener {
bltState = if (bltState == 0) 1 else 0
bltBtn.text = "BLT: $bltState"
bltBtn.setBackgroundColor(if (bltState == 1) Color.GREEN else Color.LTGRAY)
}

handler.post(saveRunnable)
}

override fun onDestroy() {
super.onDestroy()
handler.removeCallbacks(saveRunnable)
}

private fun onButtonPress(key: String) {
counters[key] = (counters[key] ?: 0) + 1
totalCounters[key] = (totalCounters[key] ?: 0) + 1

val sdf = SimpleDateFormat("dd-MM-yyyy :: HH:mm:ss", Locale.getDefault())
val timeStr = sdf.format(Date())

val currentPressure = buttonPressure[key] ?: 0

if (groupMode) {
groupBuffer.add(key)
} else {
// Individual button press: log pressure + BLT
logMessage(">> $timeStr :: $key :: ($currentPressure blt:$bltState)")
}
}

private fun blendColors(color1: Int, color2: Int, ratio: Float): Int {
val inverseR = 1f - ratio
val r = Color.red(color1) * inverseR + Color.red(color2) * ratio
val g = Color.green(color1) * inverseR + Color.green(color2) * ratio
val b = Color.blue(color1) * inverseR + Color.blue(color2) * ratio
return Color.rgb(r.toInt(), g.toInt(), b.toInt())
}

// -------------------------
// REST OF EXISTING CODE
// -------------------------
private fun saveCounters() {
try {
val table = keysToTable(counters)

val existingText = if (weeklyFile.exists()) weeklyFile.readText() else ""
val separator = "===============seperator================"
val logSection = if (existingText.contains(separator)) {
existingText.substringAfter(separator)
} else {
""
}

weeklyFile.writeText(table + "\n" + separator + "\n" + logSection)

} catch (e: Exception) {
Log.e(TAG, "Error saving weekly counters", e)
}
}

private fun saveTotal() {
try {
totalFile.writeText(keysToTable(totalCounters))
} catch (e: Exception) {
Log.e(TAG, "Error saving total counters", e)
}
}

private fun logMessage(msg: String) {
try {
val sdf = SimpleDateFormat("dd-MM-yyyy :: HH:mm:ss", Locale.getDefault())
val timeStr = sdf.format(Date())
appendToWeeklyLog(">> $timeStr :: $msg")
} catch (e: Exception) {
Log.e(TAG, "Error logging message", e)
}
}

private fun appendToWeeklyLog(line: String) {
try {
if (!weeklyFile.exists()) {
weeklyFile.writeText("===============seperator================\n")
}

val text = weeklyFile.readText()
val separator = "===============seperator================"
val newText = if (text.contains(separator)) {
val parts = text.split(separator)
val before = parts[0].trimEnd() // remove trailing spaces/newlines
val after = parts.getOrNull(1)?.trimStart()?.trimEnd() ?: ""
"$before$separator\n$after\n$line"
} else {
text.trimEnd() + "\n$separator\n$line"
}

weeklyFile.writeText(newText)

} catch (e: Exception) {
Log.e(TAG, "Error writing to weekly file", e)
}
}

private fun generateLogSeparator(): String {
return "\n===============seperator================\n"
}

private fun keysToTable(map: Map): String {
val sb = StringBuilder()

for (i in 1..12) {
sb.append(String.format("L%d : %-5d || R%d : %-5d\n",
i, map["L$i"] ?: 0, i, map["R$i"] ?: 0))
}

sb.append("\n")

sb.append(String.format("P1 : %-5d || P2 : %-5d\n", map["P1"] ?: 0, map["P2"] ?: 0))
sb.append(String.format("P3 : %-5d || P4 : %-5d\n", map["P3"] ?: 0, map["P4"] ?: 0))
sb.append(String.format("P5 : %-5d || P6 : %-5d\n", map["P5"] ?: 0, map["P6"] ?: 0))

sb.append("\n")

sb.append(String.format("O1 : %-5d || O2 : %-5d\n", map["O1"] ?: 0, map["O2"] ?: 0))
sb.append(String.format("O3 : %-5d || O4 : %-5d\n", map["O3"] ?: 0, map["O4"] ?: 0))

sb.append("\n")

val extraKeys = listOf(
"LH1","RH1","LH2","RH2","LH3","RH3",
"LN1","LE1","RN1","RE1","LM1","RM1",
"LTH9","LTH10","LTH11",
"RTH9","RTH10","RTH11"
)

for (k in extraKeys) {
sb.append(String.format("%s : %-5d\n", k, map[k] ?: 0))
}

return sb.toString()
}

private fun loadCounters(file: File, targetMap: MutableMap) {
if (!file.exists()) return

try {
file.readLines().forEach { line ->

if (line.contains("||")) {
val sides = line.split("||")

val left = sides[0].trim().split(":")
val right = sides[1].trim().split(":")

if (left.size == 2) {
val key = left[0].trim()
val value = left[1].trim().toIntOrNull() ?: 0
targetMap[key] = value
}

if (right.size == 2) {
val key = right[0].trim()
val value = right[1].trim().toIntOrNull() ?: 0
targetMap[key] = value
}

} else if (line.contains(":")) {
val parts = line.split(":")
if (parts.size == 2) {
val key = parts[0].trim()
val value = parts[1].trim().toIntOrNull() ?: 0
targetMap[key] = value
}
}
}

} catch (e: Exception) {
Log.e(TAG, "Error loading file", e)
}
}

override fun onPause() {
super.onPause()
saveCounters()
saveTotal()
}
}

Вернуться в «Android»