├── .gitignore ├── Android.mk ├── NoAnalytics ├── AndroidManifest.xml ├── custom_rules.xml ├── project.properties └── src │ └── com │ └── google │ ├── analytics │ └── tracking │ │ └── android │ │ ├── Analytics.java │ │ ├── CampaignTrackingReceiver.java │ │ ├── CampaignTrackingService.java │ │ ├── EasyTracker.java │ │ ├── ExceptionParser.java │ │ ├── ExceptionReporter.java │ │ ├── Fields.java │ │ ├── GAServiceManager.java │ │ ├── GoogleAnalytics.java │ │ ├── HitTypes.java │ │ ├── Log.java │ │ ├── Logger.java │ │ ├── MapBuilder.java │ │ ├── ServiceManager.java │ │ ├── StandardExceptionParser.java │ │ ├── Tracker.java │ │ ├── TrackerHandler.java │ │ ├── Transaction.java │ │ └── Utils.java │ └── android │ └── apps │ └── analytics │ ├── AdHitIdGenerator.java │ ├── AdMobInfo.java │ ├── AnalyticsParameterEncoder.java │ ├── AnalyticsReceiver.java │ ├── Dispatcher.java │ ├── GoogleAnalyticsTracker.java │ ├── Hit.java │ ├── Item.java │ └── Transaction.java └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | LOCAL_SRC_FILES := $(call all-java-files-under, NoAnalytics/src) 5 | LOCAL_MODULE := libGoogleAnalyticsV2 6 | LOCAL_MODULE_TAGS := optional 7 | LOCAL_MODULE_CLASS := JAVA_LIBRARIES 8 | LOCAL_MODULE_PATH := $(TARGET_OUT)/fake_packages/libGoogleAnalyticsV2.jar 9 | 10 | include $(BUILD_JAVA_LIBRARY) 11 | -------------------------------------------------------------------------------- /NoAnalytics/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /NoAnalytics/custom_rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /NoAnalytics/project.properties: -------------------------------------------------------------------------------- 1 | target=android-16 2 | android.library=true 3 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Analytics.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public interface Analytics { 4 | 5 | public boolean debugEnabled(); 6 | public Tracker getDefaultTracker(); 7 | public Tracker getTracker(String trackingId); 8 | public void requestAppOptOut(Analytics.AppOptOutCallback callback); 9 | public void setAppOptOut(boolean optOut); 10 | public void setDebug(boolean debug); 11 | public void setDefaultTracker(Tracker tracker); 12 | 13 | public static interface AppOptOutCallback { 14 | public void reportAppOptOut(boolean optOut); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/CampaignTrackingReceiver.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | public class CampaignTrackingReceiver extends BroadcastReceiver { 8 | @Override 9 | public void onReceive(Context context, Intent intent) { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/CampaignTrackingService.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.app.IntentService; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | public class CampaignTrackingService extends IntentService { 8 | 9 | private static final String DEFAULT_NAME = "com.google.analytics.tracking.android.CampaignTrackingService"; 10 | 11 | public CampaignTrackingService() { 12 | this(DEFAULT_NAME); 13 | } 14 | 15 | public CampaignTrackingService(String name) { 16 | super(name); 17 | } 18 | 19 | @Override 20 | protected void onHandleIntent(Intent intent) { 21 | } 22 | 23 | public void processIntent(Context context, Intent intent) { 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/EasyTracker.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | 6 | import java.util.Map; 7 | 8 | public class EasyTracker extends Tracker { 9 | private static final String NO_TRACKING_ID = "12345678"; 10 | private static EasyTracker instance; 11 | private Tracker tracker = GoogleAnalytics.getInstance(null).getTracker(NO_TRACKING_ID); 12 | 13 | public static EasyTracker getInstance() { 14 | if (instance == null) 15 | instance = new EasyTracker(); 16 | return instance; 17 | } 18 | 19 | public static EasyTracker getInstance(Context context) { 20 | if (instance == null) 21 | instance = new EasyTracker(); 22 | return instance; 23 | } 24 | 25 | public static Tracker getTracker() { 26 | return getInstance().tracker; 27 | } 28 | 29 | public static void setResourcePackageName(String resourcePackageName) { 30 | 31 | } 32 | 33 | public void activityStart(Activity activity) { 34 | 35 | } 36 | 37 | public void activityStop(Activity activity) { 38 | 39 | } 40 | 41 | public void dispatch() { 42 | 43 | } 44 | 45 | @Deprecated 46 | public void dispatchLocalHits() { 47 | 48 | } 49 | 50 | public void send(Map params) { 51 | 52 | } 53 | 54 | public void setContext(Context ctx) { 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/ExceptionParser.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public interface ExceptionParser { 4 | String getDescription(String threadName, Throwable t); 5 | } 6 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/ExceptionReporter.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.content.Context; 4 | 5 | public class ExceptionReporter implements Thread.UncaughtExceptionHandler { 6 | 7 | private ExceptionParser exceptionParser; 8 | 9 | public ExceptionReporter(Tracker tracker, ServiceManager serviceManager, 10 | Thread.UncaughtExceptionHandler originalHandler, Context context) { 11 | 12 | } 13 | 14 | public ExceptionParser getExceptionParser() { 15 | if (exceptionParser == null) { 16 | exceptionParser = new ExceptionParser() { 17 | @Override 18 | public String getDescription(String threadName, Throwable t) { 19 | return threadName; 20 | } 21 | }; 22 | } 23 | return exceptionParser; 24 | } 25 | 26 | public void setExceptionParser(ExceptionParser exceptionParser) { 27 | this.exceptionParser = exceptionParser; 28 | } 29 | 30 | @Override 31 | public void uncaughtException(Thread thread, Throwable throwable) { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Fields.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public final class Fields { 4 | public static final String ANDROID_APP_UID = "AppUID"; 5 | public static final String ANONYMIZE_IP = "&aip"; 6 | public static final String APP_ID = "&aid"; 7 | public static final String APP_INSTALLER_ID = "&aiid"; 8 | public static final String APP_NAME = "&an"; 9 | public static final String APP_VERSION = "&av"; 10 | public static final String CAMPAIGN_CONTENT = "&cc"; 11 | public static final String CAMPAIGN_ID = "&ci"; 12 | public static final String CAMPAIGN_KEYWORD = "&ck"; 13 | public static final String CAMPAIGN_MEDIUM = "&cm"; 14 | public static final String CAMPAIGN_NAME = "&cn"; 15 | public static final String CAMPAIGN_SOURCE = "&cs"; 16 | public static final String CLIENT_ID = "&cid"; 17 | public static final String CURRENCY_CODE = "&cu"; 18 | public static final String DESCRIPTION = "&cd"; 19 | public static final String ENCODING = "&de"; 20 | public static final String EVENT_ACTION = "&ea"; 21 | public static final String EVENT_CATEGORY = "&ec"; 22 | public static final String EVENT_LABEL = "&el"; 23 | public static final String EVENT_VALUE = "&ev"; 24 | public static final String EX_DESCRIPTION = "&exd"; 25 | public static final String EX_FATAL = "&exf"; 26 | public static final String FLASH_VERSION = "&fl"; 27 | public static final String HIT_TYPE = "&t"; 28 | public static final String HOSTNAME = "&dh"; 29 | public static final String ITEM_CATEGORY = "&iv"; 30 | public static final String ITEM_NAME = "&in"; 31 | public static final String ITEM_PRICE = "&ip"; 32 | public static final String ITEM_QUANTITY = "&iq"; 33 | public static final String ITEM_SKU = "&ic"; 34 | public static final String JAVA_ENABLED = "&je"; 35 | public static final String LANGUAGE = "&ul"; 36 | public static final String LOCATION = "&dl"; 37 | public static final String NON_INTERACTION = "&ni"; 38 | public static final String PAGE = "&dp"; 39 | public static final String REFERRER = "&dr"; 40 | public static final String SAMPLE_RATE = "&sf"; 41 | public static final String SCREEN_COLORS = "&sd"; 42 | public static final String SCREEN_NAME = "&cd"; 43 | public static final String SCREEN_RESOLUTION = "&sr"; 44 | public static final String SESSION_CONTROL = "&sc"; 45 | public static final String SOCIAL_ACTION = "&sa"; 46 | public static final String SOCIAL_NETWORK = "&sn"; 47 | public static final String SOCIAL_TARGET = "&st"; 48 | public static final String TIMING_CATEGORY = "&utc"; 49 | public static final String TIMING_LABEL = "&utl"; 50 | public static final String TIMING_VALUE = "&utt"; 51 | public static final String TIMING_VAR = "&utv"; 52 | public static final String TITLE = "&dt"; 53 | public static final String TRACKING_ID = "&tid"; 54 | public static final String TRANSACTION_AFFILIATION = "&ta"; 55 | public static final String TRANSACTION_ID = "&ti"; 56 | public static final String TRANSACTION_REVENUE = "&tr"; 57 | public static final String TRANSACTION_SHIPPING = "&ts"; 58 | public static final String TRANSACTION_TAX = "&tt"; 59 | public static final String USE_SECURE = "useSecure"; 60 | public static final String VIEWPORT_SIZE = "&vp"; 61 | 62 | public static String contentGroup(int index) { 63 | return null; 64 | } 65 | 66 | public static String customDimension(int index) { 67 | return null; 68 | } 69 | 70 | public static String customMetric(int index) { 71 | return null; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/GAServiceManager.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public class GAServiceManager extends ServiceManager { 4 | 5 | private static GAServiceManager instance; 6 | 7 | public static synchronized GAServiceManager getInstance() { 8 | if (instance == null) { 9 | instance = new GAServiceManager(); 10 | } 11 | return instance; 12 | } 13 | 14 | @Override 15 | public void dispatchLocalHits() { 16 | } 17 | 18 | @Override 19 | public void setForceLocalDispatch() { 20 | } 21 | 22 | @Override 23 | public void setLocalDispatchPeriod(int dispatchPeriodInSeconds) { 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/GoogleAnalytics.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class GoogleAnalytics implements TrackerHandler, Analytics { 10 | private static final String TAG = "GoogleAnalytics"; 11 | 12 | private static GoogleAnalytics instance; 13 | private boolean debug = false; 14 | private boolean dryRun = false; 15 | private Map trackers = new HashMap(); 16 | private Tracker defaultTracker; 17 | private boolean optOut = false; 18 | 19 | private GoogleAnalytics(Context context) { 20 | } 21 | 22 | public static synchronized GoogleAnalytics getInstance(Context context) { 23 | if (instance == null) { 24 | instance = new GoogleAnalytics(context); 25 | } 26 | return instance; 27 | } 28 | 29 | @Override 30 | public void closeTracker(Tracker tracker) { 31 | } 32 | 33 | public void closeTracker(String name) { 34 | 35 | } 36 | 37 | @Override 38 | public boolean debugEnabled() { 39 | return isDebugEnabled(); 40 | } 41 | 42 | public boolean getAppOptOut() { 43 | return optOut; 44 | } 45 | 46 | @Override 47 | public void setAppOptOut(boolean optOut) { 48 | this.optOut = optOut; 49 | } 50 | 51 | @Override 52 | public Tracker getDefaultTracker() { 53 | return defaultTracker; 54 | } 55 | 56 | @Override 57 | public void setDefaultTracker(Tracker tracker) { 58 | defaultTracker = tracker; 59 | } 60 | 61 | @Override 62 | public synchronized Tracker getTracker(String trackingId) { 63 | if (!trackers.containsKey(trackingId)) { 64 | Tracker tracker = new Tracker(trackingId, this); 65 | trackers.put(trackingId, tracker); 66 | if (defaultTracker == null) { 67 | defaultTracker = tracker; 68 | } 69 | } 70 | return trackers.get(trackingId); 71 | } 72 | 73 | public Tracker getTracker(String name, String trackingId) { 74 | if (!trackers.containsKey(trackingId)) { 75 | Tracker tracker = new Tracker(name, trackingId, this); 76 | trackers.put(trackingId, tracker); 77 | if (defaultTracker == null) { 78 | defaultTracker = tracker; 79 | } 80 | } 81 | return trackers.get(trackingId); 82 | } 83 | 84 | public boolean isDebugEnabled() { 85 | return debug; 86 | } 87 | 88 | public boolean isDryRunEnabled() { 89 | return dryRun; 90 | } 91 | 92 | @Override 93 | public void requestAppOptOut(AppOptOutCallback callback) { 94 | } 95 | 96 | @Override 97 | public void sendHit(Map map) { 98 | } 99 | 100 | @Override 101 | public void setDebug(boolean debug) { 102 | this.debug = debug; 103 | } 104 | 105 | public void setDryRun(boolean dryRun) { 106 | this.dryRun = dryRun; 107 | } 108 | 109 | public Logger getLogger() { 110 | return DEFAULT_LOGGER; 111 | } 112 | 113 | public static Logger getDefaultLogger() { 114 | return DEFAULT_LOGGER; 115 | } 116 | 117 | private static Logger DEFAULT_LOGGER = new Logger() { 118 | private LogLevel level = LogLevel.VERBOSE; 119 | 120 | @Override 121 | public void verbose(String message) { 122 | Log.v(TAG, message); 123 | } 124 | 125 | @Override 126 | public void info(String message) { 127 | Log.i(TAG, message); 128 | } 129 | 130 | @Override 131 | public void warn(String message) { 132 | Log.w(TAG, message); 133 | } 134 | 135 | @Override 136 | public void error(String message) { 137 | Log.e(TAG, message); 138 | } 139 | 140 | @Override 141 | public void error(Exception exception) { 142 | Log.e(TAG, exception.toString()); 143 | } 144 | 145 | @Override 146 | public void setLogLevel(LogLevel level) { 147 | this.level = level; 148 | } 149 | 150 | @Override 151 | public LogLevel getLogLevel() { 152 | return level; 153 | } 154 | }; 155 | 156 | } 157 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/HitTypes.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public class HitTypes { 4 | public static final String APP_VIEW = "appview"; 5 | public static final String EVENT = "event"; 6 | public static final String EXCEPTION = "exception"; 7 | public static final String ITEM = "item"; 8 | public static final String SOCIAL = "social"; 9 | public static final String TIMING = "timing"; 10 | public static final String TRANSACTION = "transaction"; 11 | } 12 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Log.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public class Log { 4 | public static void e(String msg) { 5 | GoogleAnalytics.getDefaultLogger().error(msg); 6 | } 7 | 8 | public static void e(Exception e) { 9 | GoogleAnalytics.getDefaultLogger().error(e); 10 | } 11 | 12 | public static void i(String msg) { 13 | GoogleAnalytics.getDefaultLogger().info(msg); 14 | } 15 | 16 | public static void v(String msg) { 17 | GoogleAnalytics.getDefaultLogger().verbose(msg); 18 | } 19 | 20 | public static void w(String msg) { 21 | GoogleAnalytics.getDefaultLogger().warn(msg); 22 | } 23 | 24 | public static boolean isVerbose() { 25 | return GoogleAnalytics.getDefaultLogger().getLogLevel() == Logger.LogLevel.VERBOSE; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Logger.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.util.Log; 4 | 5 | public interface Logger { 6 | public enum LogLevel { 7 | VERBOSE, INFO, WARNING, ERROR 8 | } 9 | void verbose(String message); 10 | void info(String message); 11 | void warn(String message); 12 | void error(String message); 13 | void error(Exception exception); 14 | void setLogLevel(LogLevel level); 15 | LogLevel getLogLevel(); 16 | } 17 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/MapBuilder.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class MapBuilder { 7 | 8 | private Map map = new HashMap(); 9 | 10 | public Map build() { 11 | return map; 12 | } 13 | 14 | public static MapBuilder createAppView() { 15 | return new MapBuilder(); 16 | } 17 | 18 | public static MapBuilder createEvent(String category, String action, String label, 19 | Long value) { 20 | return new MapBuilder(); 21 | } 22 | 23 | public static MapBuilder createException(String exceptionDescription, Boolean fatal) { 24 | return new MapBuilder(); 25 | } 26 | 27 | public static MapBuilder createItem(String transactionId, String name, String sku, 28 | String category, Double price, Long quantity, 29 | String currencyCode) { 30 | return new MapBuilder(); 31 | } 32 | 33 | public static MapBuilder createSocial(String network, String action, String target) { 34 | return new MapBuilder(); 35 | } 36 | 37 | public static MapBuilder createTiming(String category, Long intervalInMilliseconds, 38 | String name, String label) { 39 | return new MapBuilder(); 40 | } 41 | 42 | public static MapBuilder createTransaction(String transactionId, String affiliation, 43 | Double revenue, Double tax, 44 | Double shipping, String currencyCode) { 45 | return new MapBuilder(); 46 | } 47 | 48 | public String get(String paramName) { 49 | return map.get(paramName); 50 | } 51 | 52 | public MapBuilder set(String paramName, String paramValue) { 53 | map.put(paramName, paramValue); 54 | return this; 55 | } 56 | 57 | public MapBuilder setAll(Map params) { 58 | map.putAll(params); 59 | return this; 60 | } 61 | 62 | public MapBuilder setCampaignParamsFromUrl(String utmParams) { 63 | return this; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/ServiceManager.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public abstract class ServiceManager { 4 | @Deprecated 5 | abstract void dispatchLocalHits(); 6 | 7 | @Deprecated 8 | abstract void setForceLocalDispatch(); 9 | 10 | @Deprecated 11 | abstract void setLocalDispatchPeriod(int dispatchPeriodInSeconds); 12 | } 13 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/StandardExceptionParser.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import android.content.Context; 4 | 5 | import java.util.Collection; 6 | 7 | public class StandardExceptionParser implements ExceptionParser { 8 | 9 | public StandardExceptionParser(Context context, Collection additionalPackages) { 10 | 11 | } 12 | 13 | @Override 14 | public String getDescription(String threadName, Throwable t) { 15 | return threadName; 16 | } 17 | 18 | public void setIncludedPackages(Context context, Collection additionalPackages) { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Tracker.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.ObjectOutputStream; 6 | import java.text.DecimalFormat; 7 | import java.text.DecimalFormatSymbols; 8 | import java.util.HashMap; 9 | import java.util.Locale; 10 | import java.util.Map; 11 | 12 | public class Tracker { 13 | private Map map = new HashMap(); 14 | private ExceptionParser exceptionParser; 15 | private TrackerHandler handler; 16 | private String name; 17 | 18 | Tracker() { 19 | 20 | } 21 | 22 | Tracker(String trackingId, TrackerHandler handler) { 23 | map.put("trackingId", trackingId); 24 | map.put("sampleRate", Integer.toString(100)); 25 | map.put("useSecure", Boolean.toString(true)); 26 | this.handler = handler; 27 | } 28 | 29 | Tracker(String name, String trackingId, TrackerHandler handler) { 30 | this(trackingId, handler); 31 | this.name = name; 32 | } 33 | 34 | private static String microsToCurrencyString(long currencyInMicros) { 35 | return new DecimalFormat("0.######", new DecimalFormatSymbols(Locale.US)) 36 | .format((double) currencyInMicros / 1000000D); 37 | } 38 | 39 | public void close() { 40 | if (handler != null) { 41 | handler.closeTracker(this); 42 | } 43 | } 44 | 45 | public Map constructEvent(String category, String action, String label, Long value) { 46 | Map event = new HashMap(); 47 | event.put("eventCategory", category); 48 | event.put("eventAction", action); 49 | event.put("eventLabel", label); 50 | if (value != null) 51 | event.put("eventValue", Long.toString(value.longValue())); 52 | return event; 53 | } 54 | 55 | public Map constructException(String exceptionDescription, boolean fatal) { 56 | Map exception = new HashMap(); 57 | exception.put("exDescription", exceptionDescription); 58 | exception.put("exFatal", Boolean.toString(fatal)); 59 | return exception; 60 | } 61 | 62 | private Map constructItem(Transaction.Item transactionItem, Transaction transaction) { 63 | Map item = new HashMap(); 64 | item.put("transactionId", transaction.getTransactionId()); 65 | item.put("currencyCode", transaction.getCurrencyCode()); 66 | item.put("itemCode", transactionItem.getSKU()); 67 | item.put("itemName", transactionItem.getName()); 68 | item.put("itemCategory", transactionItem.getCategory()); 69 | item.put("itemPrice", microsToCurrencyString(transactionItem.getPriceInMicros())); 70 | item.put("itemQuantity", Long.toString(transactionItem.getQuantity())); 71 | return item; 72 | } 73 | 74 | public Map constructRawException(String threadName, Throwable exception, boolean fatal) 75 | throws IOException { 76 | Map except = new HashMap(); 77 | ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 78 | ObjectOutputStream stream = new ObjectOutputStream(byteStream); 79 | stream.writeObject(exception); 80 | stream.close(); 81 | except.put("rawException", Utils.hexEncode(byteStream.toByteArray())); 82 | if (threadName != null) 83 | except.put("exceptionThreadName", threadName); 84 | except.put("exFatal", Boolean.toString(fatal)); 85 | return except; 86 | } 87 | 88 | public Map constructSocial(String network, String action, String target) { 89 | Map social = new HashMap(); 90 | social.put("socialNetwork", network); 91 | social.put("socialAction", action); 92 | social.put("socialTarget", target); 93 | return social; 94 | } 95 | 96 | public Map constructTiming(String category, long intervalInMilliseconds, String name, 97 | String label) { 98 | Map timing = new HashMap(); 99 | timing.put("timingCategory", category); 100 | timing.put("timingValue", Long.toString(intervalInMilliseconds)); 101 | timing.put("timingVar", name); 102 | timing.put("timingLabel", label); 103 | return timing; 104 | } 105 | 106 | public Map constructTransaction(Transaction transaction) { 107 | Map trans = new HashMap(); 108 | trans.put("transactionId", transaction.getTransactionId()); 109 | trans.put("transactionAffiliation", transaction.getAffiliation()); 110 | trans.put("transactionShipping", microsToCurrencyString(transaction.getShippingCostInMicros())); 111 | trans.put("transactionTax", microsToCurrencyString(transaction.getTotalTaxInMicros())); 112 | trans.put("transactionTotal", microsToCurrencyString(transaction.getTotalCostInMicros())); 113 | trans.put("currencyCode", transaction.getCurrencyCode()); 114 | return trans; 115 | } 116 | 117 | public String get(String key) { 118 | return map.get(key); 119 | } 120 | 121 | public String getAppId() { 122 | return map.get("appId"); 123 | } 124 | 125 | public void setAppId(String appId) { 126 | map.put("appId", appId); 127 | } 128 | 129 | public String getAppInstallerId() { 130 | return map.get("appInstallerId"); 131 | } 132 | 133 | public void setAppInstallerId(String appInstallerId) { 134 | map.put("appInstallerId", appInstallerId); 135 | } 136 | 137 | public ExceptionParser getExceptionParser() { 138 | return exceptionParser; 139 | } 140 | 141 | public void setExceptionParser(ExceptionParser exceptionParser) { 142 | this.exceptionParser = exceptionParser; 143 | } 144 | 145 | public String getName() { 146 | return name; 147 | } 148 | 149 | public double getSampleRate() { 150 | return Utils.safeParseDouble(map.get("sampleRate")); 151 | } 152 | 153 | public void setSampleRate(double sampleRate) { 154 | map.put("sampleRate", Double.toString(sampleRate)); 155 | } 156 | 157 | public String getTrackingId() { 158 | return map.get("trackingId"); 159 | } 160 | 161 | private void internalSend(String hitType, Map params) { 162 | if (params != null) { 163 | map.putAll(params); 164 | } 165 | map.put("hitType", hitType); 166 | 167 | // Clone the map 168 | Map map = new HashMap(); 169 | map.putAll(this.map); 170 | if (handler != null) { 171 | handler.sendHit(map); 172 | } 173 | } 174 | 175 | public boolean isAnonymizeIpEnabled() { 176 | return Utils.safeParseBoolean(map.get("anonymizeIp")); 177 | } 178 | 179 | public boolean isUseSecure() { 180 | return Utils.safeParseBoolean(map.get("anonymizeIp")); 181 | } 182 | 183 | public void setUseSecure(boolean useSecure) { 184 | map.put("useSecure", Boolean.toString(useSecure)); 185 | } 186 | 187 | public void send(String hitType, Map params) { 188 | internalSend(hitType, params); 189 | } 190 | 191 | public void send(Map params) { 192 | 193 | } 194 | 195 | public void sendEvent(String category, String action, String label, Long value) { 196 | internalSend("event", constructEvent(category, action, label, value)); 197 | } 198 | 199 | public void sendException(String description, boolean fatal) { 200 | internalSend("exception", constructException(description, fatal)); 201 | } 202 | 203 | public void sendException(String threadName, Throwable exception, boolean fatal) { 204 | if (exceptionParser != null) { 205 | sendException(exceptionParser.getDescription(threadName, exception), fatal); 206 | } else { 207 | try { 208 | internalSend("exception", constructRawException(threadName, exception, fatal)); 209 | } catch (IOException e) { 210 | sendException("Unknown Exception", fatal); 211 | } 212 | } 213 | } 214 | 215 | public void sendSocial(String network, String action, String target) { 216 | internalSend("social", constructSocial(network, action, target)); 217 | } 218 | 219 | public void sendTiming(String category, long intervalInMilliseconds, String name, String label) { 220 | internalSend("timing", constructTiming(category, intervalInMilliseconds, name, label)); 221 | } 222 | 223 | public void sendTransaction(Transaction transaction) { 224 | internalSend("tran", constructTransaction(transaction)); 225 | for (Transaction.Item item : transaction.getItems()) { 226 | internalSend("item", constructItem(item, transaction)); 227 | } 228 | } 229 | 230 | public void sendView() { 231 | internalSend("appview", null); 232 | } 233 | 234 | public void sendView(String appScreen) { 235 | setAppScreen(appScreen); 236 | internalSend("appview", null); 237 | } 238 | 239 | public void set(String key, String value) { 240 | map.put(key, value); 241 | } 242 | 243 | public void setAnonymizeIp(boolean anonymizeIp) { 244 | map.put("anonymizeIp", Boolean.toString(anonymizeIp)); 245 | } 246 | 247 | public void setAppName(String appName) { 248 | map.put("appName", appName); 249 | } 250 | 251 | public void setAppScreen(String appScreen) { 252 | map.put("description", appScreen); 253 | } 254 | 255 | public void setAppVersion(String appVersion) { 256 | map.put("appVersion", appVersion); 257 | } 258 | 259 | public void setCampaign(String campaign) { 260 | map.put("campaign", campaign); 261 | } 262 | 263 | public void setCustomDimension(int index, String value) { 264 | 265 | } 266 | 267 | public void setCustomDimensionsAndMetrics(Map dimensions, Map metrics) { 268 | 269 | } 270 | 271 | public void setCustomMetric(int index, Long value) { 272 | 273 | } 274 | 275 | public void setReferrer(String referrer) { 276 | map.put("referrer", referrer); 277 | } 278 | 279 | public void setStartSession(boolean startSession) { 280 | 281 | } 282 | 283 | public void setThrottlingEnabled(boolean throttlingEnabled) { 284 | 285 | } 286 | 287 | @Deprecated 288 | public void trackEvent(String category, String action, String label, Long value) { 289 | sendEvent(category, action, label, value); 290 | } 291 | 292 | @Deprecated 293 | public void trackException(String description, boolean fatal) { 294 | sendException(description, fatal); 295 | } 296 | 297 | @Deprecated 298 | public void trackException(String threadName, Throwable exception, boolean fatal) { 299 | sendException(threadName, exception, fatal); 300 | } 301 | 302 | @Deprecated 303 | public void trackSocial(String network, String action, String target) { 304 | sendSocial(network, action, target); 305 | } 306 | 307 | @Deprecated 308 | public void trackTiming(String category, long intervalInMilliseconds, String name, String label) { 309 | sendTiming(category, intervalInMilliseconds, name, label); 310 | } 311 | 312 | @Deprecated 313 | public void trackTransaction(Transaction transaction) { 314 | sendTransaction(transaction); 315 | } 316 | 317 | @Deprecated 318 | public void trackView() { 319 | sendView(); 320 | } 321 | 322 | @Deprecated 323 | public void trackView(String appScreen) { 324 | sendView(appScreen); 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/TrackerHandler.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | import java.util.Map; 4 | 5 | interface TrackerHandler { 6 | public void closeTracker(Tracker tracker); 7 | 8 | public void sendHit(Map map); 9 | } 10 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Transaction.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public final class Transaction { 10 | private final String transactionId; 11 | private final String affiliation; 12 | private final long totalCostInMicros; 13 | private final long totalTaxInMicros; 14 | private final long shippingCostInMicros; 15 | private final String currencyCode; 16 | private final Map items; 17 | 18 | private Transaction(Builder builder) { 19 | transactionId = builder.transactionId; 20 | totalCostInMicros = builder.totalCostInMicros; 21 | affiliation = builder.affiliation; 22 | totalTaxInMicros = builder.totalTaxInMicros; 23 | shippingCostInMicros = builder.shippingCostInMicros; 24 | currencyCode = builder.currencyCode; 25 | items = new HashMap(); 26 | } 27 | 28 | public String getTransactionId() { 29 | return transactionId; 30 | } 31 | 32 | public String getAffiliation() { 33 | return affiliation; 34 | } 35 | 36 | public long getTotalCostInMicros() { 37 | return totalCostInMicros; 38 | } 39 | 40 | public long getTotalTaxInMicros() { 41 | return totalTaxInMicros; 42 | } 43 | 44 | public long getShippingCostInMicros() { 45 | return shippingCostInMicros; 46 | } 47 | 48 | public String getCurrencyCode() { 49 | return currencyCode; 50 | } 51 | 52 | public void addItem(Item item) { 53 | items.put(item.getSKU(), item); 54 | } 55 | 56 | public List getItems() { 57 | return new ArrayList(items.values()); 58 | } 59 | 60 | public static final class Item { 61 | private final String SKU; 62 | private final String name; 63 | private final String category; 64 | private final long priceInMicros; 65 | private final long quantity; 66 | 67 | private Item(Builder builder) { 68 | SKU = builder.SKU; 69 | priceInMicros = builder.priceInMicros; 70 | quantity = builder.quantity; 71 | name = builder.name; 72 | category = builder.category; 73 | } 74 | 75 | public String getSKU() { 76 | return SKU; 77 | } 78 | 79 | public String getName() { 80 | return name; 81 | } 82 | 83 | public String getCategory() { 84 | return category; 85 | } 86 | 87 | public long getPriceInMicros() { 88 | return priceInMicros; 89 | } 90 | 91 | public long getQuantity() { 92 | return quantity; 93 | } 94 | 95 | public static final class Builder { 96 | 97 | private final String SKU; 98 | private final long priceInMicros; 99 | private final long quantity; 100 | private final String name; 101 | private String category; 102 | 103 | public Builder(String SKU, String name, long priceInMicros, long quantity) { 104 | category = null; 105 | this.SKU = SKU; 106 | this.name = name; 107 | this.priceInMicros = priceInMicros; 108 | this.quantity = quantity; 109 | } 110 | 111 | public Builder setProductCategory(String productCategory) { 112 | category = productCategory; 113 | return this; 114 | } 115 | 116 | public Item build() { 117 | return new Item(this); 118 | } 119 | } 120 | 121 | } 122 | 123 | public static final class Builder { 124 | 125 | private final String transactionId; 126 | private final long totalCostInMicros; 127 | private String affiliation; 128 | private long totalTaxInMicros; 129 | private long shippingCostInMicros; 130 | private String currencyCode; 131 | 132 | public Builder(String transactionId, long totalCostInMicros) { 133 | affiliation = null; 134 | totalTaxInMicros = 0L; 135 | shippingCostInMicros = 0L; 136 | currencyCode = null; 137 | this.transactionId = transactionId; 138 | this.totalCostInMicros = totalCostInMicros; 139 | } 140 | 141 | public Builder setAffiliation(String affiliation) { 142 | this.affiliation = affiliation; 143 | return this; 144 | } 145 | 146 | public Builder setTotalTaxInMicros(long totalTaxInMicros) { 147 | this.totalTaxInMicros = totalTaxInMicros; 148 | return this; 149 | } 150 | 151 | public Builder setShippingCostInMicros(long shippingCostInMicros) { 152 | this.shippingCostInMicros = shippingCostInMicros; 153 | return this; 154 | } 155 | 156 | public Builder setCurrencyCode(String currencyCode) { 157 | this.currencyCode = currencyCode; 158 | return this; 159 | } 160 | 161 | public Transaction build() { 162 | return new Transaction(this); 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/analytics/tracking/android/Utils.java: -------------------------------------------------------------------------------- 1 | package com.google.analytics.tracking.android; 2 | 3 | public class Utils { 4 | private static final char HEXBYTES[] = 5 | {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 6 | 7 | public static String hexEncode(byte[] bytes) { 8 | char out[] = new char[bytes.length * 2]; 9 | for (int i = 0; i < bytes.length; i++) { 10 | int b = bytes[i] & 0xff; 11 | out[2 * i] = HEXBYTES[b >> 4]; 12 | out[2 * i + 1] = HEXBYTES[b & 0xf]; 13 | } 14 | 15 | return new String(out); 16 | } 17 | 18 | public static boolean safeParseBoolean(String s) { 19 | if (s == null) { 20 | return false; 21 | } else { 22 | return Boolean.parseBoolean(s); 23 | } 24 | } 25 | 26 | public static double safeParseDouble(String s) { 27 | if (s == null) { 28 | return 0; 29 | } 30 | try { 31 | return Double.parseDouble(s); 32 | } catch (NumberFormatException e) { 33 | return 0; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/AdHitIdGenerator.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | public class AdHitIdGenerator { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/AdMobInfo.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | import java.util.Random; 4 | 5 | public class AdMobInfo { 6 | public static AdMobInfo getInstance() { 7 | return instance; 8 | } 9 | 10 | public String getJoinId() { 11 | return null; 12 | } 13 | 14 | public int generateAdHitId() { 15 | adHitId = random.nextInt(); 16 | return getAdHitId(); 17 | } 18 | 19 | public void setAdHidId(int i) { 20 | adHitId = i; 21 | } 22 | 23 | public int getAdHitId() { 24 | return adHitId; 25 | } 26 | 27 | private int adHitId = generateAdHitId(); 28 | private Random random = new Random(); 29 | private static final AdMobInfo instance = new AdMobInfo(); 30 | } 31 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/AnalyticsParameterEncoder.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | 6 | public class AnalyticsParameterEncoder { 7 | public static String encode(String s) { 8 | return encode(s, "UTF-8"); 9 | } 10 | 11 | static String encode(String s, String charset) { 12 | try { 13 | return URLEncoder.encode(s, charset).replace("+", "%20"); 14 | } catch (UnsupportedEncodingException e) { 15 | throw new AssertionError((new StringBuilder()) 16 | .append("URL encoding failed for: ").append(s).toString()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/AnalyticsReceiver.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | public class AnalyticsReceiver extends BroadcastReceiver { 8 | 9 | @Override 10 | public void onReceive(Context arg0, Intent arg1) { 11 | // NOTHING 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/Dispatcher.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | interface Dispatcher { 4 | public static interface Callbacks { 5 | 6 | public abstract void hitDispatched(long l); 7 | 8 | public abstract void dispatchFinished(); 9 | } 10 | 11 | public abstract void dispatchHits(Hit ahit[]); 12 | 13 | public abstract void init(Callbacks callbacks); 14 | 15 | public abstract void stop(); 16 | 17 | public abstract void setDryRun(boolean flag); 18 | 19 | public abstract boolean isDryRun(); 20 | } -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/GoogleAnalyticsTracker.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | import android.content.Context; 4 | 5 | public class GoogleAnalyticsTracker { 6 | public static final String PRODUCT = "GoogleAnalytics"; 7 | public static final String VERSION = "1.4.2"; 8 | public static final String WIRE_VERSION = "4.8.1ma"; 9 | public static final String LOG_TAG = "GoogleAnalyticsTracker"; 10 | private static GoogleAnalyticsTracker instance = new GoogleAnalyticsTracker(); 11 | private boolean dryRun = true; 12 | private boolean debug = false; 13 | private boolean anonymizeIp = false; 14 | private int sampleRate = 100; 15 | 16 | public static GoogleAnalyticsTracker getInstance() { 17 | return instance; 18 | } 19 | 20 | public void start(String s, int i, Context context) { 21 | // NOTHING 22 | } 23 | 24 | public void startNewSession(String s, int i, Context context) { 25 | // NOTHING 26 | } 27 | 28 | public void start(String s, Context context) { 29 | // NOTHING 30 | } 31 | 32 | public void startNewSession(String s, Context context) { 33 | // NOTHING 34 | } 35 | 36 | public void setProductVersion(String userAgentProduct, 37 | String userAgentVersion) { 38 | } 39 | 40 | public void trackEvent(String category, String action, String s2, int i) { 41 | // NOTHING 42 | } 43 | 44 | public void trackPageView(String s) { 45 | // NOTHING 46 | } 47 | 48 | public void setDispatchPeriod(int i) { 49 | // NOTHING 50 | } 51 | 52 | public void stopSession() { 53 | // NOTHING 54 | } 55 | 56 | public void stop() { 57 | // NOTHING 58 | } 59 | 60 | public boolean setCustomVar(int i, String s, String s1, int j) { 61 | return true; 62 | } 63 | 64 | public boolean setCustomVar(int i, String s, String s1) { 65 | return true; 66 | } 67 | 68 | public String getVisitorCustomVar(int i) { 69 | return null; 70 | } 71 | 72 | public boolean dispatch() { 73 | return false; 74 | } 75 | 76 | public void addTransaction(Transaction transaction) { 77 | // NOTHING 78 | } 79 | 80 | public void addItem(Item item) { 81 | // NOTHING 82 | } 83 | 84 | public void trackTransactions() { 85 | // NOTHING 86 | } 87 | 88 | public void clearTransactions() { 89 | // NOTHING 90 | } 91 | 92 | public void setAnonymizeIp(boolean flag) { 93 | anonymizeIp = flag; 94 | } 95 | 96 | public boolean getAnonymizeIp() { 97 | return anonymizeIp; 98 | } 99 | 100 | public void setUseServerTime(boolean flag) { 101 | } 102 | 103 | public void setSampleRate(int i) { 104 | sampleRate = i; 105 | } 106 | 107 | public int getSampleRate() { 108 | return sampleRate; 109 | } 110 | 111 | public boolean setReferrer(String s) { 112 | return true; 113 | } 114 | 115 | public void setDebug(boolean flag) { 116 | debug = flag; 117 | } 118 | 119 | public boolean getDebug() { 120 | return debug; 121 | } 122 | 123 | public void setDryRun(boolean flag) { 124 | dryRun = flag; 125 | } 126 | 127 | public boolean isDryRun() { 128 | return dryRun; 129 | } 130 | 131 | public boolean setDispatcher(Dispatcher dispatcher) { 132 | return true; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/Hit.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | public class Hit { 4 | Hit(String hitString, long hitId) { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/Item.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | public class Item { 4 | 5 | public static class Builder { 6 | public Builder(String orderId, String itemSKU, double itemPrice, 7 | long itemCount) { 8 | 9 | } 10 | 11 | public Builder setItemName(String s) { 12 | return this; 13 | } 14 | 15 | public Builder setItemCategory(String s) { 16 | return this; 17 | } 18 | 19 | public Item build() { 20 | return new Item(); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /NoAnalytics/src/com/google/android/apps/analytics/Transaction.java: -------------------------------------------------------------------------------- 1 | package com.google.android.apps.analytics; 2 | 3 | public class Transaction { 4 | 5 | public static class Builder { 6 | public Builder(String orderId, double totalCost) { 7 | } 8 | 9 | public Builder setStoreName(String s) { 10 | return this; 11 | } 12 | 13 | public Builder setTotalTax(double d) { 14 | return this; 15 | } 16 | 17 | public Builder setShippingCost(double d) { 18 | return this; 19 | } 20 | 21 | public Transaction build() { 22 | return new Transaction(); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NoAnalytics 2 | =========== 3 | 4 | Clone of GoogleAnalytics for Android that does nothing - use as replacement in open source apps to make them free. 5 | 6 | Usage 7 | ----- 8 | 9 | ###To build CyanogenMod 10 | Once android_external_google is removed from CyanogenMod, it is no longer possible to build the Settings app. Luckily you can add NoAnalytics to your build system to fix this: 11 | 12 | 13 | 14 | 15 | ###General Purpose 16 | Replace "libGoogleAnalytics.jar" (or whatever it's named) with the binary "noAnalytics-0.*.jar" (or a self-compiled version) and recompile the Application. 17 | 18 | ###License 19 | > Copyright 2012-2014 μg Project Team 20 | 21 | > Licensed under the Apache License, Version 2.0 (the "License"); 22 | > you may not use this file except in compliance with the License. 23 | > You may obtain a copy of the License at 24 | 25 | > http://www.apache.org/licenses/LICENSE-2.0 26 | 27 | > Unless required by applicable law or agreed to in writing, software 28 | > distributed under the License is distributed on an "AS IS" BASIS, 29 | > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 30 | > See the License for the specific language governing permissions and 31 | > limitations under the License. 32 | --------------------------------------------------------------------------------