add ability to export logs to file

This commit is contained in:
qimiko committed 2024-01-23 01:01:14 -07:00
1 parent cb16db3bf9
commit 1b079fa3ff
3 files changed
+82 -7

No files matched your search

@@ -9,8 +9,10 @@ import android.os.Bundle
import android.widget.Toast import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedDispatcher import androidx.activity.OnBackPressedDispatcher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@@ -22,8 +24,11 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Share import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Divider import androidx.compose.material3.Divider
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@@ -39,7 +44,10 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -174,6 +182,24 @@ fun ApplicationLogsScreen(
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
val listState = rememberLazyListState() val listState = rememberLazyListState()
var showMoreOptions by remember { mutableStateOf(false) }
val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { uri ->
if (uri != null) {
coroutineScope.launch {
val logs = logViewModel.getLogData()
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
outputStream.bufferedWriter().use { writer ->
writer.write(logs)
}
}
Toast.makeText(context, R.string.application_logs_export_completed, Toast.LENGTH_SHORT)
.show()
}
}
}
LaunchedEffect(logLines.size) { LaunchedEffect(logLines.size) {
listState.scrollToItem(logLines.size) listState.scrollToItem(logLines.size)
} }
@@ -213,13 +239,48 @@ fun ApplicationLogsScreen(
contentDescription = stringResource(R.string.application_logs_share) contentDescription = stringResource(R.string.application_logs_share)
) )
} }
IconButton(onClick = { IconButton(onClick = { showMoreOptions = !showMoreOptions }) {
logViewModel.clearLogs()
onBackPressedDispatcher?.onBackPressed()
}) {
Icon( Icon(
painterResource(R.drawable.icon_delete), Icons.Filled.MoreVert,
contentDescription = stringResource(R.string.application_logs_delete) contentDescription = stringResource(R.string.application_logs_more)
)
}
DropdownMenu(
expanded = showMoreOptions,
onDismissRequest = { showMoreOptions = false }
) {
DropdownMenuItem(
leadingIcon = {
Icon(
painterResource(R.drawable.icon_save),
contentDescription = stringResource(R.string.application_logs_export)
)
},
text = {
Text(stringResource(R.string.application_logs_export))
}, onClick = {
if (!logLines.isEmpty()) {
saveLauncher.launch(context.getString(R.string.application_logs_default_filename))
}
showMoreOptions = false
}
)
DropdownMenuItem(
leadingIcon = {
Icon(
painterResource(R.drawable.icon_delete),
contentDescription = stringResource(R.string.application_logs_delete)
)
},
text = {
Text(stringResource(R.string.application_logs_delete))
}, onClick = {
logViewModel.clearLogs()
onBackPressedDispatcher?.onBackPressed()
showMoreOptions = false
}
) )
} }
}, },
+10
View File
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M840,280L840,760Q840,793 816.5,816.5Q793,840 760,840L200,840Q167,840 143.5,816.5Q120,793 120,760L120,200Q120,167 143.5,143.5Q167,120 200,120L680,120L840,280ZM760,314L646,200L200,200Q200,200 200,200Q200,200 200,200L200,760Q200,760 200,760Q200,760 200,760L760,760Q760,760 760,760Q760,760 760,760L760,314ZM480,720Q530,720 565,685Q600,650 600,600Q600,550 565,515Q530,480 480,480Q430,480 395,515Q360,550 360,600Q360,650 395,685Q430,720 480,720ZM240,400L600,400L600,240L240,240L240,400ZM200,314L200,760Q200,760 200,760Q200,760 200,760L200,760Q200,760 200,760Q200,760 200,760L200,200Q200,200 200,200Q200,200 200,200L200,200L200,314Z"/>
</vector>
+5 -1
View File
@@ -87,7 +87,11 @@
<!-- ApplicationLogsActivity strings --> <!-- ApplicationLogsActivity strings -->
<string name="title_activity_application_logs">Application Logs</string> <string name="title_activity_application_logs">Application Logs</string>
<string name="application_logs_no_logs">No logs available.</string> <string name="application_logs_no_logs">No logs available.</string>
<string name="application_logs_delete">Clear</string> <string name="application_logs_delete">Clear All</string>
<string name="application_logs_share">Share</string> <string name="application_logs_share">Share</string>
<string name="application_log_copy_label">Log Message</string> <string name="application_log_copy_label">Log Message</string>
<string name="application_logs_more">More</string>
<string name="application_logs_export">Save To</string>
<string name="application_logs_export_completed">Log export complete.</string>
<string name="application_logs_default_filename" translatable="false">launcher_logcat.txt</string>
</resources> </resources>