瀏覽代碼

feat: Allow exporting logs as txt

Peter Cai 1 年之前
父節點
當前提交
e48a919335

+ 31 - 0
app-common/src/main/java/im/angry/openeuicc/ui/LogsActivity.kt

@@ -1,9 +1,13 @@
 package im.angry.openeuicc.ui
 
+import android.icu.text.SimpleDateFormat
 import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
 import android.view.View
 import android.widget.ScrollView
 import android.widget.TextView
+import androidx.activity.result.contract.ActivityResultContracts
 import androidx.appcompat.app.AppCompatActivity
 import androidx.lifecycle.lifecycleScope
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
@@ -12,12 +16,24 @@ import im.angry.openeuicc.util.*
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
+import java.io.FileOutputStream
+import java.util.Date
 
 class LogsActivity : AppCompatActivity() {
     private lateinit var swipeRefresh: SwipeRefreshLayout
     private lateinit var scrollView: ScrollView
     private lateinit var logText: TextView
 
+    private val saveLogs =
+        registerForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { uri ->
+            if (uri == null) return@registerForActivityResult
+            contentResolver.openFileDescriptor(uri, "w")?.use {
+                FileOutputStream(it.fileDescriptor).use { os ->
+                    os.write(logText.text.toString().encodeToByteArray())
+                }
+            }
+        }
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_logs)
@@ -42,6 +58,21 @@ class LogsActivity : AppCompatActivity() {
         }
     }
 
+    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+        menuInflater.inflate(R.menu.activity_logs, menu)
+        return true
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
+        R.id.save -> {
+            saveLogs.launch(getString(R.string.logs_filename_template,
+                SimpleDateFormat.getDateTimeInstance().format(Date())
+            ))
+            true
+        }
+        else -> super.onOptionsItemSelected(item)
+    }
+
     private suspend fun reload() = withContext(Dispatchers.Main) {
         swipeRefresh.isRefreshing = true
 

+ 5 - 0
app-common/src/main/res/drawable/ic_save_as_black.xml

@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="?attr/colorControlNormal"
+    android:viewportHeight="24" android:viewportWidth="24"
+    android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="@android:color/white" android:pathData="M21,12.4V7l-4,-4H5C3.89,3 3,3.9 3,5v14c0,1.1 0.89,2 2,2h7.4L21,12.4zM15,15c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3s1.34,-3 3,-3S15,13.34 15,15zM6,6h9v4H6V6zM19.99,16.25l1.77,1.77L16.77,23H15v-1.77L19.99,16.25zM23.25,16.51l-0.85,0.85l-1.77,-1.77l0.85,-0.85c0.2,-0.2 0.51,-0.2 0.71,0l1.06,1.06C23.45,16 23.45,16.32 23.25,16.51z"/>
+</vector>

+ 9 - 0
app-common/src/main/res/menu/activity_logs.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <item
+        android:id="@+id/save"
+        android:icon="@drawable/ic_save_as_black"
+        android:title="@string/logs_save"
+        app:showAsAction="always" />
+</menu>

+ 3 - 0
app-common/src/main/res/values/strings.xml

@@ -48,6 +48,9 @@
     <string name="profile_notification_process">Process</string>
     <string name="profile_notification_delete">Delete</string>
 
+    <string name="logs_save">Save</string>
+    <string name="logs_filename_template">Logs at %s</string>
+
     <string name="pref_settings">Settings</string>
     <string name="pref_notifications">Notifications</string>
     <string name="pref_notifications_desc">eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.</string>