Skip to content

Instantly share code, notes, and snippets.

@starry-shivam
Created May 27, 2024 08:03
Show Gist options
  • Select an option

  • Save starry-shivam/e2d89e64910af68453dbbaab0f0888a1 to your computer and use it in GitHub Desktop.

Select an option

Save starry-shivam/e2d89e64910af68453dbbaab0f0888a1 to your computer and use it in GitHub Desktop.

Revisions

  1. starry-shivam created this gist May 27, 2024.
    56 changes: 56 additions & 0 deletions LogcatFlow.kt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,56 @@
    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)
    }