diff --git a/source/Plugins/GoogleAnalyticsV4/Fields.cs b/source/Plugins/GoogleAnalyticsV4/Fields.cs index 4d3a419..2e44a4f 100644 --- a/source/Plugins/GoogleAnalyticsV4/Fields.cs +++ b/source/Plugins/GoogleAnalyticsV4/Fields.cs @@ -40,6 +40,7 @@ public class Fields { public readonly static Field SCREEN_COLORS = new Field("&sd"); public readonly static Field SCREEN_RESOLUTION = new Field("&sr"); public readonly static Field VIEWPORT_SIZE = new Field("&vp"); + public readonly static Field USER_AGENT_OVERRIDE = new Field("&ua"); // Application public readonly static Field APP_NAME = new Field("&an"); diff --git a/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsAndroidV4.cs b/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsAndroidV4.cs index 99bad10..7ee2b22 100644 --- a/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsAndroidV4.cs +++ b/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsAndroidV4.cs @@ -90,6 +90,16 @@ internal void LogScreen (AppViewHitBuilder builder) { tracker.Call("setScreenName", builder.GetScreenName()); AndroidJavaObject eventBuilder = new AndroidJavaObject("com.google.android.gms.analytics.HitBuilders$ScreenViewBuilder"); + + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + eventBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + eventBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + object[] builtScreenView = new object[] { eventBuilder.Call("build") }; tracker.Call("send", builtScreenView); } @@ -100,6 +110,16 @@ internal void LogEvent(EventHitBuilder builder) { eventBuilder.Call("setAction", new object[] { builder.GetEventAction() }); eventBuilder.Call("setLabel", new object[] { builder.GetEventLabel() }); eventBuilder.Call("setValue", new object[] { builder.GetEventValue() }); + + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + eventBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + eventBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + object[] builtEvent = new object[] { eventBuilder.Call("build") }; tracker.Call("send", builtEvent); } @@ -113,6 +133,15 @@ internal void LogTransaction(TransactionHitBuilder builder) { transactionBuilder.Call("setShipping", new object[] { builder.GetShipping() }); transactionBuilder.Call("setCurrencyCode", new object[] { builder.GetCurrencyCode() }); + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + transactionBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + transactionBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + object[] builtTransaction = new object[] { transactionBuilder.Call("build") }; tracker.Call("send", builtTransaction); } @@ -127,17 +156,74 @@ internal void LogItem(ItemHitBuilder builder) { itemBuilder.Call("setQuantity", new object[] { builder.GetQuantity() }); itemBuilder.Call("setCurrencyCode", new object[] { builder.GetCurrencyCode() }); + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + itemBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + itemBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + object[] builtItem = new object[] { itemBuilder.Call("build") }; tracker.Call("send", builtItem); } public void LogException(ExceptionHitBuilder builder) { + AndroidJavaObject exceptionBuilder = new AndroidJavaObject("com.google.android.gms.analytics.HitBuilders$ExceptionBuilder"); + exceptionBuilder.Call("setDescription", new object[] { builder.GetExceptionDescription() }); + exceptionBuilder.Call("setFatal", new object[] { builder.IsFatal() }); + + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + exceptionBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + exceptionBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + + object[] builtException = new object[] { exceptionBuilder.Call("build") }; + tracker.Call("send", builtException); } public void LogSocial(SocialHitBuilder builder) { + AndroidJavaObject socialBuilder = new AndroidJavaObject("com.google.android.gms.analytics.HitBuilders$SocialBuilder"); + socialBuilder.Call("setNetwork", new object[] { builder.GetSocialNetwork() }); + socialBuilder.Call("setAction", new object[] { builder.GetSocialAction() }); + socialBuilder.Call("setTarget", new object[] { builder.GetSocialTarget() }); + + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + socialBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + socialBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + + object[] builtSocial = new object[] { socialBuilder.Call("build") }; + tracker.Call("send", builtSocial); } public void LogTiming(TimingHitBuilder builder) { + AndroidJavaObject timingBuilder = new AndroidJavaObject("com.google.android.gms.analytics.HitBuilders$TimingBuilder"); + timingBuilder.Call("setCategory", new object[] { builder.GetTimingCategory() }); + timingBuilder.Call("setValue", new object[] { builder.GetTimingInterval() }); + timingBuilder.Call("setVariable", new object[] { builder.GetTimingName() }); + timingBuilder.Call("setLabel", new object[] { builder.GetTimingLabel() }); + + foreach(KeyValuePair i in builder.GetCustomDimensions()) + { + timingBuilder.Call("setCustomDimension", new object[] { i.Key, i.Value }); + } + foreach(KeyValuePair i in builder.GetCustomMetrics()) + { + timingBuilder.Call("setCustomMetric", new object[] { i.Key, i.Value }); + } + + object[] builtTiming = new object[] { timingBuilder.Call("build") }; + tracker.Call("send", builtTiming); } public void DispatchHits() { diff --git a/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsMPV3.cs b/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsMPV3.cs index 6b5e496..54618e3 100644 --- a/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsMPV3.cs +++ b/source/Plugins/GoogleAnalyticsV4/GoogleAnalyticsMPV3.cs @@ -78,7 +78,8 @@ public void InitializeTracker() { + AddRequiredMPParameter(Fields.TRACKING_ID, trackingCode) + AddRequiredMPParameter(Fields.APP_ID, bundleIdentifier) + AddRequiredMPParameter(Fields.CLIENT_ID, clientId) - + AddRequiredMPParameter(Fields.APP_VERSION, appVersion); + + AddRequiredMPParameter(Fields.APP_VERSION, appVersion) + + AddRequiredMPParameter(Fields.USER_AGENT_OVERRIDE, GetUserAgent()); if(anonymizeIP){ url += AddOptionalMPParameter(Fields.ANONYMIZE_IP, 1); } @@ -419,5 +420,70 @@ public void SetOptOut(bool optOut) { this.optOut = optOut; } + string GetWindowsNTVersion(string UnityOSVersionName) + { + //https://en.wikipedia.org/wiki/Windows_NT + if (UnityOSVersionName.Contains("(5.1")) + return "Windows NT 5.1"; + else if (UnityOSVersionName.Contains("(5.2")) + return "Windows NT 5.2"; + else if (UnityOSVersionName.Contains("(6.0")) + return "Windows NT 6.0"; + else if (UnityOSVersionName.Contains("(6.1")) + return "Windows NT 6.1"; + else if (UnityOSVersionName.Contains("(6.2")) + return "Windows NT 6.2"; +#if UNITY_4_6 + else if (UnityOSVersionName.Contains("(6.3")) + { + // But on older versions of Unity on Windows 10, it returns "Windows 8.1 (6.3.10586) 64bit" for Windows 10.0.10586 64 bit + System.Text.RegularExpressions.Match regexResult = System.Text.RegularExpressions.Regex.Match(UnityOSVersionName, @"Windows.*?\((\d{0,5}\.\d{0,5}\.(\d{0,5}))\)"); + if (regexResult.Success) + { + string buildNumberString = regexResult.Groups[2].Value; + // Fix a bug in older versions of Unity where Windows 10 isn't recognised properly + int buildNumber = 0; + Int32.TryParse(buildNumberString, out buildNumber); + if (buildNumber > 10000) + { + return "Windows NT 10.0"; + } + } + return "Windows NT 6.3"; + } +#else + else if (UnityOSVersionName.Contains("(6.3")) + return "Windows NT 6.3"; + else if (UnityOSVersionName.Contains("(10.0")) + return "Windows NT 10.0"; +#endif + else + return "Unknown"; + } + + string GetUserAgent() + { + string str_userAgent; + str_userAgent = "Unknown"; +#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + str_userAgent = (Application.platform == RuntimePlatform.OSXPlayer ? "Unity/" : "UnityEditor/") + + Application.unityVersion + + " (Macintosh; " + + (SystemInfo.processorType.Contains("Intel") ? "Intel " : "PPC ") + + SystemInfo.operatingSystem.Replace(".", "_") + ")" + + " Unity/" + Application.unityVersion + + " Unity/" + Application.unityVersion; +#endif +#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN + str_userAgent = + (Application.platform == RuntimePlatform.WindowsPlayer ? "Unity/" : "UnityEditor/") + Application.unityVersion + + " (" + GetWindowsNTVersion(SystemInfo.operatingSystem) + (SystemInfo.operatingSystem.Contains("64bit") ? "; WOW64)" : ")") + + " Unity/" + Application.unityVersion + + " (KHTML, like Gecko) Unity/" + Application.unityVersion + + " Unity/" + Application.unityVersion; +#endif + return str_userAgent; + } + #endif } diff --git a/source/Plugins/GoogleAnalyticsV4/HitBuilders/ItemHitBuilder.cs b/source/Plugins/GoogleAnalyticsV4/HitBuilders/ItemHitBuilder.cs index d2c04f8..8645326 100644 --- a/source/Plugins/GoogleAnalyticsV4/HitBuilders/ItemHitBuilder.cs +++ b/source/Plugins/GoogleAnalyticsV4/HitBuilders/ItemHitBuilder.cs @@ -52,7 +52,7 @@ public ItemHitBuilder SetName(string name) { } public string GetSKU() { - return name; + return SKU; } public ItemHitBuilder SetSKU(string SKU) {