f076ad384e266fac8358295c84a280b8e1a33dec
[AndroidWeatherInformation] / app / src / main / java / name / gumartinm / weather / information / app / WeatherInformationApp.java
1 /**
2  * Copyright 2014 Gustavo Martin Morcuende
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package name.gumartinm.weather.information.app;
17
18 import android.app.Application;
19 import android.content.Context;
20 import android.support.multidex.MultiDex;
21
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;
26
27 import java.util.HashMap;
28
29 import name.gumartinm.weather.information.BuildConfig;
30 import name.gumartinm.weather.information.R;
31 import timber.log.Timber;
32
33 public class WeatherInformationApp extends Application {
34
35     @Override
36     public void onCreate() {
37         super.onCreate();
38
39         if (BuildConfig.DEBUG_MODE) {
40             Timber.plant(new Timber.DebugTree());
41         } else {
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();
47
48             Timber.plant(new GoogleAnalyticsReportingTree(analyticsTrackers));
49         }
50     }
51
52     @Override
53     protected void attachBaseContext(Context base) {
54         super.attachBaseContext(base);
55         MultiDex.install(this);
56     }
57
58     private static class GoogleAnalyticsTrackers {
59
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.
63         };
64
65         private final HashMap<TrackerName, Tracker> mTrackers = new HashMap<TrackerName, Tracker>();
66         private final Context appContext;
67
68         private GoogleAnalyticsTrackers(final Context appContext) {
69             this.appContext = appContext;
70         }
71
72         /**
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.
75          */
76         private void setGlobalTracker() {
77             this.getTracker(TrackerName.GLOBAL_TRACKER);
78         }
79
80         /**
81          * Get tracker
82          * @param trackerId
83          * @return Tracker
84          */
85         private synchronized Tracker getTracker(final TrackerName trackerId) {
86             if (!mTrackers.containsKey(trackerId)) {
87
88                 final GoogleAnalytics analytics = GoogleAnalytics.getInstance(appContext.getApplicationContext());
89
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);
95
96                 // Do not retrieve user's information. I strongly care about user's privacy.
97                 t.enableAdvertisingIdCollection(false);
98
99                 mTrackers.put(trackerId, t);
100             }
101             return mTrackers.get(trackerId);
102         }
103
104         /**
105          * Send exception
106          * @param exception
107          * @param trackerName
108          */
109         private void send(final Throwable exception, final TrackerName trackerName) {
110             final Tracker tracker = this.getTracker(trackerName);
111
112             // Build and send exception.
113             tracker.send(new HitBuilders.ExceptionBuilder()
114                     .setDescription(
115                             new StandardExceptionParser(appContext.getApplicationContext(), null)
116                                     .getDescription(Thread.currentThread().getName(), exception))
117                     .setFatal(false)
118                     .build());
119         }
120     }
121
122     private static class GoogleAnalyticsReportingTree extends Timber.HollowTree {
123         private final GoogleAnalyticsTrackers analyticsTrackers;
124
125         private GoogleAnalyticsReportingTree(final GoogleAnalyticsTrackers analyticsTrackers) {
126             this.analyticsTrackers = analyticsTrackers;
127         }
128
129         @Override
130         public void i(final String message, final Object... args) {
131             // Do nothing, just report exceptions.
132         }
133
134         @Override
135         public void i(final Throwable t, final String message, final Object... args) {
136             i(message, args); // Just add to the log.
137         }
138
139         @Override
140         public void e(final String message, final Object... args) {
141             i("ERROR: " + message, args); // Just add to the log.
142         }
143
144         @Override
145         public void e(final Throwable exception, final String message, final Object... args) {
146             e(message, args);
147
148             this.analyticsTrackers.send(exception, GoogleAnalyticsTrackers.TrackerName.EXCEPTIONS_TRACKER);
149         }
150     }
151 }