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" } }