diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b075b1d..7b5fa4f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -20,6 +20,17 @@
+
+
+
+
diff --git a/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt b/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt
index 339c019..8f31fde 100644
--- a/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt
+++ b/app/src/main/java/cash/z/ecc/android/feedback/FeedbackFile.kt
@@ -5,12 +5,15 @@ import okio.Okio
import java.io.File
import java.text.SimpleDateFormat
-class FeedbackFile(fileName: String = "feedback.log") :
+class FeedbackFile(fileName: String = "user_log.txt") :
FeedbackCoordinator.FeedbackObserver {
- val file = File(ZcashWalletApp.instance.noBackupFilesDir, fileName)
+ val file = File("${ZcashWalletApp.instance.filesDir}/logs", fileName)
private val format = SimpleDateFormat("MM-dd HH:mm:ss.SSS")
+ init {
+ if (!file.parentFile.exists()) file.parentFile.mkdirs()
+ }
override fun onMetric(metric: Feedback.Metric) {
appendToFile(metric.toString())
diff --git a/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt b/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt
index 529005f..e59fa5b 100644
--- a/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt
+++ b/app/src/main/java/cash/z/ecc/android/ui/profile/ProfileFragment.kt
@@ -1,23 +1,34 @@
package cash.z.ecc.android.ui.profile
+import android.content.Context
import android.content.Intent
+import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
+import androidx.core.content.FileProvider.getUriForFile
import cash.z.ecc.android.BuildConfig
import cash.z.ecc.android.R
+import cash.z.ecc.android.ZcashWalletApp
import cash.z.ecc.android.databinding.FragmentProfileBinding
import cash.z.ecc.android.di.viewmodel.viewModel
import cash.z.ecc.android.ext.onClick
import cash.z.ecc.android.ext.onClickNavBack
import cash.z.ecc.android.ext.onClickNavTo
import cash.z.ecc.android.feedback.FeedbackFile
+import cash.z.ecc.android.feedback.Report
+import cash.z.ecc.android.feedback.Report.Tap.*
import cash.z.ecc.android.ui.base.BaseFragment
import cash.z.wallet.sdk.ext.toAbbreviatedAddress
+import cash.z.wallet.sdk.ext.twig
import kotlinx.coroutines.launch
import okio.Okio
+import java.io.File
+import java.io.IOException
+
class ProfileFragment : BaseFragment() {
+ override val screen = Report.Screen.PROFILE
private val viewModel: ProfileViewModel by viewModel()
@@ -26,13 +37,20 @@ class ProfileFragment : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- binding.hitAreaClose.onClickNavBack()
- binding.buttonBackup.onClickNavTo(R.id.action_nav_profile_to_nav_backup)
+ binding.hitAreaClose.onClickNavBack() { tapped(PROFILE_CLOSE) }
+ binding.buttonBackup.onClickNavTo(R.id.action_nav_profile_to_nav_backup) { tapped(PROFILE_BACKUP) }
binding.textVersion.text = BuildConfig.VERSION_NAME
onClick(binding.buttonLogs) {
+ tapped(PROFILE_VIEW_USER_LOGS)
onViewLogs()
}
+ binding.buttonLogs.setOnLongClickListener {
+ tapped(PROFILE_VIEW_DEV_LOGS)
+ onViewDevLogs()
+ true
+ }
onClick(binding.buttonFeedback) {
+ tapped(PROFILE_SEND_FEEDBACK)
onSendFeedback()
}
}
@@ -45,31 +63,63 @@ class ProfileFragment : BaseFragment() {
}
private fun onViewLogs() {
- loadLogFileAsText().let { logText ->
- if (logText == null) {
- mainActivity?.showSnackbar("Log file not found!")
- } else {
- val sendIntent: Intent = Intent().apply {
- action = Intent.ACTION_SEND
- putExtra(Intent.EXTRA_TEXT, logText)
- type = "text/plain"
- }
+ shareFile(userLogFile())
+ }
- val shareIntent = Intent.createChooser(sendIntent, "Share Log File")
- startActivity(shareIntent)
+ private fun onViewDevLogs() {
+ shareFile(writeLogcat())
+ }
+
+ private fun shareFiles(vararg files: File?) {
+ val uris = arrayListOf().apply {
+ files.filterNotNull().mapNotNull {
+ getUriForFile(ZcashWalletApp.instance, "${BuildConfig.APPLICATION_ID}.fileprovider", it)
+ }.forEach {
+ add(it)
}
}
+ val intent = Intent(Intent.ACTION_SEND_MULTIPLE).apply {
+ putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
+ type = "text/*"
+ }
+ startActivity(Intent.createChooser(intent, "Share Log Files"))
+ }
+
+ fun shareFile(file: File?) {
+ file ?: return
+ val uri = getUriForFile(ZcashWalletApp.instance, "${BuildConfig.APPLICATION_ID}.fileprovider", file)
+ val intent = Intent(Intent.ACTION_SEND).apply {
+ putExtra(Intent.EXTRA_STREAM, uri)
+ type = "text/plain"
+ }
+ startActivity(Intent.createChooser(intent, "Share Log File"))
}
private fun onSendFeedback() {
mainActivity?.showSnackbar("Feedback feature coming soon!")
}
+ private fun userLogFile(): File? {
+ return mainActivity?.feedbackCoordinator?.findObserver()?.file
+ }
+
private fun loadLogFileAsText(): String? {
- val feedbackFile: FeedbackFile =
- mainActivity?.feedbackCoordinator?.findObserver() ?: return null
- Okio.buffer(Okio.source(feedbackFile.file)).use {
+ val feedbackFile: File = userLogFile() ?: return null
+ Okio.buffer(Okio.source(feedbackFile)).use {
return it.readUtf8()
}
}
+
+ private fun writeLogcat(): File? {
+ try {
+ val outputFile = File("${ZcashWalletApp.instance.filesDir}/logs", "developer_log.txt")
+ val cmd = arrayOf("/bin/sh", "-c", "logcat -v time -d | grep \"@TWIG\" > ${outputFile.absolutePath}")
+ Runtime.getRuntime().exec(cmd)
+ return outputFile
+ } catch (e: IOException) {
+ e.printStackTrace()
+ twig("Failed to create log")
+ }
+ return null
+ }
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_profile.xml b/app/src/main/res/layout/fragment_profile.xml
index 863d2fb..d49117a 100644
--- a/app/src/main/res/layout/fragment_profile.xml
+++ b/app/src/main/res/layout/fragment_profile.xml
@@ -161,7 +161,7 @@
android:layout_marginTop="16dp"
style="@style/TextAppearance.AppCompat.Body1"
android:textSize="16sp"
- android:text="See Application Log"
+ android:text="See Application Logs"
android:textColor="@color/selector_button_text_light_dimmed"
app:layout_constraintTop_toBottomOf="@id/button_backup"
app:layout_constraintEnd_toEndOf="parent"
diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 0000000..c66b0a5
--- /dev/null
+++ b/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file