mirror of
https://github.com/dzeiocom/crashhandler.git
synced 2025-04-22 10:52:16 +00:00
feat: simplified sample app code to better understand how it work (#10)
This commit is contained in:
parent
71993d0291
commit
64d9b25883
@ -8,15 +8,25 @@ class Application : android.app.Application() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
|
// get the device Preference store
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
|
// create the Crash Handler
|
||||||
CrashHandler.Builder()
|
CrashHandler.Builder()
|
||||||
.withActivity(ErrorActivity::class.java)
|
// need the application context to run
|
||||||
.withContext(this)
|
.withContext(this)
|
||||||
|
// define a custom activity to use
|
||||||
|
.withActivity(ErrorActivity::class.java)
|
||||||
|
// define the preferenceManager to be able to handle crash in a custom Activity and to have the previous crash date in the logs
|
||||||
.withPrefs(prefs)
|
.withPrefs(prefs)
|
||||||
.withPrefsKey("com.dzeio.crashhandler.key")
|
.withPrefsKey("com.dzeio.crashhandler.key")
|
||||||
.withPrefix("Pouet :D")
|
// a Prefix to add at the beginning the crash message
|
||||||
|
.withPrefix(
|
||||||
|
"POKEMON"
|
||||||
|
)
|
||||||
|
// a Suffix to add at the end of the crash message
|
||||||
.withSuffix("WHYYYYY")
|
.withSuffix("WHYYYYY")
|
||||||
|
// build & start the module
|
||||||
.build().setup()
|
.build().setup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package com.dzeio.crashhandlertest.ui
|
|||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Process
|
import android.os.Process
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -12,37 +11,30 @@ import androidx.core.view.WindowCompat
|
|||||||
import com.dzeio.crashhandlertest.databinding.ActivityErrorBinding
|
import com.dzeio.crashhandlertest.databinding.ActivityErrorBinding
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example Activity for a custom ErrorActivity
|
||||||
|
*
|
||||||
|
* note: try to keep the complexity of this class as low as possible
|
||||||
|
* to make sure this will always load
|
||||||
|
*/
|
||||||
class ErrorActivity : AppCompatActivity() {
|
class ErrorActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
// the view binding
|
||||||
private lateinit var binding: ActivityErrorBinding
|
private lateinit var binding: ActivityErrorBinding
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
// inflate the view
|
||||||
binding = ActivityErrorBinding.inflate(layoutInflater)
|
binding = ActivityErrorBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
// get the error string from the library
|
||||||
val data = intent.getStringExtra("error")
|
val data = intent.getStringExtra("error")
|
||||||
|
|
||||||
// Get Application datas
|
|
||||||
val deviceToReport =
|
|
||||||
if (Build.DEVICE.contains(Build.MANUFACTURER)) {
|
|
||||||
Build.DEVICE
|
|
||||||
} else {
|
|
||||||
"${Build.MANUFACTURER} ${Build.DEVICE}"
|
|
||||||
}
|
|
||||||
|
|
||||||
val reportText = """
|
|
||||||
Crash Report (Thread: ${intent?.getLongExtra("threadId", -1) ?: "unknown"})
|
|
||||||
on $deviceToReport (${Build.MODEL}) running Android ${Build.VERSION.RELEASE} (${Build.VERSION.SDK_INT})
|
|
||||||
|
|
||||||
backtrace:
|
|
||||||
|
|
||||||
""".trimIndent() + data
|
|
||||||
|
|
||||||
// put it in the textView
|
// put it in the textView
|
||||||
binding.errorText.text = reportText
|
binding.errorText.text = data
|
||||||
|
|
||||||
// Handle the Quit button
|
// Handle the Quit button
|
||||||
binding.errorQuit.setOnClickListener {
|
binding.errorQuit.setOnClickListener {
|
||||||
@ -57,8 +49,9 @@ class ErrorActivity : AppCompatActivity() {
|
|||||||
intent.setDataAndType(Uri.parse("mailto:"), "text/plain")
|
intent.setDataAndType(Uri.parse("mailto:"), "text/plain")
|
||||||
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("report.openhealth@dzeio.com"))
|
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("report.openhealth@dzeio.com"))
|
||||||
intent.putExtra(Intent.EXTRA_SUBJECT, "Error report for application crash")
|
intent.putExtra(Intent.EXTRA_SUBJECT, "Error report for application crash")
|
||||||
intent.putExtra(Intent.EXTRA_TEXT, "Send Report Email\n$reportText")
|
intent.putExtra(Intent.EXTRA_TEXT, "Send Report Email\n$data")
|
||||||
|
|
||||||
|
// send intent
|
||||||
try {
|
try {
|
||||||
startActivity(Intent.createChooser(intent, "Send Report Email..."))
|
startActivity(Intent.createChooser(intent, "Send Report Email..."))
|
||||||
} catch (e: ActivityNotFoundException) {
|
} catch (e: ActivityNotFoundException) {
|
||||||
@ -69,8 +62,10 @@ class ErrorActivity : AppCompatActivity() {
|
|||||||
// Handle the GitHub Button
|
// Handle the GitHub Button
|
||||||
binding.errorSubmitGithub.setOnClickListener {
|
binding.errorSubmitGithub.setOnClickListener {
|
||||||
// Build URL
|
// Build URL
|
||||||
val url = "https://github.com/dzeiocom/OpenHealth/issues/new?title=Application Error&body=$reportText"
|
val title = "Application Error"
|
||||||
|
val url = "https://github.com/dzeiocom/OpenHealth/issues/new?title=$title&body=$data"
|
||||||
|
|
||||||
|
// send intent
|
||||||
try {
|
try {
|
||||||
startActivity(
|
startActivity(
|
||||||
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
||||||
|
@ -3,8 +3,12 @@ package com.dzeio.crashhandlertest.ui
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
|
import com.dzeio.crashhandlertest.R
|
||||||
import com.dzeio.crashhandlertest.databinding.ActivityMainBinding
|
import com.dzeio.crashhandlertest.databinding.ActivityMainBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
@ -15,5 +19,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
binding.buttonFirst.setOnClickListener {
|
||||||
|
// DIE
|
||||||
|
throw Exception(getString(R.string.error_message))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,43 +0,0 @@
|
|||||||
package com.dzeio.crashhandlertest.ui
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import com.dzeio.crashhandlertest.databinding.FragmentMainBinding
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple [Fragment] subclass as the default destination in the navigation.
|
|
||||||
*/
|
|
||||||
class MainFragment : Fragment() {
|
|
||||||
|
|
||||||
private var _binding: FragmentMainBinding? = null
|
|
||||||
|
|
||||||
// This property is only valid between onCreateView and
|
|
||||||
// onDestroyView.
|
|
||||||
private val binding get() = _binding!!
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
_binding = FragmentMainBinding.inflate(inflater, container, false)
|
|
||||||
return binding.root
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
||||||
super.onViewCreated(view, savedInstanceState)
|
|
||||||
|
|
||||||
binding.buttonFirst.setOnClickListener {
|
|
||||||
// DIE
|
|
||||||
throw Exception("POKÉMON :D")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:id="@+id/linearLayout2"
|
android:id="@+id/linearLayout2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -12,7 +11,8 @@
|
|||||||
style="?textAppearanceHeadline5"
|
style="?textAppearanceHeadline5"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="blablabla"
|
android:textAlignment="center"
|
||||||
|
android:text="@string/crash_handler_page_title"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
@ -22,7 +22,8 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:text="blablabla2"
|
android:textAlignment="center"
|
||||||
|
android:text="@string/crash_handler_page_subtitle"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textView3" />
|
app:layout_constraintTop_toBottomOf="@+id/textView3" />
|
||||||
@ -42,7 +43,8 @@
|
|||||||
android:id="@+id/error_text"
|
android:id="@+id/error_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
style="?textAppearanceCaption"
|
style="?textAppearanceCaption"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:textIsSelectable="true" />
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
@ -52,7 +54,7 @@
|
|||||||
android:id="@+id/error_submit_github"
|
android:id="@+id/error_submit_github"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Github"
|
android:text="@string/github"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
app:layout_constraintBaseline_toBaselineOf="@+id/error_submit_email"
|
app:layout_constraintBaseline_toBaselineOf="@+id/error_submit_email"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
@ -63,7 +65,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:text="E-Mail"
|
android:text="@string/e_mail"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/error_quit"
|
app:layout_constraintBottom_toTopOf="@+id/error_quit"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
@ -72,7 +74,7 @@
|
|||||||
android:id="@+id/error_quit"
|
android:id="@+id/error_quit"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:text="Quit"
|
android:text="@string/quit"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
@ -1,23 +1,21 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:context=".ui.MainActivity">
|
tools:context=".ui.MainActivity"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<Button
|
||||||
android:id="@+id/fragment"
|
android:id="@+id/button_first"
|
||||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginTop="?attr/actionBarSize"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:text="@string/crash_app"
|
||||||
android:layout_height="match_parent"
|
|
||||||
app:defaultNavHost="true"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
app:navGraph="@navigation/nav_graph" />
|
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
tools:context=".ui.MainFragment"
|
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/button_first"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/crash_app"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
/>
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:id="@+id/nav_graph"
|
|
||||||
app:startDestination="@id/MainFragment">
|
|
||||||
|
|
||||||
<fragment
|
|
||||||
android:id="@+id/MainFragment"
|
|
||||||
android:name="com.dzeio.crashhandlertest.ui.MainFragment"
|
|
||||||
android:label="@string/first_fragment_label"
|
|
||||||
tools:layout="@layout/fragment_main"/>
|
|
||||||
</navigation>
|
|
@ -1,9 +1,10 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name" translatable="false">Crash Handler</string>
|
<string name="app_name" translatable="false">Crash Handler</string>
|
||||||
<string name="title_activity_main" translatable="false">MainActivity</string>
|
|
||||||
<!-- Strings used for fragments for navigation -->
|
|
||||||
<string name="first_fragment_label" translatable="false">First Fragment</string>
|
|
||||||
<string name="second_fragment_label" translatable="false">Second Fragment</string>
|
|
||||||
|
|
||||||
<string name="crash_app" translatable="false">Crash app</string>
|
<string name="crash_app" translatable="false">Crash app</string>
|
||||||
|
<string name="error_message" translatable="false">I am an error</string>
|
||||||
|
<string name="crash_handler_page_title" translatable="false">Crash Handler page title</string>
|
||||||
|
<string name="crash_handler_page_subtitle" translatable="false">crash handler page subtitle</string>
|
||||||
|
<string name="github" translatable="false">Github</string>
|
||||||
|
<string name="e_mail" translatable="false">E-Mail</string>
|
||||||
|
<string name="quit" translatable="false">Quit</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user