+ // Reset the logcat plain text string.
+ logcatPlainTextStringBuilder = StringBuilder()
+
+ // Create a logcat HTML string builder.
+ val logcatHtmlStringBuilder = StringBuilder()
+
+ // Populate the initial HTML.
+ logcatHtmlStringBuilder.append("<html>")
+ logcatHtmlStringBuilder.append("<head>")
+ logcatHtmlStringBuilder.append("<style>")
+
+ // Set the word break so that lines never exceed the width of the screen.
+ logcatHtmlStringBuilder.append("body { word-break: break-word; }")
+
+ // Set the colors.
+ logcatHtmlStringBuilder.append("@media (prefers-color-scheme: dark) { body { color: #C1C1C1; /* Gray 350 */ background-color: #303030; /* Gray 860 */ } }")
+ logcatHtmlStringBuilder.append("span.header { color: #0D47A1; /* Blue 900 */ } @media (prefers-color-scheme: dark) { span.header { color: #8AB4F8; /* Violet 500 */ } }")
+ logcatHtmlStringBuilder.append("strong.crash { color: #B71C1C; /* Red 900. */ } @media (prefers-color-scheme: dark) { strong.crash { color: #E24B4C; /* Red Night. */ } }")
+ logcatHtmlStringBuilder.append("span.crash { color: #EF5350; /* Red 400. */ } @media (prefers-color-scheme: dark) { span.crash { color: #EF9A9A; /* Red Night. */ } }")
+
+ // Close the style tag.
+ logcatHtmlStringBuilder.append("</style>")
+
+ // Respect dark mode.
+ logcatHtmlStringBuilder.append("<meta name=\"color-scheme\" content=\"light dark\">")
+
+ // Start the HTML body.
+ logcatHtmlStringBuilder.append("</head>")
+ logcatHtmlStringBuilder.append("<body>")
+
+ // Create a logcat line string.
+ var logcatLineString: String?
+
+ while (logcatBufferedReader.readLine().also { logcatLineString = it } != null) {
+ // Populate the logcat plain text string builder.
+ logcatPlainTextStringBuilder.append(logcatLineString)
+
+ // Add a line break.
+ logcatPlainTextStringBuilder.append("\n")
+
+ // Trim the string, which is necessary for correct detection of lines that start with `at`.
+ logcatLineString = logcatLineString!!.trim()
+
+ // Apply syntax highlighting to the logcat.
+ if (logcatLineString!!.contains("crash") || logcatLineString!!.contains("Exception") ) { // Colorize crashes.
+ logcatHtmlStringBuilder.append("<strong class=\"crash\">")
+ logcatHtmlStringBuilder.append(logcatLineString)
+ logcatHtmlStringBuilder.append("</strong>")
+ } else if (logcatLineString!!.startsWith("at") || logcatLineString!!.startsWith("Process:") || logcatLineString!!.contains("FATAL")) { // Colorize lines relating to crashes.
+ logcatHtmlStringBuilder.append("<span class=\"crash\">")
+ logcatHtmlStringBuilder.append(logcatLineString)
+ logcatHtmlStringBuilder.append("</span>")
+ } else if (logcatLineString!!.startsWith("-")) { // Colorize the headers.
+ logcatHtmlStringBuilder.append("<span class=\"header\">")
+ logcatHtmlStringBuilder.append(logcatLineString)
+ logcatHtmlStringBuilder.append("</span>")
+ } else if (logcatLineString!!.startsWith("[ ")) { // Colorize the time stamps.
+ logcatHtmlStringBuilder.append("<span style=color:gray>")
+ logcatHtmlStringBuilder.append(logcatLineString)
+ logcatHtmlStringBuilder.append("</span>")
+ } else { // Display the standard lines.
+ logcatHtmlStringBuilder.append(logcatLineString)
+ }
+
+ // Add a line break.
+ logcatHtmlStringBuilder.append("<br>")
+ }
+
+ // Close the HTML.
+ logcatHtmlStringBuilder.append("</body>")
+ logcatHtmlStringBuilder.append("</html>")
+
+ // Encode the logcat HTML.
+ val base64EncodedLogcatHtml: String = Base64.encodeToString(logcatHtmlStringBuilder.toString().toByteArray(Charsets.UTF_8), Base64.NO_PADDING)
+
+ // Load the encoded logcat.
+ logcatWebView.loadData(base64EncodedLogcatHtml, "text/html", "base64")