forked from geode-sdk/android-launcher
filter by crash buffer option
This commit is contained in:
4 files changed
+83
-25
No files matched your search
@@ -24,6 +24,7 @@ import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.material.icons.filled.Share
|
||||
import androidx.compose.material3.Divider
|
||||
@@ -219,27 +220,25 @@ fun ApplicationLogsScreen(
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = {
|
||||
if (!logLines.isEmpty()) {
|
||||
coroutineScope.launch {
|
||||
val data = logViewModel.getLogData()
|
||||
coroutineScope.launch {
|
||||
val data = logViewModel.getLogData()
|
||||
|
||||
val sendIntent = Intent(Intent.ACTION_SEND).apply {
|
||||
putExtra(Intent.EXTRA_TEXT, data)
|
||||
type = "text/plain"
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
|
||||
context.startActivity(shareIntent)
|
||||
val sendIntent = Intent(Intent.ACTION_SEND).apply {
|
||||
putExtra(Intent.EXTRA_TEXT, data)
|
||||
type = "text/plain"
|
||||
}
|
||||
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
|
||||
context.startActivity(shareIntent)
|
||||
}
|
||||
}) {
|
||||
}, enabled = !logLines.isEmpty()) {
|
||||
Icon(
|
||||
Icons.Filled.Share,
|
||||
contentDescription = stringResource(R.string.application_logs_share)
|
||||
)
|
||||
}
|
||||
IconButton(onClick = { showMoreOptions = !showMoreOptions }) {
|
||||
IconButton(onClick = { showMoreOptions = !showMoreOptions },) {
|
||||
Icon(
|
||||
Icons.Filled.MoreVert,
|
||||
contentDescription = stringResource(R.string.application_logs_more)
|
||||
@@ -253,32 +252,54 @@ fun ApplicationLogsScreen(
|
||||
DropdownMenuItem(
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painterResource(R.drawable.icon_save),
|
||||
contentDescription = stringResource(R.string.application_logs_export)
|
||||
painterResource(R.drawable.icon_filter_list),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.application_logs_export))
|
||||
}, onClick = {
|
||||
if (!logLines.isEmpty()) {
|
||||
saveLauncher.launch(context.getString(R.string.application_logs_default_filename))
|
||||
trailingIcon = {
|
||||
if (logViewModel.filterCrashes) {
|
||||
Icon(
|
||||
Icons.Filled.Check,
|
||||
contentDescription = stringResource(R.string.application_logs_crash_only_enabled_alt)
|
||||
)
|
||||
}
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.application_logs_crash_only))
|
||||
}, onClick = {
|
||||
logViewModel.toggleCrashBuffer()
|
||||
showMoreOptions = false
|
||||
}
|
||||
)
|
||||
|
||||
DropdownMenuItem(
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painterResource(R.drawable.icon_save),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.application_logs_export))
|
||||
},
|
||||
onClick = {
|
||||
saveLauncher.launch(context.getString(R.string.application_logs_default_filename))
|
||||
showMoreOptions = false
|
||||
},
|
||||
enabled = !logLines.isEmpty()
|
||||
)
|
||||
|
||||
DropdownMenuItem(
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painterResource(R.drawable.icon_delete),
|
||||
contentDescription = stringResource(R.string.application_logs_delete)
|
||||
contentDescription = null
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(stringResource(R.string.application_logs_delete))
|
||||
}, onClick = {
|
||||
logViewModel.clearLogs()
|
||||
onBackPressedDispatcher?.onBackPressed()
|
||||
showMoreOptions = false
|
||||
}
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -29,11 +30,26 @@ class LogViewModel: ViewModel() {
|
||||
private var _isLoading = MutableStateFlow(false)
|
||||
var isLoading = _isLoading.asStateFlow()
|
||||
|
||||
var logJob: Job? = null
|
||||
|
||||
var filterCrashes = false
|
||||
private set
|
||||
|
||||
fun toggleCrashBuffer() {
|
||||
filterCrashes = !filterCrashes
|
||||
|
||||
_lineState.clear()
|
||||
loadLogs()
|
||||
}
|
||||
|
||||
private suspend fun logOutput(): List<LogLine> {
|
||||
val logLines = LinkedList<LogLine>()
|
||||
|
||||
val logCommand = if (filterCrashes) "logcat -b crash -B -d"
|
||||
else "logcat -B -d"
|
||||
|
||||
// -B = binary format, -d = dump logs
|
||||
val logSource = Runtime.getRuntime().exec("logcat -B -d")
|
||||
val logSource = Runtime.getRuntime().exec(logCommand)
|
||||
.inputStream.source().buffer()
|
||||
|
||||
try {
|
||||
@@ -61,6 +77,8 @@ class LogViewModel: ViewModel() {
|
||||
}
|
||||
|
||||
fun clearLogs() {
|
||||
logJob?.cancel()
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// -c = clear
|
||||
Runtime.getRuntime().exec("logcat -c")
|
||||
@@ -74,13 +92,20 @@ class LogViewModel: ViewModel() {
|
||||
return _lineState.joinToString("\n") { it.asSimpleString }
|
||||
}
|
||||
|
||||
init {
|
||||
private fun loadLogs() {
|
||||
_isLoading.value = true
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
logJob?.cancel()
|
||||
logJob = viewModelScope.launch(Dispatchers.IO) {
|
||||
val lines = logOutput()
|
||||
_lineState.addAll(lines)
|
||||
_isLoading.value = false
|
||||
|
||||
logJob = null
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
loadLogs()
|
||||
}
|
||||
}
|
||||
@@ -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="M400,720L400,640L560,640L560,720L400,720ZM240,520L240,440L720,440L720,520L240,520ZM120,320L120,240L840,240L840,320L120,320Z"/>
|
||||
</vector>
|
||||
@@ -94,4 +94,6 @@
|
||||
<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>
|
||||
<string name="application_logs_crash_only">Show Crash Buffer</string>
|
||||
<string name="application_logs_crash_only_enabled_alt">Enabled</string>
|
||||
</resources>
|
||||
Reference in new issue
Block a user