diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/LogsActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/LogsActivity.kt index ba15e37..1a7e50f 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/LogsActivity.kt +++ b/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 diff --git a/app-common/src/main/res/drawable/ic_save_as_black.xml b/app-common/src/main/res/drawable/ic_save_as_black.xml new file mode 100644 index 0000000..aaee678 --- /dev/null +++ b/app-common/src/main/res/drawable/ic_save_as_black.xml @@ -0,0 +1,5 @@ + + + diff --git a/app-common/src/main/res/menu/activity_logs.xml b/app-common/src/main/res/menu/activity_logs.xml new file mode 100644 index 0000000..4fa3aeb --- /dev/null +++ b/app-common/src/main/res/menu/activity_logs.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 9d8932a..040c910 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -48,6 +48,9 @@ Process Delete + Save + Logs at %s + Settings Notifications eSIM profile operations send notifications to the carrier. Fine-tune this behavior as needed here.