diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 46b3699..f045d33 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -53,6 +53,7 @@
+
diff --git a/app/src/main/java/sushi/hardcore/droidfs/LogcatActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/LogcatActivity.kt
new file mode 100644
index 0000000..3eac7e2
--- /dev/null
+++ b/app/src/main/java/sushi/hardcore/droidfs/LogcatActivity.kt
@@ -0,0 +1,88 @@
+package sushi.hardcore.droidfs
+
+import android.net.Uri
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
+import android.widget.Toast
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.lifecycle.lifecycleScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import sushi.hardcore.droidfs.databinding.ActivityLogcatBinding
+import java.io.BufferedReader
+import java.io.BufferedWriter
+import java.io.InputStreamReader
+import java.io.InterruptedIOException
+import java.io.OutputStreamWriter
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+
+class LogcatActivity: BaseActivity() {
+ private lateinit var binding: ActivityLogcatBinding
+ private var process: Process? = null
+ private val dateFormat by lazy {
+ SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.getDefault())
+ }
+ private val saveAs = registerForActivityResult(ActivityResultContracts.CreateDocument("text/*")) { uri ->
+ uri?.let {
+ saveTo(it)
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ binding = ActivityLogcatBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+ title = getString(R.string.logcat_title)
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ lifecycleScope.launch(Dispatchers.IO) {
+ try {
+ BufferedReader(InputStreamReader(Runtime.getRuntime().exec("logcat").also {
+ process = it
+ }.inputStream)).forEachLine {
+ binding.content.post {
+ binding.content.append("$it\n")
+ }
+ }
+ } catch (_: InterruptedIOException) {}
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ process?.destroy()
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.logcat, menu)
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ return when (item.itemId) {
+ android.R.id.home -> {
+ finish()
+ true
+ }
+ R.id.save -> {
+ saveAs.launch("DroidFS_${dateFormat.format(Date())}.log")
+ true
+ }
+ else -> super.onOptionsItemSelected(item)
+ }
+ }
+
+ private fun saveTo(uri: Uri) {
+ lifecycleScope.launch(Dispatchers.IO) {
+ BufferedWriter(OutputStreamWriter(contentResolver.openOutputStream(uri))).use {
+ it.write(binding.content.text.toString())
+ }
+ launch(Dispatchers.Main) {
+ Toast.makeText(this@LogcatActivity, R.string.logcat_saved, Toast.LENGTH_SHORT).show()
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/sushi/hardcore/droidfs/SettingsActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/SettingsActivity.kt
index 4cc633d..2e9bf8a 100644
--- a/app/src/main/java/sushi/hardcore/droidfs/SettingsActivity.kt
+++ b/app/src/main/java/sushi/hardcore/droidfs/SettingsActivity.kt
@@ -120,6 +120,10 @@ class SettingsActivity : BaseActivity() {
false
}
}
+ findPreference("logcat")?.setOnPreferenceClickListener { _ ->
+ startActivity(Intent(requireContext(), LogcatActivity::class.java))
+ true
+ }
}
}
diff --git a/app/src/main/res/drawable/icon_debug.xml b/app/src/main/res/drawable/icon_debug.xml
new file mode 100644
index 0000000..1cc8a97
--- /dev/null
+++ b/app/src/main/res/drawable/icon_debug.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_logcat.xml b/app/src/main/res/layout/activity_logcat.xml
new file mode 100644
index 0000000..c2174b8
--- /dev/null
+++ b/app/src/main/res/layout/activity_logcat.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/logcat.xml b/app/src/main/res/menu/logcat.xml
new file mode 100644
index 0000000..2ffc835
--- /dev/null
+++ b/app/src/main/res/menu/logcat.xml
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 57860b9..fd68b14 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -276,4 +276,7 @@
Your current kernel does not support memfd_create(). This feature requires a minimum kernel version of %s.
Export method
File export method. Used for sharing, external opening and accessing exposed files.
+ Debug
+ DroidFS Logcat
+ Logcat saved
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index a28bee5..01d46b2 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -93,6 +93,16 @@
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index 18e59f1..a8173a6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.2.1'
+ classpath 'com.android.tools.build:gradle:8.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}