Added Settings item to copy the latest logs in case of crash.

This commit is contained in:
Antoine POPINEAU 2020-06-10 23:59:09 +02:00
parent 54f911793a
commit a4b2907c07
No known key found for this signature in database
GPG Key ID: A78AC64694F84063
7 changed files with 70 additions and 8 deletions

View File

@ -2,13 +2,14 @@ package com.github.apognu.otter
import android.app.Application
import androidx.appcompat.app.AppCompatDelegate
import com.github.apognu.otter.utils.Command
import com.github.apognu.otter.utils.Event
import com.github.apognu.otter.utils.Request
import com.github.apognu.otter.utils.*
import com.preference.PowerPreference
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import java.text.SimpleDateFormat
import java.time.format.DateTimeFormatter
import java.util.*
class Otter : Application() {
companion object {
@ -17,6 +18,8 @@ class Otter : Application() {
fun get(): Otter = instance
}
var defaultExceptionHandler: Thread.UncaughtExceptionHandler? = null
val eventBus: BroadcastChannel<Event> = BroadcastChannel(10)
val commandBus: Channel<Command> = Channel(10)
val requestBus: BroadcastChannel<Request> = BroadcastChannel(10)
@ -25,6 +28,10 @@ class Otter : Application() {
override fun onCreate() {
super.onCreate()
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler(CrashReportHandler())
instance = this
when (PowerPreference.getDefaultFile().getString("night_mode")) {
@ -33,4 +40,27 @@ class Otter : Application() {
else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
}
}
inner class CrashReportHandler : Thread.UncaughtExceptionHandler {
override fun uncaughtException(t: Thread, e: Throwable) {
val now = Date(Date().time - (5 * 60 * 1000))
val formatter = SimpleDateFormat("MM-dd kk:mm:ss.000", Locale.US)
Runtime.getRuntime().exec(listOf("logcat", "-d", "-T", formatter.format(now)).toTypedArray()).also {
it.inputStream.bufferedReader().also { reader ->
val builder = StringBuilder()
while (true) {
builder.appendln(reader.readLine() ?: break)
}
builder.appendln(e.toString())
Cache.set(this@Otter, "crashdump", builder.toString().toByteArray())
}
}
defaultExceptionHandler?.uncaughtException(t, e)
}
}
}

View File

@ -79,6 +79,7 @@ class MainActivity : AppCompatActivity() {
now_playing_toggle.setOnClickListener {
CommandBus.send(Command.ToggleState)
throw Exception("coucou")
}
now_playing_next.setOnClickListener {

View File

@ -1,8 +1,8 @@
package com.github.apognu.otter.activities
import android.content.Intent
import android.content.SharedPreferences
import android.content.*
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
@ -12,9 +12,7 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SeekBarPreference
import com.github.apognu.otter.BuildConfig
import com.github.apognu.otter.R
import com.github.apognu.otter.utils.AppContext
import com.github.apognu.otter.utils.Command
import com.github.apognu.otter.utils.CommandBus
import com.github.apognu.otter.utils.*
import com.preference.PowerPreference
class SettingsActivity : AppCompatActivity() {
@ -62,6 +60,18 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
}
}
"crash" -> {
activity?.let { activity ->
(activity.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager)?.also { clip ->
Cache.get(activity, "crashdump")?.readLines()?.joinToString("\n").also {
clip.setPrimaryClip(ClipData.newPlainText("Otter logs", it))
Toast.makeText(activity, activity.getString(R.string.settings_crash_report_copied), Toast.LENGTH_SHORT).show()
}
}
}
}
"logout" -> {
context?.let { context ->
AlertDialog.Builder(context)

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,8h-2.81c-0.45,-0.78 -1.07,-1.45 -1.82,-1.96L17,4.41 15.59,3l-2.17,2.17C12.96,5.06 12.49,5 12,5c-0.49,0 -0.96,0.06 -1.41,0.17L8.41,3 7,4.41l1.62,1.63C7.88,6.55 7.26,7.22 6.81,8L4,8v2h2.09c-0.05,0.33 -0.09,0.66 -0.09,1v1L4,12v2h2v1c0,0.34 0.04,0.67 0.09,1L4,16v2h2.81c1.04,1.79 2.97,3 5.19,3s4.15,-1.21 5.19,-3L20,18v-2h-2.09c0.05,-0.33 0.09,-0.66 0.09,-1v-1h2v-2h-2v-1c0,-0.34 -0.04,-0.67 -0.09,-1L20,10L20,8zM14,16h-4v-2h4v2zM14,12h-4v-2h4v2z"/>
</vector>

View File

@ -41,6 +41,9 @@
<string name="settings_version_title">Version</string>
<string name="settings_information_license_title">Licence</string>
<string name="settings_information_license_description">Licence MIT</string>
<string name="settings_crash_report_title">Copier les journaux de crash</string>
<string name="settings_crash_report_description">Seuls les journaux d`Otter des 5 dernières minutes jusqu\'au crash seront collectés</string>
<string name="settings_crash_report_copied">Les journaux d\'événements ont été copiés dans votre presse-papier</string>
<string name="settings_logout">Déconnexion</string>
<string name="artists">Artistes</string>
<string name="albums">Albums</string>

View File

@ -48,6 +48,9 @@
<string name="settings_version_title">Version</string>
<string name="settings_information_license_title">License</string>
<string name="settings_information_license_description">MIT license</string>
<string name="settings_crash_report_title">Copy crash logs</string>
<string name="settings_crash_report_description">Only Otter\'s logs from the last 5 minutes up until the crash will be collected</string>
<string name="settings_crash_report_copied">Last crash report was copied to your clipboard</string>
<string name="settings_logout">Sign out</string>
<string name="artists">Artists</string>

View File

@ -40,6 +40,12 @@
android:summary="@string/settings_experiments_description"
android:title="@string/settings_experiments" />
<Preference
android:icon="@drawable/bug"
android:key="crash"
android:summary="@string/settings_crash_report_description"
android:title="@string/settings_crash_report_title" />
<Preference
android:icon="@drawable/logout"
android:key="logout"