From 00f5b9431ea57af62d8112ad026af7c027476175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Sat, 22 Feb 2020 21:24:06 +0100 Subject: [PATCH] Add log viewer (#686) --- app/build.gradle | 3 +- .../wulkanowy/utils/CrashlyticsUtils.kt | 13 ++- app/src/main/AndroidManifest.xml | 14 ++- .../java/io/github/wulkanowy/WulkanowyApp.kt | 13 ++- .../repositories/logger/LoggerRepository.kt | 39 ++++++++ .../ui/modules/about/AboutFragment.kt | 5 + .../ui/modules/about/AboutPresenter.kt | 5 + .../wulkanowy/ui/modules/about/AboutView.kt | 2 + .../about/logviewer/LogViewerAdapter.kt | 22 +++++ .../about/logviewer/LogViewerFragment.kt | 98 +++++++++++++++++++ .../about/logviewer/LogViewerPresenter.kt | 54 ++++++++++ .../modules/about/logviewer/LogViewerView.kt | 13 +++ .../wulkanowy/ui/modules/main/MainModule.kt | 5 + .../io/github/wulkanowy/utils/LoggerUtils.kt | 12 +-- app/src/main/res/drawable/ic_refresh.xml | 5 + .../main/res/layout/fragment_logviewer.xml | 34 +++++++ .../main/res/menu/action_menu_logviewer.xml | 11 +++ app/src/main/res/values-pl/strings.xml | 5 + app/src/main/res/values-ru/strings.xml | 10 ++ app/src/main/res/values/strings.xml | 5 + app/src/main/res/xml/provider_paths.xml | 5 + .../wulkanowy/utils/CrashlyticsUtils.kt | 15 +-- 22 files changed, 361 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt create mode 100644 app/src/main/res/drawable/ic_refresh.xml create mode 100644 app/src/main/res/layout/fragment_logviewer.xml create mode 100644 app/src/main/res/menu/action_menu_logviewer.xml create mode 100644 app/src/main/res/xml/provider_paths.xml diff --git a/app/build.gradle b/app/build.gradle index dc3eed77..95522dd3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,7 @@ android { defaultConfig { applicationId "io.github.wulkanowy" testApplicationId "io.github.tests.wulkanowy" - minSdkVersion 16 + minSdkVersion 17 targetSdkVersion 29 versionCode 52 versionName "0.15.0" @@ -173,6 +173,7 @@ dependencies { implementation "com.jakewharton.threetenabp:threetenabp:1.2.2" implementation "com.jakewharton.timber:timber:4.7.1" implementation "at.favre.lib:slf4j-timber:1.0.1" + implementation "fr.bipi.treessence:treessence:0.3.0" implementation "com.mikepenz:aboutlibraries-core:7.1.0" implementation 'com.wdullaer:materialdatetimepicker:4.2.3' diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt index be4c0ebe..60dc6b56 100644 --- a/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt +++ b/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt @@ -5,13 +5,12 @@ package io.github.wulkanowy.utils import android.content.Context import timber.log.Timber -fun initCrashlytics(context: Context, appInfo: AppInfo) { - // do nothing +fun initCrashlytics(context: Context, appInfo: AppInfo) {} + +open class TimberTreeNoOp : Timber.Tree() { + override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {} } -class CrashlyticsTree : Timber.Tree() { +class CrashlyticsTree : TimberTreeNoOp() - override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { - // do nothing - } -} +class CrashlyticsExceptionTree : TimberTreeNoOp() diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c644c863..694c8053 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,8 +43,8 @@ android:name=".ui.modules.message.send.SendMessageActivity" android:configChanges="orientation|screenSize" android:label="@string/send_message_title" - android:windowSoftInputMode="adjustResize" - android:theme="@style/WulkanowyTheme.NoActionBar" /> + android:theme="@style/WulkanowyTheme.NoActionBar" + android:windowSoftInputMode="adjustResize" /> + + + + diff --git a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt index 90b3581c..96ec7cb8 100644 --- a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt +++ b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt @@ -1,6 +1,7 @@ package io.github.wulkanowy import android.content.Context +import android.util.Log.DEBUG import android.util.Log.INFO import android.util.Log.VERBOSE import androidx.multidex.MultiDex @@ -11,11 +12,13 @@ import dagger.android.AndroidInjector import dagger.android.support.DaggerApplication import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.utils.Log +import fr.bipi.tressence.file.FileLoggerTree import io.github.wulkanowy.di.DaggerAppComponent import io.github.wulkanowy.services.sync.SyncWorkerFactory import io.github.wulkanowy.ui.base.ThemeManager import io.github.wulkanowy.utils.ActivityLifecycleLogger import io.github.wulkanowy.utils.AppInfo +import io.github.wulkanowy.utils.CrashlyticsExceptionTree import io.github.wulkanowy.utils.CrashlyticsTree import io.github.wulkanowy.utils.DebugLogTree import io.github.wulkanowy.utils.initCrashlytics @@ -54,9 +57,17 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider { private fun initLogging() { if (appInfo.isDebug) { - Timber.plant(DebugLogTree()) FlexibleAdapter.enableLogs(Log.Level.DEBUG) + Timber.plant(DebugLogTree()) + Timber.plant(FileLoggerTree.Builder() + .withFileName("wulkanowy.%g.log") + .withDirName(applicationContext.filesDir.absolutePath) + .withFileLimit(10) + .withMinPriority(DEBUG) + .build() + ) } else { + Timber.plant(CrashlyticsExceptionTree()) Timber.plant(CrashlyticsTree()) } registerActivityLifecycleCallbacks(ActivityLifecycleLogger()) diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt new file mode 100644 index 00000000..be6ad2f4 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt @@ -0,0 +1,39 @@ +package io.github.wulkanowy.data.repositories.logger + +import android.content.Context +import io.reactivex.Single +import java.io.File +import java.io.FileNotFoundException +import javax.inject.Inject + +class LoggerRepository @Inject constructor(private val context: Context) { + + fun getLastLogLines(): Single> { + return getLastModified() + .map { it.readText() } + .map { it.split("\n") } + } + + fun getLogFiles(): Single> { + return Single.fromCallable { + File(context.filesDir.absolutePath).listFiles(File::isFile)?.filter { + it.name.endsWith(".log") + } + } + } + + private fun getLastModified(): Single { + return Single.fromCallable { + var lastModifiedTime = Long.MIN_VALUE + var chosenFile: File? = null + File(context.filesDir.absolutePath).listFiles(File::isFile)?.forEach { file -> + if (file.lastModified() > lastModifiedTime) { + lastModifiedTime = file.lastModified() + chosenFile = file + } + } + if (chosenFile == null) throw FileNotFoundException("Log file not found") + chosenFile + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt index d9430a47..d92c3cd6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt @@ -18,6 +18,7 @@ import io.github.wulkanowy.R import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.about.creator.CreatorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment +import io.github.wulkanowy.ui.modules.about.logviewer.LogViewerFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.utils.AppInfo @@ -110,6 +111,10 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView { } } + override fun openLogViewer() { + if (appInfo.isDebug) (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance()) + } + override fun openDiscordInvite() { context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt index 66293983..7e740b32 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutPresenter.kt @@ -27,6 +27,11 @@ class AboutPresenter @Inject constructor( if (item !is AboutItem) return view?.run { when (item.title) { + versionRes?.first -> { + Timber.i("Opening log viewer") + openLogViewer() + analytics.logEvent("about_open", "name" to "log_viewer") + } feedbackRes?.first -> { Timber.i("Opening email client") openEmailClient() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt index 228225ec..4bc0c3fe 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutView.kt @@ -25,6 +25,8 @@ interface AboutView : BaseView { fun updateData(header: AboutScrollableHeader, items: List) + fun openLogViewer() + fun openDiscordInvite() fun openEmailClient() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt new file mode 100644 index 00000000..45c304aa --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerAdapter.kt @@ -0,0 +1,22 @@ +package io.github.wulkanowy.ui.modules.about.logviewer + +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +class LogViewerAdapter : RecyclerView.Adapter() { + + var lines = emptyList() + + class ViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + return ViewHolder(TextView(parent.context)) + } + + override fun getItemCount() = lines.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.textView.text = lines[position] + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt new file mode 100644 index 00000000..0b7b05c7 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerFragment.kt @@ -0,0 +1,98 @@ +package io.github.wulkanowy.ui.modules.about.logviewer + +import android.content.Intent +import android.content.Intent.EXTRA_EMAIL +import android.content.Intent.EXTRA_STREAM +import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION +import android.net.Uri +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.LOLLIPOP +import android.os.Bundle +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.core.content.FileProvider +import androidx.recyclerview.widget.LinearLayoutManager +import io.github.wulkanowy.BuildConfig.APPLICATION_ID +import io.github.wulkanowy.R +import io.github.wulkanowy.ui.base.BaseFragment +import io.github.wulkanowy.ui.modules.main.MainView +import kotlinx.android.synthetic.main.fragment_logviewer.* +import java.io.File +import javax.inject.Inject + +class LogViewerFragment : BaseFragment(), LogViewerView, MainView.TitledView { + + @Inject + lateinit var presenter: LogViewerPresenter + + private val logAdapter = LogViewerAdapter() + + override val titleStringId: Int + get() = R.string.logviewer_title + + companion object { + fun newInstance() = LogViewerFragment() + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setHasOptionsMenu(true) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_logviewer, container, false) + } + + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + messageContainer = logViewerRecycler + presenter.onAttachView(this) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { + inflater.inflate(R.menu.action_menu_logviewer, menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return if (item.itemId == R.id.logViewerMenuShare) presenter.onShareLogsSelected() + else false + } + + override fun initView() { + with(logViewerRecycler) { + layoutManager = LinearLayoutManager(context) + adapter = logAdapter + } + + logViewRefreshButton.setOnClickListener { presenter.onRefreshClick() } + } + + override fun setLines(lines: List) { + logAdapter.lines = lines + logAdapter.notifyDataSetChanged() + logViewerRecycler.scrollToPosition(lines.size - 1) + } + + override fun shareLogs(files: List) { + val intent = Intent(Intent.ACTION_SEND_MULTIPLE).apply { + type = "text/plain" + putExtra(EXTRA_EMAIL, arrayOf("wulkanowyinc@gmail.com")) + addFlags(FLAG_GRANT_READ_URI_PERMISSION) + putParcelableArrayListExtra(EXTRA_STREAM, ArrayList(files.map { + if (SDK_INT < LOLLIPOP) Uri.fromFile(it) + else FileProvider.getUriForFile(requireContext(), "$APPLICATION_ID.fileprovider", it) + })) + } + + startActivity(Intent.createChooser(intent, getString(R.string.logviewer_share))) + } + + override fun onDestroyView() { + presenter.onDetachView() + super.onDestroyView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt new file mode 100644 index 00000000..4485cb3e --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt @@ -0,0 +1,54 @@ +package io.github.wulkanowy.ui.modules.about.logviewer + +import io.github.wulkanowy.data.repositories.logger.LoggerRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.SchedulersProvider +import timber.log.Timber +import javax.inject.Inject + +class LogViewerPresenter @Inject constructor( + schedulers: SchedulersProvider, + errorHandler: ErrorHandler, + studentRepository: StudentRepository, + private val loggerRepository: LoggerRepository +) : BasePresenter(errorHandler, studentRepository, schedulers) { + + override fun onAttachView(view: LogViewerView) { + super.onAttachView(view) + view.initView() + loadLogFile() + } + + fun onShareLogsSelected(): Boolean { + disposable.add(loggerRepository.getLogFiles() + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .subscribe({ + Timber.i("Loading logs files result: ${it.joinToString { it.name }}") + view?.shareLogs(it) + }, { + Timber.i("Loading logs files result: An exception occurred") + errorHandler.dispatch(it) + })) + return true + } + + fun onRefreshClick() { + loadLogFile() + } + + private fun loadLogFile() { + disposable.add(loggerRepository.getLastLogLines() + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .subscribe({ + Timber.i("Loading last log file result: load ${it.size} lines") + view?.setLines(it) + }, { + Timber.i("Loading last log file result: An exception occurred") + errorHandler.dispatch(it) + })) + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt new file mode 100644 index 00000000..bd98c24f --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerView.kt @@ -0,0 +1,13 @@ +package io.github.wulkanowy.ui.modules.about.logviewer + +import io.github.wulkanowy.ui.base.BaseView +import java.io.File + +interface LogViewerView : BaseView { + + fun initView() + + fun setLines(lines: List) + + fun shareLogs(files: List) +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt index a16e6320..b3a9e4a0 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainModule.kt @@ -11,6 +11,7 @@ import io.github.wulkanowy.ui.modules.about.AboutFragment import io.github.wulkanowy.ui.modules.about.creator.CreatorFragment import io.github.wulkanowy.ui.modules.about.license.LicenseFragment import io.github.wulkanowy.ui.modules.about.license.LicenseModule +import io.github.wulkanowy.ui.modules.about.logviewer.LogViewerFragment import io.github.wulkanowy.ui.modules.account.AccountDialog import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment import io.github.wulkanowy.ui.modules.attendance.AttendanceModule @@ -121,6 +122,10 @@ abstract class MainModule { @ContributesAndroidInjector(modules = [LicenseModule::class]) abstract fun bindLicenseFragment(): LicenseFragment + @PerFragment + @ContributesAndroidInjector + abstract fun bindLogViewerFragment(): LogViewerFragment + @PerFragment @ContributesAndroidInjector() abstract fun bindCreatorsFragment(): CreatorFragment diff --git a/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt index f9db0465..15de40d3 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/LoggerUtils.kt @@ -18,6 +18,8 @@ class DebugLogTree : Timber.DebugTree() { } } +private fun Bundle?.checkSavedState() = if (this == null) "(STATE IS NULL)" else "" + class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks { override fun onActivityPaused(activity: Activity?) { @@ -45,7 +47,7 @@ class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks { } override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) { - activity?.let { Timber.d("${it::class.java.simpleName} CREATED ${checkSavedState(savedInstanceState)}") } + activity?.let { Timber.d("${it::class.java.simpleName} CREATED ${savedInstanceState.checkSavedState()}") } } } @@ -53,7 +55,7 @@ class ActivityLifecycleLogger : Application.ActivityLifecycleCallbacks { class FragmentLifecycleLogger @Inject constructor() : FragmentManager.FragmentLifecycleCallbacks() { override fun onFragmentViewCreated(fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle?) { - Timber.d("${f::class.java.simpleName} VIEW CREATED ${checkSavedState(savedInstanceState)}") + Timber.d("${f::class.java.simpleName} VIEW CREATED ${savedInstanceState.checkSavedState()}") } override fun onFragmentStopped(fm: FragmentManager, f: Fragment) { @@ -61,7 +63,7 @@ class FragmentLifecycleLogger @Inject constructor() : FragmentManager.FragmentLi } override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) { - Timber.d("${f::class.java.simpleName} CREATED ${checkSavedState(savedInstanceState)}") + Timber.d("${f::class.java.simpleName} CREATED ${savedInstanceState.checkSavedState()}") } override fun onFragmentResumed(fm: FragmentManager, f: Fragment) { @@ -89,7 +91,7 @@ class FragmentLifecycleLogger @Inject constructor() : FragmentManager.FragmentLi } override fun onFragmentActivityCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) { - Timber.d("${f::class.java.simpleName} ACTIVITY CREATED ${checkSavedState(savedInstanceState)}") + Timber.d("${f::class.java.simpleName} ACTIVITY CREATED ${savedInstanceState.checkSavedState()}") } override fun onFragmentPaused(fm: FragmentManager, f: Fragment) { @@ -100,5 +102,3 @@ class FragmentLifecycleLogger @Inject constructor() : FragmentManager.FragmentLi Timber.d("${f::class.java.simpleName} DETACHED") } } - -private fun checkSavedState(savedInstanceState: Bundle?) = if (savedInstanceState == null) "(STATE IS NULL)" else "" diff --git a/app/src/main/res/drawable/ic_refresh.xml b/app/src/main/res/drawable/ic_refresh.xml new file mode 100644 index 00000000..cc2d1e04 --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/fragment_logviewer.xml b/app/src/main/res/layout/fragment_logviewer.xml new file mode 100644 index 00000000..64f9125f --- /dev/null +++ b/app/src/main/res/layout/fragment_logviewer.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/app/src/main/res/menu/action_menu_logviewer.xml b/app/src/main/res/menu/action_menu_logviewer.xml new file mode 100644 index 00000000..cb2b31a0 --- /dev/null +++ b/app/src/main/res/menu/action_menu_logviewer.xml @@ -0,0 +1,11 @@ + + + + diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d6ef19d7..e45c6d62 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -306,6 +306,11 @@ Awatar Zobacz więcej na GitHub + + Przeglądarka logów + Share logs + Odśwież + Treść diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 6a994f6d..30e4ef80 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -295,6 +295,16 @@ Лицензия + + аватар + Смотрите больше на GitHub + + + Просмотр журнала + Share logs + Обновление + + Содержание Снова diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e2afb061..9090fc6c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,6 +12,7 @@ Settings More About + Log viewer Creators Licenses Messages @@ -287,6 +288,10 @@ Avatar See more on GitHub + + Share logs + Refresh + Content diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml new file mode 100644 index 00000000..f0da4709 --- /dev/null +++ b/app/src/main/res/xml/provider_paths.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt b/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt index 4f76ef83..5c661f1a 100644 --- a/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt +++ b/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt @@ -1,10 +1,12 @@ package io.github.wulkanowy.utils import android.content.Context +import android.util.Log import com.crashlytics.android.Crashlytics import com.crashlytics.android.core.CrashlyticsCore +import fr.bipi.tressence.crash.CrashlyticsLogExceptionTree +import fr.bipi.tressence.crash.CrashlyticsLogTree import io.fabric.sdk.android.Fabric -import timber.log.Timber fun initCrashlytics(context: Context, appInfo: AppInfo) { Fabric.with(Fabric.Builder(context) @@ -19,13 +21,6 @@ fun initCrashlytics(context: Context, appInfo: AppInfo) { .build()) } -class CrashlyticsTree : Timber.Tree() { +class CrashlyticsTree : CrashlyticsLogTree(Log.VERBOSE) - override fun log(priority: Int, tag: String?, message: String, t: Throwable?) { - Crashlytics.setInt("priority", priority) - Crashlytics.setString("tag", tag) - - if (t == null) Crashlytics.log(message) - else Crashlytics.logException(t) - } -} +class CrashlyticsExceptionTree : CrashlyticsLogExceptionTree()