diff --git a/app/src/main/java/com/example/medilightv2android/services/BleDebugLogger.kt b/app/src/main/java/com/example/medilightv2android/services/BleDebugLogger.kt index b9d4eae..0942beb 100644 --- a/app/src/main/java/com/example/medilightv2android/services/BleDebugLogger.kt +++ b/app/src/main/java/com/example/medilightv2android/services/BleDebugLogger.kt @@ -207,32 +207,47 @@ class BleDebugLogger private constructor(private val context: Context) { // ── File Export ── + private fun writeLogContent(writer: java.io.BufferedWriter) { + writer.write("=== VesiScan BLE Debug Log ===\n") + writer.write("Device: $deviceName\n") + writer.write("Session: ${dateFmt.format(Date(sessionStart))}\n") + writer.write("Duration: ${sessionDurationSec()}s\n") + writer.write("TX: $txCount RX: $rxCount Errors: $errorCount Timeouts: $packetTimeouts\n") + + if (rssiHistory.isNotEmpty()) { + writer.write("RSSI: avg=${rssiHistory.map { it.second }.average().toInt()} ") + writer.write("min=${rssiHistory.minOf { it.second }} max=${rssiHistory.maxOf { it.second }}\n") + } + + writer.write("=".repeat(60) + "\n\n") + + for (entry in entries) { + writer.write(entry.toLogLine() + "\n") + } + } + fun exportToFile(): File { val fileName = "ble_debug_${dateFmt.format(Date())}.log" val file = File(logDir, fileName) - - file.bufferedWriter().use { writer -> - writer.write("=== VesiScan BLE Debug Log ===\n") - writer.write("Device: $deviceName\n") - writer.write("Session: ${dateFmt.format(Date(sessionStart))}\n") - writer.write("Duration: ${sessionDurationSec()}s\n") - writer.write("TX: $txCount RX: $rxCount Errors: $errorCount Timeouts: $packetTimeouts\n") - - if (rssiHistory.isNotEmpty()) { - writer.write("RSSI: avg=${rssiHistory.map { it.second }.average().toInt()} ") - writer.write("min=${rssiHistory.minOf { it.second }} max=${rssiHistory.maxOf { it.second }}\n") - } - - writer.write("=".repeat(60) + "\n\n") - - for (entry in entries) { - writer.write(entry.toLogLine() + "\n") - } - } - + file.bufferedWriter().use { writeLogContent(it) } return file } + /** Downloads 폴더에 저장 (파일 탐색기에서 바로 접근 가능) */ + fun exportToDownloads(): File? { + return try { + val downloadsDir = android.os.Environment.getExternalStoragePublicDirectory( + android.os.Environment.DIRECTORY_DOWNLOADS + ) + val fileName = "VesiScan_BLE_${dateFmt.format(Date())}.log" + val file = File(downloadsDir, fileName) + file.bufferedWriter().use { writeLogContent(it) } + file + } catch (e: Exception) { + null + } + } + fun exportToJsonFile(): File { val fileName = "ble_debug_${dateFmt.format(Date())}.jsonl" val file = File(logDir, fileName) diff --git a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt index 38edc70..d4ac6a3 100644 --- a/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt +++ b/app/src/main/java/com/example/medilightv2android/ui/views/monitoring/PiezoMonitoringView.kt @@ -1115,11 +1115,16 @@ private fun BleDebugPanel(bleManager: BleManager) { Icon(Icons.Default.ContentCopy, "Copy", tint = Color.Gray, modifier = Modifier.size(16.dp)) } - // Export file button + // Export to Downloads IconButton( onClick = { - val file = logger.exportToFile() - android.widget.Toast.makeText(context, "Saved: ${file.name}", android.widget.Toast.LENGTH_SHORT).show() + val file = logger.exportToDownloads() + if (file != null) { + android.widget.Toast.makeText(context, "Downloads/${file.name} 저장 완료", android.widget.Toast.LENGTH_LONG).show() + } else { + logger.exportToFile() + android.widget.Toast.makeText(context, "내부 저장소에 저장됨", android.widget.Toast.LENGTH_SHORT).show() + } }, modifier = Modifier.size(32.dp) ) {