Export notification logs through document picker
This commit is contained in:
@@ -3,6 +3,7 @@ package se.ajpanton.notificationlog
|
||||
import android.os.Bundle
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
@@ -15,11 +16,17 @@ import se.ajpanton.notificationlog.settings.LogField
|
||||
import se.ajpanton.notificationlog.settings.LogViewSettingsStore
|
||||
import se.ajpanton.notificationlog.settings.TimestampZone
|
||||
import se.ajpanton.notificationlog.capture.NotificationCaptureService
|
||||
import se.ajpanton.notificationlog.export.LogExporter
|
||||
import java.util.zip.ZipOutputStream
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
|
||||
class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
|
||||
private var binding: FragmentViewLogsBinding? = null
|
||||
private var pendingExport: ExportFormat? = null
|
||||
private val createDocument = registerForActivityResult(androidx.activity.result.contract.ActivityResultContracts.CreateDocument("application/octet-stream")) { uri ->
|
||||
uri?.let(::writeExport)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
@@ -27,6 +34,7 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
|
||||
binding!!.notificationAccess.setOnClickListener {
|
||||
startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS))
|
||||
}
|
||||
binding!!.exportLogs.setOnClickListener { chooseExportFormat() }
|
||||
binding!!.clearLogs.setOnClickListener {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle("Clear logs?")
|
||||
@@ -90,4 +98,32 @@ class ViewLogsFragment : Fragment(R.layout.fragment_view_logs) {
|
||||
ComponentName(requireContext(), NotificationCaptureService::class.java),
|
||||
)
|
||||
}
|
||||
|
||||
private fun chooseExportFormat() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setItems(arrayOf("CSV", "Formatted text", "HTML ZIP")) { _, which ->
|
||||
pendingExport = ExportFormat.entries[which]
|
||||
createDocument.launch("notification-log.${pendingExport!!.extension}")
|
||||
}.show()
|
||||
}
|
||||
|
||||
private fun writeExport(uri: Uri) {
|
||||
val format = pendingExport ?: return
|
||||
val context = requireContext().applicationContext
|
||||
Thread {
|
||||
val entries = EncryptedNotificationLogStore(context).readAll()
|
||||
val settings = LogViewSettingsStore(context).load()
|
||||
context.contentResolver.openOutputStream(uri)?.use { output -> when (format) {
|
||||
ExportFormat.CSV -> output.write(LogExporter.csv(entries, settings).encodeToByteArray())
|
||||
ExportFormat.FORMATTED -> output.write(LogExporter.formatted(entries, settings).encodeToByteArray())
|
||||
ExportFormat.HTML_ZIP -> ZipOutputStream(output).use { zip ->
|
||||
zip.putNextEntry(java.util.zip.ZipEntry("notification-log.html"))
|
||||
zip.write(LogExporter.html(entries, settings).encodeToByteArray())
|
||||
zip.closeEntry()
|
||||
}
|
||||
} }
|
||||
}.start()
|
||||
}
|
||||
|
||||
private enum class ExportFormat(val extension: String) { CSV("csv"), FORMATTED("txt"), HTML_ZIP("zip") }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="@dimen/page_padding">
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"><Button android:id="@+id/notification_access" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enable notification access"/><Button android:id="@+id/clear_logs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear logs" /></LinearLayout>
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"><Button android:id="@+id/notification_access" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Enable notification access"/><Button android:id="@+id/export_logs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Export logs"/><Button android:id="@+id/clear_logs" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Clear logs" /></LinearLayout>
|
||||
<ScrollView android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1">
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical">
|
||||
<TextView android:id="@+id/empty_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:text="No logs yet." />
|
||||
|
||||
Reference in New Issue
Block a user