From be161cf16147681dd0eeaf215a83c4482653d968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Thu, 11 Jan 2018 21:57:41 +0100 Subject: [PATCH] Add crashlytics (#47) --- .circleci/config.yml | 6 ++--- app/build.gradle | 27 +++++++++++++++++++ app/src/main/AndroidManifest.xml | 3 +++ .../io/github/wulkanowy/WulkanowyApp.java | 15 +++++++++++ .../github/wulkanowy/ui/login/LoginTask.java | 23 ++++++++++++++-- build.gradle | 1 - 6 files changed, 69 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea9c7e65..841ff9e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,7 +33,7 @@ jobs: command: ./gradlew dependencies --no-daemon --stacktrace --console=plain -PdisablePreDex || true - run: name: Initial build - command: ./gradlew -x test -x lint build assembleDebug --no-daemon --stacktrace --console=plain -PdisablePreDex + command: ./gradlew build assembleDebug -x test -x lint -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex - store_artifacts: path: ./app/build/outputs/apk/ destination: apks/ @@ -54,7 +54,7 @@ jobs: <<: *general_cache_key - run: name: Run lint - command: ./gradlew lint --no-daemon --stacktrace --console=plain -PdisablePreDex + command: ./gradlew lint -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex - store_artifacts: path: ./app/build/reports/ destination: lint_reports/app/ @@ -73,7 +73,7 @@ jobs: <<: *general_cache_key - run: name: Run app tests - command: ./gradlew :app:test :app:jacocoTestReport --no-daemon --stacktrace --console=plain -PdisablePreDex + command: ./gradlew :app:test :app:jacocoTestReport -x fabricGenerateResourcesRelease --no-daemon --stacktrace --console=plain -PdisablePreDex - run: name: Upload unit code coverage to codecov command: bash <(curl -s https://codecov.io/bash) -F app diff --git a/app/build.gradle b/app/build.gradle index 37309c30..205a056d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,22 @@ +buildscript { + repositories { + maven { url "https://plugins.gradle.org/m2/" } + maven { url 'https://maven.fabric.io/public' } + } + + dependencies { + classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' + classpath 'io.fabric.tools:gradle:1.25.1' + } +} + +repositories { + maven { url 'https://maven.fabric.io/public' } +} + apply plugin: 'com.android.application' apply plugin: 'org.greenrobot.greendao' +apply plugin: 'io.fabric' apply from: '../jacoco.gradle' apply from: '../android-sonarqube.gradle' @@ -17,6 +34,9 @@ android { vectorDrawables.useSupportLibrary = true buildConfigField "String", "UPDATE_URL", "\"https://bitrise-redirector.herokuapp.com" + "/v0.1/apps/daeff1893f3c8128/builds/" + "${getCurrentGitBranch()}" + "/artifacts/app-release-bitrise-signed.apk/info\"" + manifestPlaceholders = [ + fabricApiKey: System.getenv("FABRIC_API_KEY") ?: "null" + ] } buildTypes { @@ -66,6 +86,13 @@ dependencies { implementation 'com.google.dagger:dagger-android:2.14.1' implementation 'com.google.dagger:dagger-android-support:2.14.1' + implementation('com.crashlytics.sdk.android:crashlytics:2.8.0@aar') { + transitive = true + } + implementation('com.crashlytics.sdk.android:answers:1.4.1@aar') { + transitive = true + } + annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cc127ca4..4b919954 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -59,6 +59,9 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> + diff --git a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java index c2fde603..2c7c74ac 100644 --- a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java +++ b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.java @@ -4,10 +4,14 @@ import android.app.Application; import android.content.Context; import android.content.SharedPreferences; +import com.crashlytics.android.Crashlytics; +import com.crashlytics.android.core.CrashlyticsCore; + import org.greenrobot.greendao.query.QueryBuilder; import eu.davidea.flexibleadapter.FlexibleAdapter; import eu.davidea.flexibleadapter.utils.Log; +import io.fabric.sdk.android.Fabric; import io.github.wulkanowy.db.dao.entities.DaoMaster; import io.github.wulkanowy.db.dao.entities.DaoSession; @@ -25,6 +29,8 @@ public class WulkanowyApp extends Application { enableDebugLog(); } + initializeFabric(); + DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(this, "wulkanowy-db"); daoSession = new DaoMaster(devOpenHelper.getWritableDb()).newSession(); @@ -46,6 +52,15 @@ public class WulkanowyApp extends Application { FlexibleAdapter.enableLogs(Log.Level.DEBUG); } + private void initializeFabric() { + Fabric.with(new Fabric.Builder(this) + .kits(new Crashlytics.Builder() + .core(new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()) + .build()) + .debuggable(BuildConfig.DEBUG) + .build()); + } + public DaoSession getDaoSession() { return daoSession; } diff --git a/app/src/main/java/io/github/wulkanowy/ui/login/LoginTask.java b/app/src/main/java/io/github/wulkanowy/ui/login/LoginTask.java index 6e8a5596..3bf70284 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/login/LoginTask.java +++ b/app/src/main/java/io/github/wulkanowy/ui/login/LoginTask.java @@ -13,6 +13,10 @@ import android.view.View; import android.widget.EditText; import android.widget.TextView; +import com.crashlytics.android.Crashlytics; +import com.crashlytics.android.answers.Answers; +import com.crashlytics.android.answers.CustomEvent; + import java.io.IOException; import java.lang.ref.WeakReference; import java.net.SocketTimeoutException; @@ -53,7 +57,7 @@ public class LoginTask extends AsyncTask { private WeakReference showText; - public LoginTask(Activity activity, String email, String password, String symbol) { + LoginTask(Activity activity, String email, String password, String symbol) { this.activity = new WeakReference<>(activity); this.email = email; this.password = password; @@ -93,6 +97,9 @@ public class LoginTask extends AsyncTask { return R.string.error_host_offline; } catch (UnsupportedOperationException e) { return -1; + } catch (Throwable e) { + Crashlytics.logException(e); + return R.string.login_denied_text; } new FullSyncJob().scheduledJob(activity.get()); @@ -116,6 +123,7 @@ public class LoginTask extends AsyncTask { switch (messageID) { // if success case R.string.login_accepted_text: + logFirstLoginAction(true, activity.get().getString(messageID)); Intent intent = new Intent(activity.get(), DashboardActivity.class); activity.get().finish(); activity.get().startActivity(intent); @@ -123,6 +131,7 @@ public class LoginTask extends AsyncTask { // if bad credentials entered case R.string.login_bad_credentials_text: + logFirstLoginAction(false, activity.get().getString(messageID)); EditText passwordView = activity.get().findViewById(R.id.password); passwordView.setError(activity.get().getString(R.string.error_incorrect_password)); passwordView.requestFocus(); @@ -131,6 +140,7 @@ public class LoginTask extends AsyncTask { // if no permission case R.string.error_bad_account_permission: + logFirstLoginAction(false, activity.get().getString(messageID)); // Change to visible symbol input view TextInputLayout symbolLayout = activity.get().findViewById(R.id.to_symbol_input_layout); symbolLayout.setVisibility(View.VISIBLE); @@ -143,6 +153,7 @@ public class LoginTask extends AsyncTask { // if rooted and SDK < 18 case -1: + logFirstLoginAction(false, "Device rooted"); final AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity.get()) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(R.string.alert_dialog_blocked_app) @@ -157,12 +168,20 @@ public class LoginTask extends AsyncTask { break; default: + logFirstLoginAction(false, activity.get().getString(messageID)); Snackbar.make(activity.get().findViewById(R.id.fragment_container), messageID, Snackbar.LENGTH_LONG).show(); break; } } + private void logFirstLoginAction(boolean success, String message) { + Answers.getInstance().logCustom(new CustomEvent("First login") + .putCustomAttribute("Symbol", symbol) + .putCustomAttribute("Success", success ? 1 : 0) + .putCustomAttribute("Message", message)); + } + @Override protected void onCancelled() { showProgress(false); @@ -171,7 +190,7 @@ public class LoginTask extends AsyncTask { /** * Shows the progress UI and hides the login form. */ - public void showProgress(final boolean show) { + void showProgress(final boolean show) { loginFormView = new WeakReference<>(activity.get().findViewById(R.id.login_form)); progressView = new WeakReference<>(activity.get().findViewById(R.id.login_progress)); diff --git a/build.gradle b/build.gradle index e4bc7bec..17b22c0d 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,6 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' - classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files