Added crash reporting.
This commit is contained in:
parent
3b257fb15b
commit
ea346de4df
5 changed files with 249 additions and 0 deletions
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* App.kt
|
||||
*
|
||||
* Copyright 2016-2017 Erik C. Thauvin (erik@thauvin.net)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.thauvin.erik.android.tesremoteprogrammer
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.reporting.CrashEmailFactory
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.reporting.CrashReportActivity
|
||||
import org.acra.ACRA
|
||||
import org.acra.ReportingInteractionMode
|
||||
import org.acra.annotation.ReportsCrashes
|
||||
|
||||
|
||||
@ReportsCrashes(mailTo = "erik@thauvin.net",
|
||||
mode = ReportingInteractionMode.DIALOG,
|
||||
reportSenderFactoryClasses = arrayOf(CrashEmailFactory::class),
|
||||
reportDialogClass = CrashReportActivity::class)
|
||||
|
||||
open class App : Application() {
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base)
|
||||
ACRA.init(this)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* CrashEmail.kt
|
||||
*
|
||||
* Copyright 2016-2017 Erik C. Thauvin (erik@thauvin.net)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.thauvin.erik.android.tesremoteprogrammer.reporting
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.text.TextUtils
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.R
|
||||
import org.acra.ACRAConstants
|
||||
import org.acra.ReportField
|
||||
import org.acra.collections.ImmutableSet
|
||||
import org.acra.collector.CrashReportData
|
||||
import org.acra.config.ACRAConfiguration
|
||||
import org.acra.sender.ReportSender
|
||||
import org.acra.sender.ReportSenderException
|
||||
|
||||
class CrashEmail(private val config: ACRAConfiguration) : ReportSender {
|
||||
|
||||
@Throws(ReportSenderException::class)
|
||||
override fun send(context: Context, errorContent: CrashReportData) {
|
||||
|
||||
val subject = context.getString(R.string.crash_report_subject,
|
||||
context.getString(R.string.app_name))
|
||||
val body = buildBody(errorContent)
|
||||
|
||||
val emailIntent = Intent(android.content.Intent.ACTION_SENDTO)
|
||||
emailIntent.data = Uri.fromParts("mailto", config.mailTo(), null)
|
||||
emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject)
|
||||
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body)
|
||||
context.startActivity(emailIntent)
|
||||
}
|
||||
|
||||
private fun buildBody(errorContent: CrashReportData): String {
|
||||
var fields: Set<ReportField> = config.reportFields
|
||||
if (fields.isEmpty()) {
|
||||
fields = ImmutableSet(*ACRAConstants.DEFAULT_MAIL_REPORT_FIELDS)
|
||||
}
|
||||
val builder = StringBuilder()
|
||||
for (field in fields) {
|
||||
if (field == ReportField.USER_COMMENT || field == ReportField.STACK_TRACE) {
|
||||
builder.append("-- ").append(field.toString()).append(" --\n")
|
||||
} else {
|
||||
builder.append(field.toString()).append('=')
|
||||
}
|
||||
val value = errorContent[field]
|
||||
if (value != null) {
|
||||
builder.append(TextUtils.join("\n\t", value.flatten()))
|
||||
}
|
||||
builder.append('\n')
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* CrashEmailFactory.kt
|
||||
*
|
||||
* Copyright 2016-2017 Erik C. Thauvin (erik@thauvin.net)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.thauvin.erik.android.tesremoteprogrammer.reporting
|
||||
|
||||
import android.content.Context
|
||||
import org.acra.config.ACRAConfiguration
|
||||
import org.acra.sender.ReportSender
|
||||
import org.acra.sender.ReportSenderFactory
|
||||
|
||||
class CrashEmailFactory : ReportSenderFactory {
|
||||
override fun create(context: Context, config: ACRAConfiguration): ReportSender =
|
||||
CrashEmail(config)
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* CrashReportActivity.kt
|
||||
*
|
||||
* Copyright 2016-2017 Erik C. Thauvin (erik@thauvin.net)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.thauvin.erik.android.tesremoteprogrammer.reporting
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.widget.EditText
|
||||
|
||||
import net.thauvin.erik.android.tesremoteprogrammer.R
|
||||
|
||||
import org.acra.dialog.BaseCrashReportDialog
|
||||
import org.jetbrains.anko.find
|
||||
|
||||
class CrashReportActivity : BaseCrashReportDialog(), DialogInterface.OnDismissListener,
|
||||
DialogInterface.OnClickListener {
|
||||
private var comment: EditText? = null
|
||||
|
||||
companion object {
|
||||
private val STATE_USER_COMMENT = "comment"
|
||||
}
|
||||
|
||||
override fun init(savedInstanceState: Bundle?) {
|
||||
super.init(savedInstanceState)
|
||||
|
||||
val dialog = AlertDialog.Builder(this)
|
||||
.setTitle(getString(R.string.crash_dialog_title, getString(R.string.app_name)))
|
||||
.setView(R.layout.crash_report_dialog)
|
||||
.setPositiveButton(R.string.ok, this)
|
||||
.setNegativeButton(R.string.cancel, this)
|
||||
.create()
|
||||
|
||||
dialog.setCanceledOnTouchOutside(false)
|
||||
dialog.setOnDismissListener(this)
|
||||
dialog.show()
|
||||
|
||||
comment = dialog.find(android.R.id.input)
|
||||
if (savedInstanceState != null) {
|
||||
comment!!.setText(savedInstanceState.getString(STATE_USER_COMMENT))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onClick(dialog: DialogInterface, which: Int) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
sendCrash(comment!!.text.toString(), "")
|
||||
} else {
|
||||
cancelReports()
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
outState.putString(STATE_USER_COMMENT, comment!!.text.toString())
|
||||
super.onSaveInstanceState(outState)
|
||||
}
|
||||
}
|
37
app/src/main/res/layout/crash_report_dialog.xml
Normal file
37
app/src/main/res/layout/crash_report_dialog.xml
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="24dp"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:paddingTop="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/crash_dialog_text" />
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/text2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="@string/crash_dialog_comment_prompt" />
|
||||
|
||||
<EditText
|
||||
android:id="@android:id/input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:inputType="textMultiLine" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
Loading…
Add table
Add a link
Reference in a new issue