private async Task CreateLocationDataRequest(bool urgent)
        {
            // Don't send anything unless we're setup
            if (!Settings.WeatherLoaded)
            {
                return;
            }

            if (mWearNodesWithApp == null)
            {
                // Create requests if nodes exist with app support
                mWearNodesWithApp = await FindWearDevicesWithApp();

                if (mWearNodesWithApp == null || mWearNodesWithApp.Count == 0)
                {
                    return;
                }
            }

            PutDataMapRequest mapRequest = PutDataMapRequest.Create(WearableHelper.LocationPath);
            var homeData = Settings.HomeData;

            mapRequest.DataMap.PutString("locationData", homeData?.ToJson());
            mapRequest.DataMap.PutLong("update_time", DateTime.UtcNow.Ticks);
            PutDataRequest request = mapRequest.AsPutDataRequest();

            if (urgent)
            {
                request.SetUrgent();
            }
            await WearableClass.DataApi.PutDataItem(mGoogleApiClient, request);

            Logger.WriteLine(LoggerLevel.Info, "{0}: CreateLocationDataRequest(): urgent: {1}", TAG, urgent.ToString());
        }
예제 #2
0
            public void Run()
            {
                if (Activity != null)
                {
                    var putDataMapRequest = PutDataMapRequest.Create(CountPath);
                    putDataMapRequest.DataMap.PutInt(CountKey, count++);
                    var request = putDataMapRequest.AsPutDataRequest();

                    LOGD(Tag, "Generating DataItem: " + request);
                    if (!Activity.mGoogleApiClient.IsConnected)
                    {
                        return;
                    }
                    WearableClass.DataApi.PutDataItem(Activity.mGoogleApiClient, request)
                    .SetResultCallback(
                        new ResultCallback()
                    {
                        OnResultAction = (Java.Lang.Object result) => {
                            try
                            {
                                var res = result.JavaCast <IDataApiDataItemResult>();
                                if (!res.Status.IsSuccess)
                                {
                                    Log.Error(Tag, "Failed to send message with status code: " + res.Status.StatusCode);
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                        );
                }
            }
        private void UpdateItem()
        {
            Log.Info(tag, "Update Item: ");
            DataMap itemMap = new DataMap();

            itemMap.PutString(StylistConstants.AppIdKey, item.AppId);
            itemMap.PutString(StylistConstants.FirstNameKey, item.FirstName);
            itemMap.PutString(StylistConstants.LastNameKey, item.LastName);
            itemMap.PutString(StylistConstants.ScheduleDateKey, item.ScheduleDate.ToString());
            itemMap.PutString(StylistConstants.StartServiceDateKey, item.StartServiceDate.ToString());
            itemMap.PutString(StylistConstants.EndServiceDateKey, item.EndServiceDate.ToString());
            itemMap.PutString(StylistConstants.ListStatusKey, item.Status.ToString());
            itemMap.PutString(StylistConstants.ListTypeKey, item.ListType.ToString());
            itemMap.PutBoolean(StylistConstants.IsDirtyKey, true);

            var serviceMap = new List <DataMap>();

            serviceMap.Add(itemMap);

            var request = PutDataMapRequest.Create(StylistConstants.GetDataPath + StylistConstants.UpdatePath).SetUrgent();

            Log.Info(tag, "Send data");
            request.DataMap.PutDataMapArrayList(StylistConstants.ListKey, serviceMap);
            WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
        }
예제 #4
0
 public void SendData(DataMap dataMap)
 {
     Task.Run(() => {
         var request = PutDataMapRequest.Create(path);
         request.DataMap.PutAll(dataMap);
         var result  = WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest()).Await();
         var success = result.JavaCast <IDataApiDataItemResult>().Status.IsSuccess ? "Ok." : "Failed!";
         Console.WriteLine(string.Format("Communicator: Sending data map {0}... {1}", dataMap, success));
     });
 }
예제 #5
0
        public static void SaveStepCountStatus(GoogleApiClient googleApiClient, bool stepCountOn)
        {
            var putDataMapRequest = PutDataMapRequest.Create(PathWithFeature);

            putDataMapRequest.DataMap.PutBoolean("stepcount", stepCountOn);
            var putDataRequest = putDataMapRequest.AsPutDataRequest();

            putDataRequest.SetUrgent();
            WearableClass.DataApi.PutDataItem(googleApiClient, putDataRequest);
        }
예제 #6
0
        async void HandleMessage(IMessageEvent message)
        {
            try
            {
                Android.Util.Log.Info("WearIntegration", "Received Message");
                var client = new GoogleApiClient.Builder(this)
                             .AddApi(WearableClass.API)
                             .Build();

                var result = client.BlockingConnect(30, Java.Util.Concurrent.TimeUnit.Seconds);
                if (!result.IsSuccess)
                {
                    return;
                }

                var path = message.Path;

                try
                {
                    if (path.StartsWith(TweetsPath))
                    {
                        var viewModel = new TwitterViewModel();

                        await viewModel.ExecuteLoadTweetsCommand();

                        var request = PutDataMapRequest.Create(TweetsPath + "/Answer");
                        var map     = request.DataMap;

                        var tweetMap = new List <DataMap>();
                        foreach (var tweet in viewModel.Tweets)
                        {
                            var itemMap = new DataMap();

                            itemMap.PutLong("CreatedAt", tweet.CreatedAt.Ticks);
                            itemMap.PutString("ScreenName", tweet.ScreenName);
                            itemMap.PutString("Text", tweet.Text);

                            tweetMap.Add(itemMap);
                        }
                        map.PutDataMapArrayList("Tweets", tweetMap);
                        map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);

                        await WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
                    }
                }
                finally
                {
                    client.Disconnect();
                }
            }
            catch (Exception e)
            {
                Android.Util.Log.Error("WearIntegration", e.ToString());
            }
        }
예제 #7
0
        /// <summary>
        /// Sends an asset that was created from the photo we took by adding it to the Data Item store
        /// </summary>
        /// <param name="asset">Asset.</param>
        private async Task SendPhoto(Asset asset)
        {
            var dataMap = PutDataMapRequest.Create(ImagePath);

            dataMap.DataMap.PutAsset(ImageKey, asset);
            dataMap.DataMap.PutLong("time", DateTime.Now.ToBinary());
            var request = dataMap.AsPutDataRequest();
            var res     = await WearableClass.DataApi.PutDataItemAsync(mGoogleApiClient, request);

            LOGD(Tag, "Sending image was successful: " + res.Status.IsSuccess);
        }
            public PutDataRequest ToPutDataRequest()
            {
                PutDataMapRequest request = PutDataMapRequest.Create("/question/" + questionIndex);
                DataMap           dataMap = request.DataMap;

                dataMap.PutString(Constants.QUESTION, question);
                dataMap.PutInt(Constants.QUESTION_INDEX, questionIndex);
                dataMap.PutStringArray(Constants.ANSWERS, answers);
                dataMap.PutInt(Constants.CORRECT_ANSWER_INDEX, correctAnswerIndex);
                return(request.AsPutDataRequest());
            }
예제 #9
0
        public void SendData()
        {
            //Things to keep in mind:
            // *The path should always starts with forward-slash(/).
            // * Timestamps is a must when sending data because the OnDataChanged() event only gets called when the data really changes.
            //   Adding the Timestamp to the data will make sure that the method gets called.
            var request = PutDataMapRequest.Create(MessagePath);
            var map     = request.DataMap;

            map.PutString("Message", "Hello from Wearable!");
            map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
            WearableClass.DataApi.PutDataItem(_googleApiClient, request.AsPutDataRequest());
        }
예제 #10
0
 public void SendData()
 {
     try {
         var request = PutDataMapRequest.Create(_syncPath);
         var map     = request.DataMap;
         map.PutString("Message", "Vinz says Hello from Wearable!");
         map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
         WearableClass.DataApi.PutDataItem(_client, request.AsPutDataRequest());
     }
     finally {
         _client.Disconnect();
     }
 }
예제 #11
0
        protected override void OnHandleIntent(Intent intent)
        {
            google_api_client.BlockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.Milliseconds);

            if (Log.IsLoggable(TAG, LogPriority.Verbose))
            {
                Log.Verbose(TAG, "FindPhoneService.OnHandleEvent");
            }

            if (google_api_client.IsConnected)
            {
                bool alarmOn = false;
                if (intent.Action == ACTION_TOGGLE_ALARM)
                {
                    var result = WearableClass.DataApi.GetDataItems(google_api_client).Await().JavaCast <DataItemBuffer>();
                    if (result.Status.IsSuccess)
                    {
                        if (result.Count == 1)
                        {
                            alarmOn = DataMap.FromByteArray((result.Get(0).JavaCast <IDataItem>()).GetData()).GetBoolean(FIELD_ALARM_ON, false);
                        }
                        else
                        {
                            Log.Error(TAG, "Unexpected number of DataItems found.\n" +
                                      "\tExpected: 1\n" +
                                      "\tActual: " + result.Count);
                        }
                    }
                    else if (Log.IsLoggable(TAG, LogPriority.Debug))
                    {
                        Log.Debug(TAG, "OnHandleIntent: failed to get current alarm state");
                    }

                    result.Close();
                    alarmOn = !alarmOn;
                    string notificationText = alarmOn ? GetString(Resource.String.turn_alarm_on) : GetString(Resource.String.turn_alarm_off);
                    MainActivity.UpdateNotification(this, notificationText);
                }

                var putDataMapRequest = PutDataMapRequest.Create(PATH_SOUND_ALARM);
                putDataMapRequest.DataMap.PutBoolean(FIELD_ALARM_ON, alarmOn);
                WearableClass.DataApi.PutDataItem(google_api_client, putDataMapRequest.AsPutDataRequest()).Await();
            }
            else
            {
                Log.Error(TAG, "Failed to toggle alarm on phone - Client disconnected from Google Play Services");
            }
            google_api_client.Disconnect();
        }
예제 #12
0
        public void SendData()
        {
            //send data to DataApi layer
            if (!_client.IsConnected)
            {
                return;
            }

            PutDataMapRequest mrequest = PutDataMapRequest.Create(syncPath);

            mrequest.DataMap.PutInt("heartratedata", heartRate);
            PutDataRequest request = mrequest.AsPutDataRequest();

            WearableClass.DataApi.PutDataItem(_client, request);
        }
        public static void PutConfigDataItem(IGoogleApiClient googleApiClient, DataMap newConfig)
        {
            var putDataMapRequest = PutDataMapRequest.Create(PathWithFeature);
            var configToPut       = putDataMapRequest.DataMap;

            configToPut.PutAll(newConfig);
            WearableClass.DataApi.PutDataItem(googleApiClient, putDataMapRequest.AsPutDataRequest())
            .SetResultCallback(new DataItemResultCallback(dataItemResult => {
                if (Log.IsLoggable(Tag, LogPriority.Debug))
                {
                    Log.Debug(Tag, "PutDataItem result status: " + dataItemResult.Status);
                }
            })
                               );
        }
예제 #14
0
        public async Task UpdateSharedTimeEntryList()
        {
            entryData = await WearDataProvider.GetTimeEntryData();

            mapReq = PutDataMapRequest.Create(Common.TimeEntryListPath);

            currentDataMap = new List <DataMap> ();

            foreach (var entry in entryData)
            {
                currentDataMap.Add(entry.DataMap);
            }
            mapReq.DataMap.PutDataMapArrayList(Common.TimeEntryListKey, currentDataMap);
            await SendData(mapReq);
        }
예제 #15
0
 void BuildWearableOnlyNotification(string title, string content, string path)
 {
     if (googleApiClient.IsConnected)
     {
         var putDataMapRequest = PutDataMapRequest.Create(path);
         putDataMapRequest.DataMap.PutString(Constants.KeyContent, content);
         putDataMapRequest.DataMap.PutString(Constants.KeyTitle, title);
         var request = putDataMapRequest.AsPutDataRequest();
         WearableClass.DataApi.PutDataItem(googleApiClient, request).SetResultCallback(this);
     }
     else
     {
         Log.Error(Tag, "BuildWearableOnlyNotification(): No Google API Client connection");
     }
 }
예제 #16
0
 /// <summary>
 /// Actually sends the data
 /// </summary>
 /// <param name="data">The string to be sent</param>
 /// <param name="path">the path where the data can be found</param>
 public void SendData(string data, string path)
 {
     try
     {
         var request = PutDataMapRequest.Create(path);
         var map     = request.DataMap;
         map.PutString("Message", data);
         map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
         WearableClass.DataApi.PutDataItem(googleApiClient, request.AsPutDataRequest());
         dataStatusHandler.updateStatus("Data sent");
     }
     finally
     {
         //_client.Disconnect();
     }
 }
        /// <summary>
        /// Handles incoming intents
        /// </summary>
        /// <param name="intent">The intent sent by Location Services. This Intent is provided to Location Services (inside a PendingIntent)
        /// when AddGeofences() is called</param>
        protected override void OnHandleIntent(Android.Content.Intent intent)
        {
            // First check for errors
            var geofencingEvent = GeofencingEvent.FromIntent(intent);

            if (geofencingEvent.HasError)
            {
                int errorCode = geofencingEvent.ErrorCode;
                Log.Error(Constants.TAG, "Location Services error: " + errorCode);
            }
            else
            {
                // Get the type of Geofence transition (i.e. enter or exit in this sample).
                int transitionType = geofencingEvent.GeofenceTransition;
                // Create a DataItem when a user enters one of the geofences. The wearable app will receie this and create a
                // notification to prompt him/her to check in
                if (transitionType == Geofence.GeofenceTransitionEnter)
                {
                    // Connect to the Google Api service in preparation for sending a DataItem
                    mGoogleApiClient.BlockingConnect(Constants.CONNECTION_TIME_OUT_MS, TimeUnit.Milliseconds);
                    // Get the geofence ID triggered. Note that only one geofence can be triggered at a time in this example, but in some cases
                    // you might want to consider the full list of geofences triggered
                    string triggeredGeofenceId = geofencingEvent.TriggeringGeofences[0].RequestId;
                    // Create a DataItem with this geofence's id. The wearable can use this to create a notification
                    PutDataMapRequest putDataMapRequest = PutDataMapRequest.Create(Constants.GEOFENCE_DATA_ITEM_PATH);
                    putDataMapRequest.DataMap.PutString(Constants.KEY_GEOFENCE_ID, triggeredGeofenceId);
                    if (mGoogleApiClient.IsConnected)
                    {
                        WearableClass.DataApi.PutDataItem(
                            mGoogleApiClient, putDataMapRequest.AsPutDataRequest()).Await();
                    }
                    else
                    {
                        Log.Error(Constants.TAG, "Failed to send data item: " + putDataMapRequest +
                                  " - disconnected from Google Play Services");
                    }
                    mGoogleApiClient.Disconnect();
                }
                else if (Geofence.GeofenceTransitionExit == transitionType)
                {
                    // Delete the data item when leaving a geofence region
                    mGoogleApiClient.BlockingConnect(Constants.CONNECTION_TIME_OUT_MS, TimeUnit.Milliseconds);
                    WearableClass.DataApi.DeleteDataItems(mGoogleApiClient, Constants.GEOFENCE_DATA_ITEM_URI).Await();
                    mGoogleApiClient.Disconnect();
                }
            }
        }
예제 #18
0
            public PutDataMapRequest ToPutDataMapRequest()
            {
                PutDataMapRequest putDataMapRequest = PutDataMapRequest.Create(
                    MakeDataItemPath(EventId, Begin));
                DataMap data = putDataMapRequest.DataMap;

                data.PutString(Constants.DATA_ITEM_URI, putDataMapRequest.Uri.ToString());
                data.PutLong(Constants.ID, Id);
                data.PutLong(Constants.EVENT_ID, EventId);
                data.PutString(Constants.TITLE, Title);
                data.PutLong(Constants.BEGIN, Begin);
                data.PutLong(Constants.END, End);
                data.PutBoolean(Constants.ALL_DAY, AllDay);
                data.PutString(Constants.DESCRIPTION, Description);
                data.PutAsset(Constants.PROFILE_PIC, OwnerProfilePic);
                return(putDataMapRequest);
            }
예제 #19
0
 // Sending data via DataApi
 public void SendData(DataMap dataMap)
 {
     Task.Run(() => {
         try
         {
             var request = PutDataMapRequest.Create(path);
             request.DataMap.PutAll(dataMap);
             var result  = WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest()).Await();
             var success = result.JavaCast <IDataApiDataItemResult>().Status.IsSuccess ? "Ok." : "Failed!";
             Log.Info("my_log", "Communicator: Sending data map " + dataMap + "... " + success);
         }
         catch (System.Exception ex)
         {
             throw;
         }
     });
 }
예제 #20
0
        /// <summary>
        /// Sends an asset that was created from the photo we took by adding it to the Data Item store
        /// </summary>
        /// <param name="asset">Asset.</param>
        private void SendPhoto(Asset asset)
        {
            var dataMap = PutDataMapRequest.Create(ImagePath);

            dataMap.DataMap.PutAsset(ImageKey, asset);
            dataMap.DataMap.PutLong("time", DateTime.Now.ToBinary());
            var request = dataMap.AsPutDataRequest();

            WearableClass.DataApi.PutDataItem(mGoogleApiClient, request)
            .SetResultCallback(new ResultCallback()
            {
                OnResultAction = (Java.Lang.Object result) =>
                {
                    var res = result.JavaCast <IDataApiDataItemResult>();
                    LOGD(Tag, "Sending image was successful: " + res.Status.IsSuccess);
                }
            });
        }
예제 #21
0
            public async void Run()
            {
                if (Activity != null)
                {
                    var putDataMapRequest = PutDataMapRequest.Create(CountPath);
                    putDataMapRequest.DataMap.PutInt(CountKey, count++);
                    var request = putDataMapRequest.AsPutDataRequest();

                    LOGD(Tag, "Generating DataItem: " + request);
                    if (!Activity.mGoogleApiClient.IsConnected)
                    {
                        return;
                    }
                    var res = await WearableClass.DataApi.PutDataItemAsync(Activity.mGoogleApiClient, request);

                    if (!res.Status.IsSuccess)
                    {
                        Log.Error(Tag, "Failed to send message with status code: " + res.Status.StatusCode);
                    }
                }
            }
예제 #22
0
        void BtnTapCounterClick(object sender, System.EventArgs e)
        {
            try
            {
                tapCount++;

                var request = PutDataMapRequest.Create(SYNC_PATH);
                request.SetUrgent(); // Use this only to send the message asap
                request.DataMap.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
                request.DataMap.PutString("TapCounter", tapCount.ToString());
                WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
            }
            catch (Exception ex)
            {
                Android.Util.Log.Error("Exception Occurred: " + ex.Message, "watch");
            }
            //Note: Uncomment only if you want to send a message only once
            //finally
            //{
            //    client.Disconnect();
            //}
        }
        private async Task CreateSettingsDataRequest(bool urgent)
        {
            // Don't send anything unless we're setup
            if (!Settings.WeatherLoaded)
            {
                return;
            }

            if (mWearNodesWithApp == null)
            {
                // Create requests if nodes exist with app support
                mWearNodesWithApp = await FindWearDevicesWithApp();

                if (mWearNodesWithApp == null || mWearNodesWithApp.Count == 0)
                {
                    return;
                }
            }

            var mapRequest = PutDataMapRequest.Create(WearableHelper.SettingsPath);

            mapRequest.DataMap.PutString("API", Settings.API);
            mapRequest.DataMap.PutString("API_KEY", Settings.API_KEY);
            mapRequest.DataMap.PutBoolean("KeyVerified", Settings.KeyVerified);
            mapRequest.DataMap.PutBoolean("FollowGPS", Settings.FollowGPS);
            mapRequest.DataMap.PutLong("update_time", DateTime.UtcNow.Ticks);
            var request = mapRequest.AsPutDataRequest();

            if (urgent)
            {
                request.SetUrgent();
            }
            await WearableClass.DataApi.PutDataItem(mGoogleApiClient, request);

            Logger.WriteLine(LoggerLevel.Info, "{0}: CreateSettingsDataRequest(): urgent: {1}", TAG, urgent.ToString());
        }
예제 #24
0
        async void HandleMessage(IMessageEvent message)
        {
            try {
                Android.Util.Log.Info("WearIntegration", "Received Message");
                var client = new GoogleApiClientBuilder(this)
                             .AddApi(LocationServices.API)
                             .AddApi(WearableClass.API)
                             .Build();

                var result = client.BlockingConnect(30, Java.Util.Concurrent.TimeUnit.Seconds);
                if (!result.IsSuccess)
                {
                    return;
                }

                var path = message.Path;

                try {
                    var stations = Hubway.Instance.LastStations;
                    if (stations == null)
                    {
                        stations = await Hubway.Instance.GetStations();
                    }

                    if (path.StartsWith(SearchStationPath))
                    {
                        var lastLocation = LocationServices.FusedLocationApi.GetLastLocation(client);
                        if (lastLocation == null)
                        {
                            return;
                        }

                        var currentPoint = new GeoPoint {
                            Lat = lastLocation.Latitude,
                            Lon = lastLocation.Longitude
                        };
                        var nearestStations = Hubway.GetStationsAround(stations, currentPoint, maxItems: 6, minDistance: double.MaxValue);
                        var favManager      = FavoriteManager.Obtain(this);
                        var favorites       = await favManager.GetFavoriteStationIdsAsync();

                        var request = PutDataMapRequest.Create(SearchStationPath + "/Answer");
                        var map     = request.DataMap;

                        var stationMap = new List <DataMap> ();
                        foreach (var station in nearestStations)
                        {
                            var itemMap = new DataMap();

                            itemMap.PutInt("Id", station.Id);

                            var asset = await CreateWearAssetFrom(station);

                            itemMap.PutAsset("Background", asset);

                            string secondary;
                            string primary = StationUtils.CutStationName(station.Name, out secondary);
                            itemMap.PutString("Primary", primary);
                            itemMap.PutString("Secondary", secondary);

                            var distance = GeoUtils.Distance(currentPoint, station.Location);
                            itemMap.PutDouble("Distance", distance);
                            itemMap.PutDouble("Lat", station.Location.Lat);
                            itemMap.PutDouble("Lon", station.Location.Lon);

                            itemMap.PutInt("Bikes", station.BikeCount);
                            itemMap.PutInt("Racks", station.EmptySlotCount);

                            itemMap.PutBoolean("IsFavorite", favorites.Contains(station.Id));

                            stationMap.Add(itemMap);
                        }
                        map.PutDataMapArrayList("Stations", stationMap);
                        map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);

                        await WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
                    }
                    else
                    {
                        var uri   = new Uri("wear://watch" + path);
                        var query = uri.GetComponents(UriComponents.Query, UriFormat.Unescaped);
                        var parts = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped).Split('/');

                        var action = parts[parts.Length - 2];
                        var id     = int.Parse(parts.Last());

                        if (action == FavoriteAction)
                        {
                            var favorites = FavoriteManager.Obtain(this);
                            handler.Post(() => {
                                if (query == "add")
                                {
                                    favorites.AddToFavorite(id);
                                }
                                else
                                {
                                    favorites.RemoveFromFavorite(id);
                                }
                            });
                        }
                    }
                } finally {
                    client.Disconnect();
                }
            } catch (Exception e) {
                Android.Util.Log.Error("WearIntegration", e.ToString());
                AnalyticsHelper.LogException("WearIntegration", e);
            }
        }
예제 #25
0
        /**
         * Transfer the required data over to the wearable
         * @param attractions list of attraction data to transfer over
         */
        private void SendDataToWearable(List <Attraction> attractions)
        {
            GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
                                              .AddApi(WearableClass.API)
                                              .Build();

            // It's OK to use blockingConnect() here as we are running in an
            // IntentService that executes work on a separate (background) thread.
            ConnectionResult connectionResult = googleApiClient.BlockingConnect(
                Constants.GOOGLE_API_CLIENT_TIMEOUT_S, TimeUnit.Seconds);

            // Limit attractions to send
            int count = attractions.Count > Constants.MAX_ATTRACTIONS ?
                        Constants.MAX_ATTRACTIONS : attractions.Count;

            List <DataMap> attractionsData = new List <DataMap>(count);

            for (int i = 0; i < count; i++)
            {
                Attraction attraction = attractions[i];

                Bitmap image          = null;
                Bitmap secondaryImage = null;

                try
                {
                    //TODO:
                    // Fetch and resize attraction image bitmap
                    //image = Glide.with(this)
                    //		.load(attraction.imageUrl)
                    //		.asBitmap()
                    //		.diskCacheStrategy(DiskCacheStrategy.SOURCE)
                    //		.into(Constants.WEAR_IMAGE_SIZE_PARALLAX_WIDTH, Constants.WEAR_IMAGE_SIZE)
                    //		.get();

                    //secondaryImage = Glide.with(this)
                    //		.load(attraction.secondaryImageUrl)
                    //		.asBitmap()
                    //		.diskCacheStrategy(DiskCacheStrategy.SOURCE)
                    //		.into(Constants.WEAR_IMAGE_SIZE_PARALLAX_WIDTH, Constants.WEAR_IMAGE_SIZE)
                    //		.get();
                }
                catch (Exception e)
                {
                    Log.Error("UtilityService", "Exception loading bitmap from network");
                }

                if (image != null && secondaryImage != null)
                {
                    DataMap attractionData = new DataMap();

                    string distance = Utils.FormatDistanceBetween(
                        Utils.GetLocation(this), attraction.Location);

                    attractionData.PutString(Constants.EXTRA_TITLE, attraction.Name);
                    attractionData.PutString(Constants.EXTRA_DESCRIPTION, attraction.Description);
                    attractionData.PutDouble(
                        Constants.EXTRA_LOCATION_LAT, attraction.Location.Latitude);
                    attractionData.PutDouble(
                        Constants.EXTRA_LOCATION_LNG, attraction.Location.Longitude);
                    attractionData.PutString(Constants.EXTRA_DISTANCE, distance);
                    attractionData.PutString(Constants.EXTRA_CITY, attraction.City);

                    //TODO:
                    //	attractionData.PutAsset(Constants.EXTRA_IMAGE,
                    //		Utils.CreateAssetFromBitmap(image));
                    //attractionData.PutAsset(Constants.EXTRA_IMAGE_SECONDARY,
                    //		Utils.CreateAssetFromBitmap(secondaryImage));

                    attractionsData.Add(attractionData);
                }
            }

            if (connectionResult.IsSuccess && googleApiClient.IsConnected &&
                attractionsData.Count > 0)
            {
                PutDataMapRequest dataMap = PutDataMapRequest.Create(Constants.ATTRACTION_PATH);
                dataMap.DataMap.PutDataMapArrayList(Constants.EXTRA_ATTRACTIONS, attractionsData);
                //TODO:
                //dataMap.DataMap.PutLong(Constants.EXTRA_TIMESTAMP, DateTime.Now.ToFileTime);
                PutDataRequest request = dataMap.AsPutDataRequest();
                request.SetUrgent();

                //TODO: Async/Await
                // Send the data over
                //            var result =
                //					WearableClass.DataApi.PutDataItem(googleApiClient, request));

                //            if (!result.).isSuccess()) {
                //                Log.e(TAG, String.format("Error sending data using DataApi (error code = %d)",
                //                        result.getStatus().getStatusCode()));
                //            }

                //} else {
                //            Log.e(TAG, String.format(Constants.GOOGLE_API_CLIENT_ERROR_MSG,
                //                    connectionResult.getErrorCode()));
                //        }
                googleApiClient.Disconnect();
            }
        }
        private async Task CreateWeatherDataRequest(bool urgent)
        {
            // Don't send anything unless we're setup
            if (!Settings.WeatherLoaded)
            {
                return;
            }

            if (mWearNodesWithApp == null)
            {
                // Create requests if nodes exist with app support
                mWearNodesWithApp = await FindWearDevicesWithApp();

                if (mWearNodesWithApp == null || mWearNodesWithApp.Count == 0)
                {
                    return;
                }
            }

            PutDataMapRequest mapRequest = PutDataMapRequest.Create(WearableHelper.WeatherPath);
            var homeData    = Settings.HomeData;
            var weatherData = await Settings.GetWeatherData(homeData.query);

            var alertData = await Settings.GetWeatherAlertData(homeData.query);

            if (weatherData != null)
            {
                weatherData.weather_alerts = alertData;

                // location
                // update_time
                // forecast
                // hr_forecast
                // txt_forecast
                // condition
                // atmosphere
                // astronomy
                // precipitation
                // ttl
                // source
                // query
                // locale

                mapRequest.DataMap.PutString("weatherData", weatherData?.ToJson());
                List <String> alerts = new List <String>();
                if (weatherData.weather_alerts.Count > 0)
                {
                    foreach (WeatherData.WeatherAlert alert in weatherData.weather_alerts)
                    {
                        alerts.Add(alert.ToJson());
                    }
                }
                mapRequest.DataMap.PutStringArrayList("weatherAlerts", alerts);
                mapRequest.DataMap.PutLong("update_time", weatherData.update_time.UtcTicks);
                PutDataRequest request = mapRequest.AsPutDataRequest();
                if (urgent)
                {
                    request.SetUrgent();
                }
                await WearableClass.DataApi.PutDataItem(mGoogleApiClient, request);

                Logger.WriteLine(LoggerLevel.Info, "{0}: CreateWeatherDataRequest(): urgent: {1}", TAG, urgent.ToString());
            }
        }