2 * Copyright 2014 Gustavo Martin Morcuende
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package name.gumartinm.weather.information.app;
18 import android.app.Application;
19 import android.content.Context;
20 import android.support.multidex.MultiDex;
22 import com.google.android.gms.analytics.GoogleAnalytics;
23 import com.google.android.gms.analytics.HitBuilders;
24 import com.google.android.gms.analytics.StandardExceptionParser;
25 import com.google.android.gms.analytics.Tracker;
27 import java.util.HashMap;
29 import name.gumartinm.weather.information.BuildConfig;
30 import name.gumartinm.weather.information.R;
31 import timber.log.Timber;
33 public class WeatherInformationApp extends Application {
36 public void onCreate() {
39 if (BuildConfig.DEBUG_MODE) {
40 Timber.plant(new Timber.DebugTree());
42 // Trying to avoid this bug: https://code.google.com/p/android/issues/detail?id=82157
43 // When Google fixes the bug I will be able to rely on the AndroidManifest.xml configuration.
44 final GoogleAnalyticsTrackers analyticsTrackers =
45 new GoogleAnalyticsTrackers(this.getApplicationContext());
46 analyticsTrackers.setGlobalTracker();
48 Timber.plant(new GoogleAnalyticsReportingTree(analyticsTrackers));
53 protected void attachBaseContext(Context base) {
54 super.attachBaseContext(base);
55 MultiDex.install(this);
58 private static class GoogleAnalyticsTrackers {
60 private enum TrackerName {
61 EXCEPTIONS_TRACKER, // Tracker used when logging caught exceptions in this app.
62 GLOBAL_TRACKER, // Tracker used when logging uncaught exception in this app.
65 private final HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();
66 private final Context appContext;
68 private GoogleAnalyticsTrackers(final Context appContext) {
69 this.appContext = appContext;
73 * Trying to avoid this bug: https://code.google.com/p/android/issues/detail?id=82157
74 * When Google fixes the bug I will be able to rely on the AndroidManifest.xml configuration.
76 private void setGlobalTracker() {
77 this.getTracker(TrackerName.GLOBAL_TRACKER);
85 private synchronized Tracker getTracker(final TrackerName trackerId) {
86 if (!mTrackers.containsKey(trackerId)) {
88 final GoogleAnalytics analytics = GoogleAnalytics.getInstance(appContext.getApplicationContext());
90 final Tracker t = (trackerId == TrackerName.EXCEPTIONS_TRACKER) ?
91 analytics.newTracker(R.xml.exceptions_tracker) :
92 (trackerId == TrackerName.GLOBAL_TRACKER) ?
93 analytics.newTracker(R.xml.global_tracker) :
94 analytics.newTracker(R.xml.exceptions_tracker);
96 // Do not retrieve user's information. I strongly care about user's privacy.
97 t.enableAdvertisingIdCollection(false);
99 mTrackers.put(trackerId, t);
101 return mTrackers.get(trackerId);
109 private void send(final Throwable exception, final TrackerName trackerName) {
110 final Tracker tracker = this.getTracker(trackerName);
112 // Build and send exception.
113 tracker.send(new HitBuilders.ExceptionBuilder()
115 new StandardExceptionParser(appContext.getApplicationContext(), null)
116 .getDescription(Thread.currentThread().getName(), exception))
122 private static class GoogleAnalyticsReportingTree extends Timber.HollowTree {
123 private final GoogleAnalyticsTrackers analyticsTrackers;
125 private GoogleAnalyticsReportingTree(final GoogleAnalyticsTrackers analyticsTrackers) {
126 this.analyticsTrackers = analyticsTrackers;
130 public void i(final String message, final Object... args) {
131 // Do nothing, just report exceptions.
135 public void i(final Throwable t, final String message, final Object... args) {
136 i(message, args); // Just add to the log.
140 public void e(final String message, final Object... args) {
141 i("ERROR: " + message, args); // Just add to the log.
145 public void e(final Throwable exception, final String message, final Object... args) {
148 this.analyticsTrackers.send(exception, GoogleAnalyticsTrackers.TrackerName.EXCEPTIONS_TRACKER);