Add Firebase Analytics & Crashlytics

This commit is contained in:
Sergey Solovyev 2023-09-15 11:29:30 +02:00
parent d9bbdff0e0
commit 0a69050e98
9 changed files with 64 additions and 109 deletions

View File

@ -24,6 +24,8 @@ apply plugin: 'com.android.application'
apply plugin: 'signing' apply plugin: 'signing'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
android { android {
compileSdk versions.sdk.compile compileSdk versions.sdk.compile
@ -89,9 +91,10 @@ dependencies {
exclude(module: 'xercesImpl') exclude(module: 'xercesImpl')
} }
implementation 'org.solovyev.android:checkout:1.3.0' implementation 'org.solovyev.android:checkout:1.3.0'
implementation "com.google.android.gms:play-services-ads:22.2.0" implementation platform('com.google.firebase:firebase-bom:32.2.3')
implementation "com.google.android.gms:play-services-base:${versions.gpsLib}" implementation "com.google.firebase:firebase-crashlytics"
implementation "com.google.android.gms:play-services-analytics:18.0.3" implementation "com.google.firebase:firebase-analytics"
implementation 'com.google.android.gms:play-services-ads:22.4.0'
implementation 'com.google.guava:guava:32.1.2-android' implementation 'com.google.guava:guava:32.1.2-android'
implementation('org.simpleframework:simple-xml:2.7.1') { implementation('org.simpleframework:simple-xml:2.7.1') {
exclude(module: 'stax') exclude(module: 'stax')

29
app/google-services.json Normal file
View File

@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "256354490244",
"project_id": "calculatorpp-86d8a",
"storage_bucket": "calculatorpp-86d8a.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:256354490244:android:4674f70d035e4bbdb5efd1",
"android_client_info": {
"package_name": "org.solovyev.android.calculator"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyDmabRGhOstItse_rveL5ReDooqfK2hDHo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

View File

@ -5,8 +5,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static org.solovyev.android.calculator.App.cast; import static org.solovyev.android.calculator.App.cast;
import static org.solovyev.android.calculator.Preferences.Gui.keepScreenOn; import static org.solovyev.android.calculator.Preferences.Gui.keepScreenOn;
import android.app.Activity;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
@ -16,7 +14,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.DrawableRes; import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
import androidx.annotation.StringRes; import androidx.annotation.StringRes;
@ -25,6 +22,10 @@ import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import dagger.Lazy;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import org.solovyev.android.Check; import org.solovyev.android.Check;
import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.ga.Ga;
import org.solovyev.android.calculator.language.Language; import org.solovyev.android.calculator.language.Language;
@ -32,12 +33,6 @@ import org.solovyev.android.calculator.language.Languages;
import org.solovyev.android.calculator.view.Tabs; import org.solovyev.android.calculator.view.Tabs;
import org.solovyev.android.views.dragbutton.DirectionDragImageButton; import org.solovyev.android.views.dragbutton.DirectionDragImageButton;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import dagger.Lazy;
public abstract class BaseActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { public abstract class BaseActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
@Nonnull @Nonnull
@ -79,14 +74,6 @@ public abstract class BaseActivity extends AppCompatActivity implements SharedPr
this.tabs = new Tabs(this); this.tabs = new Tabs(this);
} }
public void reportActivityStop(@Nonnull Activity activity) {
ga.get().getAnalytics().reportActivityStop(activity);
}
public void reportActivityStart(@Nonnull Activity activity) {
ga.get().getAnalytics().reportActivityStart(activity);
}
public static void setFont(@Nonnull View view, @Nonnull Typeface newTypeface) { public static void setFont(@Nonnull View view, @Nonnull Typeface newTypeface) {
if (view instanceof TextView) { if (view instanceof TextView) {
final TextView textView = (TextView) view; final TextView textView = (TextView) view;
@ -210,18 +197,6 @@ public abstract class BaseActivity extends AppCompatActivity implements SharedPr
protected void inject(@Nonnull AppComponent component) { protected void inject(@Nonnull AppComponent component) {
} }
@Override
protected void onStart() {
super.onStart();
reportActivityStart(this);
}
@Override
protected void onStop() {
reportActivityStop(this);
super.onStop();
}
@Override @Override
public boolean onKeyUp(int keyCode, KeyEvent event) { public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) { if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) {

View File

@ -15,8 +15,6 @@ import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import org.solovyev.android.calculator.ga.Ga; import org.solovyev.android.calculator.ga.Ga;
@ -76,14 +74,6 @@ public abstract class BaseDialogFragment extends DialogFragment implements View.
return dialog; return dialog;
} }
@Override
public void onResume() {
super.onResume();
final Tracker tracker = ga.getTracker();
tracker.setScreenName(getClass().getSimpleName());
tracker.send(new HitBuilders.ScreenViewBuilder().build());
}
protected void onShowDialog(@NonNull AlertDialog dialog, boolean firstTime) { protected void onShowDialog(@NonNull AlertDialog dialog, boolean firstTime) {
} }

View File

@ -25,9 +25,6 @@ package org.solovyev.android.calculator;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.view.GravityCompat;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.Spanned; import android.text.Spanned;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
@ -36,8 +33,14 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.StringRes;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.view.GravityCompat;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
import jscl.AngleUnit; import jscl.AngleUnit;
import jscl.NumeralBase; import jscl.NumeralBase;
import org.solovyev.android.calculator.converter.ConverterFragment; import org.solovyev.android.calculator.converter.ConverterFragment;
@ -46,10 +49,6 @@ import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.keyboard.PartialKeyboardUi; import org.solovyev.android.calculator.keyboard.PartialKeyboardUi;
import org.solovyev.android.widget.menu.CustomPopupMenu; import org.solovyev.android.widget.menu.CustomPopupMenu;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class CalculatorActivity extends BaseActivity implements View.OnClickListener { public class CalculatorActivity extends BaseActivity implements View.OnClickListener {
@Nonnull @Nonnull

View File

@ -2,53 +2,37 @@ package org.solovyev.android.calculator.ga;
import android.app.Application; import android.app.Application;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import com.google.android.gms.analytics.GoogleAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import org.solovyev.android.calculator.Preferences;
import org.solovyev.android.calculator.R;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.solovyev.android.calculator.Preferences;
@Singleton @Singleton
public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListener { public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final int LAYOUT = 1;
private static final int THEME = 2;
@Nonnull @Nonnull
private final GoogleAnalytics analytics; private final FirebaseAnalytics analytics;
@Nonnull
private final Tracker tracker;
@Inject @Inject
public Ga(@Nonnull Application application, @Nonnull SharedPreferences preferences) { public Ga(@Nonnull Application application, @Nonnull SharedPreferences preferences) {
analytics = GoogleAnalytics.getInstance(application); analytics = FirebaseAnalytics.getInstance(application);
tracker = analytics.newTracker(R.xml.ga);
preferences.registerOnSharedPreferenceChangeListener(this); preferences.registerOnSharedPreferenceChangeListener(this);
} }
private void reportLayout(@Nonnull Preferences.Gui.Mode mode) { private void reportLayout(@Nonnull Preferences.Gui.Mode mode) {
tracker.send(new HitBuilders.EventBuilder().setCustomDimension(LAYOUT, mode.name()).build()); final Bundle params = new Bundle();
params.putString("name", mode.name());
analytics.logEvent("layout", params);
} }
private void reportTheme(@Nonnull Preferences.Gui.Theme theme) { private void reportTheme(@Nonnull Preferences.Gui.Theme theme) {
tracker.send(new HitBuilders.EventBuilder().setCustomDimension(THEME, theme.name()).build()); final Bundle params = new Bundle();
} params.putString("name", theme.name());
analytics.logEvent("theme", params);
@Nonnull
public GoogleAnalytics getAnalytics() {
return analytics;
}
@Nonnull
public Tracker getTracker() {
return tracker;
} }
public void onButtonPressed(@Nullable String text) { public void onButtonPressed(@Nullable String text) {
@ -56,11 +40,9 @@ public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListe
return; return;
} }
final HitBuilders.EventBuilder b = new HitBuilders.EventBuilder(); final Bundle params = new Bundle();
b.setCategory("ui"); params.putString("text", text);
b.setAction("click"); analytics.logEvent("click", params);
b.setLabel(text);
tracker.send(b.build());
} }
@Override @Override
@ -78,10 +60,6 @@ public final class Ga implements SharedPreferences.OnSharedPreferenceChangeListe
} }
public void onFloatingCalculatorOpened() { public void onFloatingCalculatorOpened() {
final HitBuilders.EventBuilder b = new HitBuilders.EventBuilder(); analytics.logEvent("floating_calculator_open", null);
b.setCategory("lifecycle");
b.setAction("floating_calculator");
b.setLabel("start");
tracker.send(b.build());
} }
} }

View File

@ -72,18 +72,6 @@ public class PurchaseDialogActivity extends AppCompatActivity implements Request
checkout.createPurchaseFlow(this); checkout.createPurchaseFlow(this);
} }
@Override
protected void onStart() {
super.onStart();
ga.getAnalytics().reportActivityStart(this);
}
@Override
protected void onStop() {
ga.getAnalytics().reportActivityStop(this);
super.onStop();
}
private void purchase() { private void purchase() {
checkout.whenReady(new Checkout.EmptyListener() { checkout.whenReady(new Checkout.EmptyListener() {
@Override @Override

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"
tools:ignore="UnusedResources">
<string name="ga_trackingId">UA-28724009-2</string>
<bool name="ga_reportUncaughtExceptions">true</bool>
<bool name="ga_autoActivityTracking">true</bool>
<string name="ga_sampleFrequency">10.0</string>
</resources>

View File

@ -1,12 +1,11 @@
buildscript { buildscript {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
ext { ext {
versions = [supportLib: "28.0.0", versions = [supportLib: "28.0.0",
gpsLib : "18.2.0",
kotlin : "1.8.20", kotlin : "1.8.20",
sdk : [compile: 33, min: 21, target: 33]] sdk : [compile: 33, min: 21, target: 33]]
} }
@ -14,13 +13,15 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.1.0' classpath 'com.android.tools.build:gradle:8.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
} }
} }
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
flatDir { flatDir {
dirs 'misc/libs' dirs 'misc/libs'