Use Crashlytics for error handling and fix up navigation

This commit is contained in:
Billy Brawner 2019-01-26 22:10:03 -06:00
parent f3e456ac28
commit ba92bd850b
11 changed files with 95 additions and 58 deletions

2
.gitignore vendored
View file

@ -11,4 +11,4 @@
*.log
.idea/
*~
acra.properties
*/google-services.json

View file

@ -2,30 +2,24 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
Properties acra = new Properties()
acra.load(new FileInputStream("app/acra.properties"))
apply plugin: 'io.fabric'
android {
compileSdkVersion 27
compileSdkVersion 28
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId "com.wbrawner.budget"
minSdkVersion 24
targetSdkVersion 27
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
vectorDrawables {
useSupportLibrary = true
}
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
buildConfigField "String", "ACRA_URL", "\"${acra.getProperty("url")}\""
buildConfigField "String", "ACRA_USER", "\"${acra.getProperty("user")}\""
buildConfigField "String", "ACRA_PASS", "\"${acra.getProperty("pass")}\""
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
@ -46,10 +40,13 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:support-compat:28.0.0'
implementation 'com.android.support:support-media-compat:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:27.1.1'
implementation "com.android.support:support-emoji-bundled:27.1.1"
implementation 'com.android.support:design:28.0.0'
implementation "com.android.support:support-emoji-bundled:28.0.0"
implementation 'com.github.BlacKCaT27:CurrencyEditText:2.0.2'
def room_version = "1.1.1"
def lifecycle_version = "1.1.1"
@ -60,9 +57,11 @@ dependencies {
androidTestImplementation "android.arch.persistence.room:testing:$room_version"
testImplementation 'junit:junit:4.12'
// ACRA Crash reporting
def acraVersion = '5.1.3'
implementation "ch.acra:acra-http:$acraVersion"
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.firebase:firebase-core:16.0.6'
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'
}
apply plugin: 'com.google.gms.google-services'

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.wbrawner.budget">
<application
@ -9,7 +10,8 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name="com.wbrawner.budget.ui.MainActivity">
<intent-filter android:label="@string/app_name_short">
<action android:name="android.intent.action.MAIN" />
@ -20,8 +22,20 @@
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
<activity android:name="com.wbrawner.budget.ui.transactions.AddEditTransactionActivity" />
<activity android:name="com.wbrawner.budget.ui.categories.AddEditCategoryActivity" />
<activity
android:name="com.wbrawner.budget.ui.transactions.AddEditTransactionActivity"
android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.MainActivity" />
</activity>
<activity
android:name="com.wbrawner.budget.ui.categories.AddEditCategoryActivity"
android:parentActivityName=".ui.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.MainActivity" />
</activity>
</application>
</manifest>

View file

@ -2,24 +2,13 @@ package com.wbrawner.budget
import android.app.Application
import android.arch.persistence.room.Room
import android.content.Context
import com.wbrawner.budget.data.dao.TransactionDao
import com.wbrawner.budget.data.BudgetDatabase
import com.wbrawner.budget.data.dao.CategoryDao
import com.wbrawner.budget.data.dao.TransactionDao
import com.wbrawner.budget.data.migrations.MIGRATION_1_2
import com.wbrawner.budget.data.migrations.MIGRATION_2_3
import org.acra.ACRA
import org.acra.annotation.AcraCore
import org.acra.annotation.AcraHttpSender
import org.acra.data.StringFormat
import org.acra.sender.HttpSender
@AcraCore(reportFormat = StringFormat.JSON)
@AcraHttpSender(uri = BuildConfig.ACRA_URL,
basicAuthLogin = BuildConfig.ACRA_USER,
basicAuthPassword = BuildConfig.ACRA_PASS,
httpMethod = HttpSender.Method.POST)
class AllowanceApplication: Application() {
class AllowanceApplication : Application() {
lateinit var database: BudgetDatabase
private set
@ -39,10 +28,4 @@ class AllowanceApplication: Application() {
transactionDao = database.transactionDao()
categoryDao = database.categoryDao()
}
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
if (!BuildConfig.DEBUG) ACRA.init(this)
}
}

View file

@ -18,7 +18,7 @@ interface TransactionDao {
@Query("SELECT * FROM `Transaction` WHERE id = :id")
fun load(id: Int): LiveData<TransactionWithCategory>
@Query("SELECT * FROM `Transaction` LIMIT :count")
@Query("SELECT * FROM `Transaction` ORDER BY date DESC LIMIT :count")
fun loadMultiple(count: Int): LiveData<List<TransactionWithCategory>>
@Query("SELECT (SELECT TOTAL(amount) from `Transaction` WHERE isExpense = 0) - (SELECT TOTAL(amount) from `Transaction` WHERE isExpense = 1)")

View file

@ -2,12 +2,14 @@ package com.wbrawner.budget.ui.categories
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.support.v4.app.NavUtils
import android.support.v4.app.TaskStackBuilder
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import com.wbrawner.budget.R
import com.wbrawner.budget.data.model.Category
import kotlinx.android.synthetic.main.activity_add_edit_category.*
@ -55,7 +57,21 @@ class AddEditCategoryActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
android.R.id.home -> onBackPressed()
android.R.id.home -> {
val upIntent: Intent? = NavUtils.getParentActivityIntent(this)
when {
upIntent == null -> throw IllegalStateException("No Parent Activity Intent")
NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot -> {
TaskStackBuilder.create(this)
.addNextIntentWithParentStack(upIntent)
.startActivities()
}
else -> {
NavUtils.navigateUpTo(this, upIntent)
}
}
}
R.id.action_save -> {
if (!validateFields()) return true
viewModel.saveCategory(Category(
@ -79,7 +95,7 @@ class AddEditCategoryActivity : AppCompatActivity() {
private fun validateFields(): Boolean {
var errors = false
if (edit_category_name.text.isEmpty()) {
if (edit_category_name.text?.isEmpty() == true) {
edit_category_name.error = getString(R.string.required_field_name)
errors = true
}

View file

@ -51,7 +51,7 @@ class CategoryListFragment : Fragment() {
}
})
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0) fab.hide() else fab.show()
}
})

View file

@ -2,7 +2,10 @@ package com.wbrawner.budget.ui.transactions
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Intent
import android.os.Bundle
import android.support.v4.app.NavUtils
import android.support.v4.app.TaskStackBuilder
import android.support.v7.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem
@ -95,7 +98,7 @@ class AddEditTransactionActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
android.R.id.home -> onBackPressed()
android.R.id.home -> onNavigateUp()
R.id.action_save -> {
val field = edit_transaction_date
val cal = Calendar.getInstance()
@ -111,16 +114,33 @@ class AddEditTransactionActivity : AppCompatActivity() {
categoryId = (edit_transaction_category.selectedItem as TransactionCategory).id,
remoteId = null
))
finish()
onNavigateUp()
}
R.id.action_delete -> {
viewModel.deleteTransactionById(this@AddEditTransactionActivity.id!!)
finish()
onNavigateUp()
}
}
return true
}
override fun onNavigateUp(): Boolean {
val upIntent: Intent? = NavUtils.getParentActivityIntent(this)
when {
upIntent == null -> throw IllegalStateException("No Parent Activity Intent")
NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot -> {
TaskStackBuilder.create(this)
.addNextIntentWithParentStack(upIntent)
.startActivities()
}
else -> {
NavUtils.navigateUpTo(this, upIntent)
}
}
return true
}
companion object {
const val EXTRA_TRANSACTION_ID = "EXTRA_TRANSACTION_ID"

View file

@ -51,7 +51,7 @@ class TransactionListFragment : Fragment() {
}
})
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0) fab.hide() else fab.show()
}
})

View file

@ -1,17 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.0'
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
maven {
url 'https://maven.fabric.io/public'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:3.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.google.gms:google-services:4.2.0'
classpath 'io.fabric.tools:gradle:1.26.1'
}
}
@ -20,6 +22,9 @@ allprojects {
google()
jcenter()
maven { url "https://jitpack.io" }
maven {
url 'https://maven.google.com/'
}
}
}

View file

@ -1,6 +1,6 @@
#Mon Jul 30 21:54:00 CDT 2018
#Sat Jan 26 20:48:01 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip