Skip to content

Instantly share code, notes, and snippets.

@starry-shivam
Created May 27, 2024 08:03
Show Gist options
  • Save starry-shivam/e2d89e64910af68453dbbaab0f0888a1 to your computer and use it in GitHub Desktop.
Save starry-shivam/e2d89e64910af68453dbbaab0f0888a1 to your computer and use it in GitHub Desktop.
Get logcat for your app as a Kotlin flow
import android.os.Process
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.LinkedList
object LogcatFlow {
const val TAG = "LogcatFlow"
private val runtime = Runtime.getRuntime()
private const val MAX_LOGS = 100
fun logcatFlow(): Flow<List<String>> = callbackFlow {
val process = runtime.exec("logcat -v threadtime")
val logcatReader = BufferedReader(InputStreamReader(process.inputStream))
// Logs are filtered using PID of the app.
val pid = Process.myPid().toString()
val logList = LinkedList<String>()
val job = launch(Dispatchers.IO) {
try {
logcatReader.use { reader ->
reader.forEachLine { line ->
if (line.contains(pid)) {
if (logList.size >= MAX_LOGS) {
logList.poll()
}
logList.add(line)
trySend(ArrayList(logList))
}
}
}
} catch (e: Exception) {
Log.d(TAG, "logcatFlow: $e")
close(e)
} finally {
withContext(Dispatchers.IO) {
process.destroy()
}
}
}
awaitClose {
job.cancel()
process.destroy()
}
}.flowOn(Dispatchers.IO)
}
@starry-shivam
Copy link
Author

starry-shivam commented May 27, 2024

Example usage:

val logItems = LogcatFlow.logcatFlow().collectAsState(initial = listOf()).value
LazyColumn {
     items(logItems.size) { idx ->
           Text(
                text = logItems[idx],
                fontFamily = FontFamily.Monospace,
                fontSize = 20.sp,
                modifier = Modifier.padding(16.dp)
            )
            HorizontalDivider()
      }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment