/// <summary> /// Tracks this application being launched. If the LaunchActivatedEventArgs /// parameter contains push data passed through from a Toast's "launch" /// parameter, then we extract and report information to correlate this /// application open with that push. /// </summary> /// <param name="launchArgs">The LaunchActivatedEventArgs available in an /// Application.OnLaunched override.</param> /// <returns>An Async Task that can be waited on or ignored.</returns> public static Task TrackAppOpenedAsync(ILaunchActivatedEventArgs launchArgs) { // Short-circuit if the Launch event isn't from an actual app launch. // We'll still phone home if the launchArgs passed in is null, though, // so here we only check for a non-Launch ActivationKind. if (launchArgs != null && launchArgs.Kind != ActivationKind.Launch) { return(((Task)null).Safe()); } object pushHash; IDictionary <string, object> contentJson = AVPush.PushJson(launchArgs); contentJson.TryGetValue("push_hash", out pushHash); return(AVAnalytics.TrackAppOpenedWithPushHashAsync((string)pushHash)); }
/// <summary> /// This method adds event listeners to track app opens from tiles, the app list, /// and push notifications. Windows Phone 8 developers should use TrackAppOpens instead of /// TrackAppOpenedAsync, which this method will call automatically. /// /// This method can be called in Application_Launching or as follows in the Application constructor: /// /// <code> /// this.Startup += (sender, args) => { /// AVAnalytics.TrackAppOpens(RootFrame); /// }; /// </code> /// </summary> /// <param name="frame">The RootFrame of the Application.</param> public static void TrackAppOpens(PhoneApplicationFrame frame) { // This method is supposed to be called from OnLaunched. This call may also be // an app open; if it doesn't contain a valid push hash, make sure that it's counted once upon startup. var isFirstLaunch = true; frame.Navigated += async(sender, args) => { bool alwaysReport = isFirstLaunch; isFirstLaunch = false; // If the user navigates to a push, goes to a new activity, and then goes back, // we shouldn't double count the push. if (args.NavigationMode != System.Windows.Navigation.NavigationMode.New) { return; } var json = AVPush.PushJson(args.Uri.ToString()); object hash = null; if (json.TryGetValue("push_hash", out hash) || alwaysReport) { await TrackAppOpenedWithPushHashAsync((string)hash); } }; }
/// <summary> /// Handle push intent from <see cref="ParsePushBroadcastReceiver"/>. /// </summary> /// <param name="intent">The intent to be handled.</param> protected override void OnHandleIntent(Intent intent) { Task task = Task.FromResult(0); try { // Assume only GCM intent is received here. switch (intent.Action) { case ParsePushBroadcastReceiver.ActionGcmRegisterResponse: task = GcmRegistrar.GetInstance().HandleRegistrationIntentAsync(intent); break; case ParsePushBroadcastReceiver.ActionGcmReceive: if (ManifestInfo.HasPermissionForGCM()) { AVPush.parsePushNotificationReceived.Invoke(AVInstallation.CurrentInstallation, new AVPushNotificationEventArgs(AVPush.PushJson(intent))); } break; default: // TODO (hallucinogen): Prints error that we don't support other intent. break; } // Wait for its completion with timeout. task.Wait(IntentServiceHandlerTimeout); } finally { AVWakefulHelper.CompleteWakefulIntent(intent); } }