From bbba2469d169403497fd5d366cbf2ffc23682fce Mon Sep 17 00:00:00 2001 From: Hossain Khan Date: Fri, 28 Oct 2016 22:32:01 -0400 Subject: [PATCH 1/2] [ADDED] [#4] Headline selected and error analytics events. --- .../android/core/CoreApplication.java | 15 +++++ .../core/analytics/AnalyticsReporter.java | 59 +++++++++++++++++++ .../core/headlines/HeadlinesPresenter.java | 1 + .../CardItemViewInteractionListener.java | 3 + 4 files changed, 78 insertions(+) create mode 100644 core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java diff --git a/core-lib/src/main/java/info/hossainkhan/android/core/CoreApplication.java b/core-lib/src/main/java/info/hossainkhan/android/core/CoreApplication.java index f7af814..c67dcd8 100644 --- a/core-lib/src/main/java/info/hossainkhan/android/core/CoreApplication.java +++ b/core-lib/src/main/java/info/hossainkhan/android/core/CoreApplication.java @@ -27,8 +27,10 @@ import android.app.Application; import android.content.Context; +import com.google.firebase.analytics.FirebaseAnalytics; import com.squareup.leakcanary.LeakCanary; +import info.hossainkhan.android.core.analytics.AnalyticsReporter; import info.hossainkhan.android.core.dagger.components.AppComponent; import info.hossainkhan.android.core.dagger.components.DaggerAppComponent; import info.hossainkhan.android.core.dagger.modules.InteractorsModule; @@ -43,11 +45,16 @@ public class CoreApplication extends Application { private static AppComponent sAppComponent; private static final boolean ENABLE_LOGGING = true; + private static CoreApplication sContext; + private static AnalyticsReporter sAnalyticsReporter; @Override public void onCreate() { super.onCreate(); + sContext = this; + sAnalyticsReporter = new AnalyticsReporter(FirebaseAnalytics.getInstance(sContext)); + initLeakCanary(); initAppComponent(); initLogger(); @@ -95,4 +102,12 @@ public static AppComponent getAppComponent() { public static CoreApplication getCoreApplication(final Context context) { return (CoreApplication) context.getApplicationContext(); } + + /** + * Provides application analytics reporter. + * @return analytics reporter instance. + */ + public static AnalyticsReporter getAnalyticsReporter() { + return sAnalyticsReporter; + } } diff --git a/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java b/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java new file mode 100644 index 0000000..2489964 --- /dev/null +++ b/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2016 Hossain Khan + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package info.hossainkhan.android.core.analytics; + +import android.os.Bundle; + +import com.google.firebase.analytics.FirebaseAnalytics; + +import info.hossainkhan.android.core.model.CardItem; + +public class AnalyticsReporter { + + private static final String EVENT_NAME_HEADLINE_LOADING_ERROR = "headline_load_failed"; + + private FirebaseAnalytics mAnalytics; + + /** + * Creates analytics reporter with firebase backend reporting. + * @param analytics Firebase analytics instance. + */ + public AnalyticsReporter(FirebaseAnalytics analytics) { + mAnalytics = analytics; + } + + + public void reportHeadlineSelectedEvent(final CardItem card) { + Bundle bundle = new Bundle(); + bundle.putString(FirebaseAnalytics.Param.ITEM_ID, card.contentUrl()); + bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, card.title()); + bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, card.category()); + mAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_CONTENT, bundle); + } + + public void reportHeadlineLoadingError() { + mAnalytics.logEvent(EVENT_NAME_HEADLINE_LOADING_ERROR, null); + } +} diff --git a/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java b/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java index 74378a2..3e8cb84 100644 --- a/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java +++ b/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java @@ -122,6 +122,7 @@ public void onError(Throwable e) { getView().toggleLoadingIndicator(false); getView().showDataLoadingError(); + CoreApplication.getAnalyticsReporter().reportHeadlineLoadingError(); FirebaseCrash.report(e); } diff --git a/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java b/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java index f4a28dd..ba81f6c 100644 --- a/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java +++ b/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java @@ -32,6 +32,7 @@ import java.lang.ref.WeakReference; +import info.hossainkhan.android.core.CoreApplication; import info.hossainkhan.android.core.headlines.HeadlinesContract; import info.hossainkhan.android.core.model.CardItem; import timber.log.Timber; @@ -51,6 +52,8 @@ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, Timber.d("onItemClicked: %s", item); final CardItem card = (CardItem) item; + CoreApplication.getAnalyticsReporter().reportHeadlineSelectedEvent(card); + HeadlinesContract.Presenter presenter = mHeadlinesPresenterRef.get(); if(presenter != null) { presenter.onHeadlineItemClicked(card); From 67b44b866b3fb5cfd192b6697e9a96de4d79990d Mon Sep 17 00:00:00 2001 From: Hossain Khan Date: Fri, 28 Oct 2016 22:55:47 -0400 Subject: [PATCH 2/2] [ADDED] [#4] More analytics events. --- .../core/analytics/AnalyticsReporter.java | 17 +++++++++++++++++ .../core/headlines/HeadlinesPresenter.java | 3 +++ .../CardItemViewInteractionListener.java | 3 --- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java b/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java index 2489964..dc9e8d5 100644 --- a/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java +++ b/core-lib/src/main/java/info/hossainkhan/android/core/analytics/AnalyticsReporter.java @@ -33,6 +33,8 @@ public class AnalyticsReporter { private static final String EVENT_NAME_HEADLINE_LOADING_ERROR = "headline_load_failed"; + private static final String EVENT_NAME_HEADLINE_DETAILS_LOAD = "details_content"; + private static final String EVENT_NAME_SETTINGS_LOAD = "application_settings"; private FirebaseAnalytics mAnalytics; @@ -56,4 +58,19 @@ public void reportHeadlineSelectedEvent(final CardItem card) { public void reportHeadlineLoadingError() { mAnalytics.logEvent(EVENT_NAME_HEADLINE_LOADING_ERROR, null); } + + public void reportHeadlineDetailsLoadedEvent(CardItem card) { + Bundle bundle = new Bundle(); + bundle.putString(FirebaseAnalytics.Param.ITEM_ID, card.contentUrl()); + bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, card.title()); + bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, card.category()); + mAnalytics.logEvent(EVENT_NAME_HEADLINE_DETAILS_LOAD, bundle); + } + + public void reportSettingsScreenLoadedEvent(String settingsName) { + Bundle bundle = new Bundle(); + bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, settingsName); + bundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY, "app_settings"); + mAnalytics.logEvent(EVENT_NAME_SETTINGS_LOAD, bundle); + } } diff --git a/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java b/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java index 3e8cb84..6486f9f 100644 --- a/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java +++ b/core-lib/src/main/java/info/hossainkhan/android/core/headlines/HeadlinesPresenter.java @@ -182,6 +182,7 @@ public void openHeadlineDetails(@NonNull final CardItem cardItem) { @Override public void onHeadlineItemSelected(@NonNull final CardItem cardItem) { + CoreApplication.getAnalyticsReporter().reportHeadlineSelectedEvent(cardItem); if (cardItem.imageUrl() !=null) { getView().showHeadlineBackdropBackground(cardItem.getImageURI()); } else { @@ -195,11 +196,13 @@ public void onHeadlineItemClicked(@NonNull final CardItem cardItem) { CardItem.Type type = cardItem.type(); if (type == CardItem.Type.ICON) { if (id == R.string.settings_card_item_news_source_title) { + CoreApplication.getAnalyticsReporter().reportSettingsScreenLoadedEvent(mContext.getString(R.string.settings_card_item_news_source_title)); getView().showAppSettingsScreen(); } else { Timber.w("Unable to handle settings item: %s", cardItem.title()); } } else if(type == CardItem.Type.HEADLINES) { + CoreApplication.getAnalyticsReporter().reportHeadlineDetailsLoadedEvent(cardItem); getView().showHeadlineDetailsUi(cardItem); } } diff --git a/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java b/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java index ba81f6c..f4a28dd 100644 --- a/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java +++ b/tv/src/main/java/info/hossainkhan/dailynewsheadlines/browser/listeners/CardItemViewInteractionListener.java @@ -32,7 +32,6 @@ import java.lang.ref.WeakReference; -import info.hossainkhan.android.core.CoreApplication; import info.hossainkhan.android.core.headlines.HeadlinesContract; import info.hossainkhan.android.core.model.CardItem; import timber.log.Timber; @@ -52,8 +51,6 @@ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, Timber.d("onItemClicked: %s", item); final CardItem card = (CardItem) item; - CoreApplication.getAnalyticsReporter().reportHeadlineSelectedEvent(card); - HeadlinesContract.Presenter presenter = mHeadlinesPresenterRef.get(); if(presenter != null) { presenter.onHeadlineItemClicked(card);