/*
* Copyright (C) 2014-2015 University of South Florida
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.android.io;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import org.onebusaway.android.BuildConfig;
import org.onebusaway.android.R;
import org.onebusaway.android.app.Application;
import org.onebusaway.android.util.RegionUtils;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.location.Location;
import android.support.v4.app.Fragment;
/**
* Analytics class for tracking the app
*
* @author Cagri Cetin
*/
public class ObaAnalytics {
/**
* Users location accuracy should be less then 50f
*/
private static final float LOCATION_ACCURACY_THRESHOLD = 50f;
/**
* Amazon devices manufacturer name
*/
public static final String mAmazonManufacturer = "amazon";
/**
* To measure the distance when the bus stop tapped.
*/
public enum ObaStopDistance {
DISTANCE_1("User Distance: 00000-00050m", 50),
DISTANCE_2("User Distance: 00050-00100m", 100),
DISTANCE_3("User Distance: 00100-00200m", 200),
DISTANCE_4("User Distance: 00200-00400m", 400),
DISTANCE_5("User Distance: 00400-00800m", 800),
DISTANCE_6("User Distance: 00800-01600m", 1600),
DISTANCE_7("User Distance: 01600-03200m", 3200),
DISTANCE_8("User Distance: 03200-INFINITY", 0);
private final String stringValue;
private final int distanceInMeters;
ObaStopDistance(final String s, final int i) {
stringValue = s;
distanceInMeters = i;
}
public String toString() {
return stringValue;
}
public int getDistanceInMeters() {
return distanceInMeters;
}
}
/**
* Event categories for segmentation
* app_settings, ui_action, submit is similar with OBA IOS
*/
public enum ObaEventCategory {
APP_SETTINGS("app_settings"), UI_ACTION("ui_action"),
SUBMIT("submit"), STOP_ACTION("stop_metrics"),
ACCESSIBILITY("accessibility");
private final String stringValue;
ObaEventCategory(final String s) {
stringValue = s;
}
public String toString() {
return stringValue;
}
}
/**
* Reports events with categories. Helps segmentation in GA admin console.
*
* @param category category name
* @param action action name
* @param label label name
*/
public static void reportEventWithCategory(String category, String action, String label) {
if (isAnalyticsActive()) {
Tracker tracker = Application.get().getTracker(Application.TrackerName.APP_TRACKER);
Tracker tracker2 = Application.get().getTracker(Application.TrackerName.GLOBAL_TRACKER);
String obaRegionName = RegionUtils.getObaRegionName();
tracker.send(new HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.setLabel(label)
.setCustomDimension(1, obaRegionName)
.build());
tracker2.send(new HitBuilders.EventBuilder()
.setCategory(category)
.setAction(action)
.setLabel(label)
.setCustomDimension(1, obaRegionName)
.build());
}
}
/**
* Tracks stop tap distance between bus stop location and users current location
*
* @param stopId for action
* @param myLocation the users location
* @param stopLocation tapped stop location
*/
public static void trackBusStopDistance(String stopId, Location myLocation, Location stopLocation) {
if (isAnalyticsActive()) {
if (myLocation == null) {
return;
}
if (myLocation.getAccuracy() < LOCATION_ACCURACY_THRESHOLD) {
float distanceInMeters = myLocation.distanceTo(stopLocation);
ObaStopDistance stopDistance;
if (distanceInMeters < ObaStopDistance.DISTANCE_1.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_1;
} else if (distanceInMeters < ObaStopDistance.DISTANCE_2.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_2;
} else if (distanceInMeters < ObaStopDistance.DISTANCE_3.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_3;
} else if (distanceInMeters < ObaStopDistance.DISTANCE_4.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_4;
} else if (distanceInMeters < ObaStopDistance.DISTANCE_5.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_5;
} else if (distanceInMeters < ObaStopDistance.DISTANCE_6.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_6;
} else if (distanceInMeters < ObaStopDistance.DISTANCE_7.getDistanceInMeters()) {
stopDistance = ObaStopDistance.DISTANCE_7;
} else {
stopDistance = ObaStopDistance.DISTANCE_8;
}
reportEventWithCategory(ObaEventCategory.STOP_ACTION.toString(), "Stop Id: " + stopId,
stopDistance.toString());
}
}
}
/**
* For reporting activities on Start
*
* @param activity The activity being reported
*/
public static void reportActivityStart(Activity activity) {
if (isAnalyticsActive()) {
Tracker tracker = Application.get().getTracker(Application.TrackerName.APP_TRACKER);
tracker.setScreenName(activity.getClass().getSimpleName());
tracker.send(new HitBuilders.ScreenViewBuilder().build());
Tracker tracker2 = Application.get().getTracker(Application.TrackerName.GLOBAL_TRACKER);
tracker2.setScreenName(activity.getClass().getSimpleName());
tracker2.send(new HitBuilders.ScreenViewBuilder().build());
}
}
/**
* For reporting fragments on Start
*
* @param fragment The fragment being reported
*/
public static void reportFragmentStart(Fragment fragment) {
if (isAnalyticsActive()) {
Tracker tracker = Application.get().getTracker(Application.TrackerName.APP_TRACKER);
tracker.setScreenName(fragment.getClass().getSimpleName());
tracker.send(new HitBuilders.ScreenViewBuilder().build());
Tracker tracker2 = Application.get().getTracker(Application.TrackerName.GLOBAL_TRACKER);
tracker2.setScreenName(fragment.getClass().getSimpleName());
tracker2.send(new HitBuilders.ScreenViewBuilder().build());
}
}
public static void initAnalytics(Context context) {
if (BuildConfig.DEBUG) {
//Disables reporting when app runs on debug
GoogleAnalytics.getInstance(context).setDryRun(true);
// Workaround for #243- setDryRun(true) doesn't work on Fire Phone
if (android.os.Build.MANUFACTURER.toLowerCase().contains(mAmazonManufacturer)) {
GoogleAnalytics.getInstance(context).setAppOptOut(true);
}
}
}
/**
* @return is GA enabled or disabled from settings
*/
private static Boolean isAnalyticsActive() {
SharedPreferences settings = Application.getPrefs();
return settings.getBoolean(Application.get().getString(R.string.preferences_key_analytics), Boolean.TRUE);
}
}