/**
   * Adds DataItem to the Android Wear network. The updated item is synchronized across all devices.
   *
   * @param dataPath The path to the data
   * @param data The data to send
   * @param callBack The callback to receive the response
   * @param isAsynchronous send data asynchronously
   * @param sendImmediately source :
   *     http://android-developers.blogspot.in/2015/11/whats-new-in-google-play-services-83.html
   *     With Google Play services 8.3, we’ve updated the DataApi to allow for urgency in how data
   *     items are synced. Now, a priority can be added to the data item to determine when it should
   *     be synced. For example, if you are building an app that requires immediate syncing, such as
   *     a remote control app, it can still be done immediately by calling setUrgent(), but for
   *     something such as updating your contacts, you could tolerate some delay. Non-urgent
   *     DataItems may be delayed for up to 30 minutes, but you can expect that in most cases they
   *     will be delivered within a few minutes. Low priority is now the default, so setUrgent() is
   *     needed to obtain the previous timing.
   */
  public void sendData(
      String dataPath,
      DataMap data,
      ResultCallback<DataApi.DataItemResult> callBack,
      boolean isAsynchronous,
      boolean sendImmediately) {
    if (!isConnected()) {
      if (mConnectionCallBacks != null) {
        mConnectionCallBacks.onConnectionFailed(WearConnectionCallBacks.NETWORK_ERROR);
      }
      return;
    } else if (dataPath == null) {
      if (mConnectionCallBacks != null) {
        mConnectionCallBacks.onConnectionFailed(WearConnectionCallBacks.PATH_NULL_ERROR);
      }
      return;
    } else if (data == null) {
      Log.d("Send DataMap", "Data cannot be null");
      return;
    }

    PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(dataPath);
    putDataMapRequest.getDataMap().putAll(data);

    /** Current time is also sent with data, just to make it a new data */
    putDataMapRequest
        .getDataMap()
        .putString(
            WearConnectionConstants.KEY.CURRENT_TIME, String.valueOf(System.currentTimeMillis()));

    PutDataRequest request = putDataMapRequest.asPutDataRequest();

    // update from google play service 8.3. refer comments above
    if (sendImmediately) {
      request.setUrgent();
    }

    if (isAsynchronous) {
      /** You will get callback after data is sent use the below code */
      PendingResult<DataApi.DataItemResult> dataResult =
          Wearable.DataApi.putDataItem(mGoogleApiClient, request);
      if (callBack != null) {
        dataResult.setResultCallback(callBack);
      }
    } else {
      if (isRunningOnMainThread()) {
        if (mConnectionCallBacks != null) {
          mConnectionCallBacks.onConnectionFailed(
              WearConnectionCallBacks.METHOD_CALLED_FROM_UI_THREAD);
        }
        return;
      }
      Wearable.DataApi.putDataItem(mGoogleApiClient, request).await();
    }
  }
Beispiel #2
0
  void sendHeadVector() {
    mHeadTracker.getLastHeadView(headView, 0);
    // Matrix.rotateM(headView, 0, 180, 0, 0, 1);  //upside down
    SensorManager.remapCoordinateSystem(
        headView, SensorManager.AXIS_Z, SensorManager.AXIS_MINUS_Y, headView);
    // SensorManager.remapCoordinateSystem(headView, SensorManager.AXIS_MINUS_Z,
    // SensorManager.AXIS_Y, headView); //rotate for sensor.

    PutDataMapRequest req = PutDataMapRequest.create("/head");
    for (int i = 0; i < 16; ++i) {
      req.getDataMap().putFloat(HEAD_PRE + i, headView[i]);
    }
    req.getDataMap().putLong("time", new Date().getTime());
    Wearable.DataApi.putDataItem(mGoogleApiClient, req.asPutDataRequest())
        .setResultCallback(
            new ResultCallback<DataApi.DataItemResult>() {
              @Override
              public void onResult(DataApi.DataItemResult dataItemResult) {
                if (dataItemResult.getStatus().isSuccess()) {
                  Log.d("TEST", "Data item set: " + dataItemResult.getDataItem().getUri());
                } else if (dataItemResult.getStatus().isCanceled()) {
                  Log.d("TEST", "canceled");
                } else if (dataItemResult.getStatus().isInterrupted()) {
                  Log.d("TEST", "interrupted");
                }
              }
            });
  }
 private void sendMessageToWearable(String message, String type) {
   // Log.d(TAG, "sendMessageToWearable: " + type + ": " + message);
   if (mGoogleApiClient.isConnected()) {
     PutDataMapRequest putDataMapRequest =
         PutDataMapRequest.create(Constants.MESSAGE_MOBILE_TO_WEARABLE_PATH);
     putDataMapRequest.getDataMap().putString(Constants.KEY_TEXT_FROM_SERVER, message);
     putDataMapRequest.getDataMap().putLong(Constants.KEY_TIMESTAMP, new Date().getTime());
     putDataMapRequest.getDataMap().putString(Constants.KEY_MESSAGE_TYPE, type);
     PutDataRequest request = putDataMapRequest.asPutDataRequest();
     Wearable.DataApi.putDataItem(mGoogleApiClient, request)
         .setResultCallback(
             new ResultCallback<DataApi.DataItemResult>() {
               @Override
               public void onResult(DataApi.DataItemResult dataItemResult) {
                 if (!dataItemResult.getStatus().isSuccess()) {
                   Log.e(
                       TAG,
                       "buildWatchOnlyNotification(): Failed to set the data, "
                           + "status: "
                           + dataItemResult.getStatus().getStatusCode());
                 } else {
                   // Log.d(TAG, "message sent successfully!");
                 }
               }
             });
   } else {
     Log.e(TAG, "sendMessageToWearable(): no Google API Client connection");
   }
 }
Beispiel #4
0
 @Override
 protected void onHandleIntent(Intent intent) {
   GoogleApiClient googleApiClient =
       new GoogleApiClient.Builder(this).addApi(Wearable.API).build();
   ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
   if (!connectionResult.isSuccess()) {
     Log.e(TAG, "Failed to connect to GoogleApiClient: " + connectionResult.getErrorCode());
     return;
   }
   // Read all DataItems
   DataItemBuffer dataItemBuffer = Wearable.DataApi.getDataItems(googleApiClient).await();
   if (!dataItemBuffer.getStatus().isSuccess()) {
     Log.e(TAG, "Error getting all data items: " + dataItemBuffer.getStatus().getStatusMessage());
   }
   Iterator<DataItem> dataItemIterator = dataItemBuffer.singleRefIterator();
   boolean foundArtwork = false;
   while (dataItemIterator.hasNext()) {
     DataItem dataItem = dataItemIterator.next();
     foundArtwork = foundArtwork || processDataItem(googleApiClient, dataItem);
   }
   dataItemBuffer.release();
   if (!foundArtwork
       && intent != null
       && intent.getBooleanExtra(SHOW_ACTIVATE_NOTIFICATION_EXTRA, false)) {
     ActivateMuzeiIntentService.maybeShowActivateMuzeiNotification(this);
   }
   googleApiClient.disconnect();
 }
 private void apagarDados() {
   if (mUriDados != null) {
     Wearable.DataApi.deleteDataItems(mGoogleApiClient, mUriDados);
   }
   if (mNodes != null) {
     mNodes.clear();
   }
 }
Beispiel #6
0
 @Override
 protected void onPause() {
   super.onPause();
   if (mGoogleApiClient != null) Wearable.DataApi.removeListener(mGoogleApiClient, this);
   if (mSensorManager != null) mSensorManager.unregisterListener(this);
   if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect();
   if (mHeadTracker != null) mHeadTracker.stopTracking();
 }
 @Override
 public void onConnected(Bundle bundle) {
   final Uri dataItemUri =
       new Uri.Builder().scheme(WEAR_URI_SCHEME).path(Constants.NOTIFICATION_PATH).build();
   if (Log.isLoggable(TAG, Log.DEBUG)) {
     Log.d(TAG, "Deleting Uri: " + dataItemUri.toString());
   }
   Wearable.DataApi.deleteDataItems(mGoogleApiClient, dataItemUri).setResultCallback(this);
 }
  // Create a data map and put data in it!
  private void increaseCounter() {
    if (gac.isConnected()) {
      PutDataMapRequest putDataMapReq = PutDataMapRequest.create(DATA_COUNT_PATH);

      putDataMapReq.getDataMap().putInt(DATA_KEY, count++);

      PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
      Wearable.DataApi.putDataItem(gac, putDataReq);

      Log.i("DataItemPut!", "" + count);
    }
  }
Beispiel #9
0
 private boolean processDataItem(GoogleApiClient googleApiClient, DataItem dataItem) {
   if (!dataItem.getUri().getPath().equals("/artwork")) {
     Log.w(TAG, "Ignoring data item " + dataItem.getUri().getPath());
     return false;
   }
   DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItem);
   DataMap artworkDataMap = dataMapItem.getDataMap().getDataMap("artwork");
   if (artworkDataMap == null) {
     Log.w(TAG, "No artwork in datamap.");
     return false;
   }
   final Artwork artwork = Artwork.fromBundle(artworkDataMap.toBundle());
   final Asset asset = dataMapItem.getDataMap().getAsset("image");
   if (asset == null) {
     Log.w(TAG, "No image asset in datamap.");
     return false;
   }
   // Convert asset into a file descriptor and block until it's ready
   final DataApi.GetFdForAssetResult getFdForAssetResult =
       Wearable.DataApi.getFdForAsset(googleApiClient, asset).await();
   InputStream assetInputStream = getFdForAssetResult.getInputStream();
   if (assetInputStream == null) {
     Log.w(TAG, "Empty asset input stream (probably an unknown asset).");
     return false;
   }
   Bitmap image = BitmapFactory.decodeStream(assetInputStream);
   if (image == null) {
     Log.w(TAG, "Couldn't decode a bitmap from the stream.");
     return false;
   }
   File localCache = new File(getCacheDir(), "cache.png");
   FileOutputStream out = null;
   try {
     out = new FileOutputStream(localCache);
     image.compress(Bitmap.CompressFormat.PNG, 100, out);
   } catch (IOException e) {
     Log.e(TAG, "Error writing local cache", e);
   } finally {
     try {
       if (out != null) {
         out.close();
       }
     } catch (IOException e) {
       Log.e(TAG, "Error closing local cache file", e);
     }
   }
   enableComponents(FullScreenActivity.class);
   if (MuzeiProvider.saveCurrentArtworkLocation(this, localCache)) {
     getContentResolver().insert(MuzeiContract.Artwork.CONTENT_URI, artwork.toContentValues());
   }
   return true;
 }
  private void openFunction(String key) {
    if (gac.isConnected()) {
      PutDataMapRequest putDataMapReq = PutDataMapRequest.create(DATA_PATH);

      putDataMapReq.getDataMap().putInt(DATA_REFRESH_KEY, DATA_REFRESH_COUNT++);
      putDataMapReq.getDataMap().putString(DATA_KEY, key);

      PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
      Wearable.DataApi.putDataItem(gac, putDataReq);

      Log.d("REFRESH COUNT", "" + DATA_REFRESH_COUNT);
    }
  }
Beispiel #11
0
    @Override
    protected Void doInBackground(Void... params) {

      PutDataMapRequest dataMap = PutDataMapRequest.create("/bulk/update");

      dataMap.getDataMap().putStringArrayList("contents", contents);
      dataMap.getDataMap().putLong("timestamp", System.currentTimeMillis());

      Wearable.DataApi.putDataItem(googleApiClient, dataMap.asPutDataRequest().setUrgent());

      Log.d(TAG, "Data sent:" + contents.toString());

      return null;
    }
 /**
  * Overwrites the current config {@link DataItem}'s {@link DataMap} with {@code newConfig}. If the
  * config DataItem doesn't exist, it's created.
  */
 public static void putConfigDataItem(GoogleApiClient googleApiClient, DataMap newConfig) {
   PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(PATH_WITH_FEATURE);
   DataMap configToPut = putDataMapRequest.getDataMap();
   configToPut.putAll(newConfig);
   Wearable.DataApi.putDataItem(googleApiClient, putDataMapRequest.asPutDataRequest())
       .setResultCallback(
           new ResultCallback<DataApi.DataItemResult>() {
             @Override
             public void onResult(DataApi.DataItemResult dataItemResult) {
               if (Log.isLoggable(TAG, Log.DEBUG)) {
                 Log.d(TAG, "putDataItem result status: " + dataItemResult.getStatus());
               }
             }
           });
 }
    public void run() {

      if (googleClient != null) {
        PutDataMapRequest putDMR = PutDataMapRequest.create(path);
        putDMR.getDataMap().putAll(dataMap);
        PutDataRequest request = putDMR.asPutDataRequest();
        DataApi.DataItemResult result = Wearable.DataApi.putDataItem(googleClient, request).await();
        if (result.getStatus().isSuccess()) {
          Log.v("myTag", "DataMap: " + dataMap + " sent successfully to data layer ");
        } else {
          // Log an error
          Log.v("myTag", "ERROR: failed to send DataMap to data layer");
        }
      }
    }
  @Override
  public void onConnected(Bundle connectionHint) {
    if (mDataListener != null) {
      Wearable.DataApi.addListener(mGoogleApiClient, mDataListener);
    }
    if (mMessageListener != null) {
      Wearable.MessageApi.addListener(mGoogleApiClient, mMessageListener);
    }
    if (mNodeListener != null) {
      Wearable.NodeApi.addListener(mGoogleApiClient, mNodeListener);
    }

    // TODO  Vishnu : check this callback is needed
    if (mConnectionCallBacks != null) {
      mConnectionCallBacks.onConnectionSuccess();
    }
  }
  private void putData() {
    Log.e("jerem", "putData: ");
    PutDataMapRequest putDataMapRequest =
        PutDataMapRequest.create(
            mContext.getResources().getString(R.string.wearable_data_item_path));
    putDataMapRequest
        .getDataMap()
        .putDouble(
            mContext.getResources().getString(R.string.wearable_data_item_high_temp),
            mWearableHighTemp);
    putDataMapRequest
        .getDataMap()
        .putDouble(
            mContext.getResources().getString(R.string.wearable_data_item_low_temp),
            mWearableLowTemp);

    int artResourceForWeatherCondition =
        Utility.getArtResourceForWeatherCondition(mWearableWeatherId);
    Bitmap bitmap =
        BitmapFactory.decodeResource(mContext.getResources(), artResourceForWeatherCondition);
    Asset asset = createAssetFromBitmap(bitmap);
    if (asset != null) {
      putDataMapRequest
          .getDataMap()
          .putAsset(mContext.getResources().getString(R.string.wearable_data_item_asset), asset);
    }

    PutDataRequest request = putDataMapRequest.asPutDataRequest();
    Wearable.DataApi.putDataItem(mGoogleApiClient, request)
        .setResultCallback(
            new ResultCallback<DataApi.DataItemResult>() {
              @Override
              public void onResult(DataApi.DataItemResult dataItemResult) {
                if (dataItemResult.getStatus().isSuccess()) {
                  Log.i("SUNSHINE", "Data update successfully sync with the wearable");
                } else {
                  Log.i("SUNSHINE", "Syncing with the wearable failed");
                }
              }
            });

    //        mGoogleApiClient.disconnect();

  }
  /*データの種類
  key	     type    備考        format(BluetoothSPP)
  --------------------------------------------------
  scene    string  シーン情報   "scene:ex"
  ready    boolean 準備完了状態 "ready:ex"
  vibrator integer バイブ時間   "vibrator:ex(ms)"
  */
  public void SyncData(
      String key_name, String sync_data) { // HandheldとWear間の各種データの更新をする。データの種類は上記のコメントを参照
    PutDataMapRequest dataMapRequest = PutDataMapRequest.create(globalv.DATA_PATH);
    DataMap dataMap = dataMapRequest.getDataMap();
    // Data set
    dataMap.putString(key_name, sync_data); // ("keyname",data);

    // Data Push
    PutDataRequest request = dataMapRequest.asPutDataRequest();
    PendingResult<DataApi.DataItemResult> pendingResult =
        Wearable.DataApi.putDataItem(mGoogleApiClient, request);
    pendingResult.setResultCallback(
        new ResultCallback<DataApi.DataItemResult>() {
          @Override
          public void onResult(DataApi.DataItemResult dataItemResult) {
            Log.d("TAG", "onResult:" + dataItemResult.getStatus().toString());
          }
        });
  }
Beispiel #17
0
 void sendMessage(String str) {
   Log.d("sendMessage", "Message: " + str);
   PutDataMapRequest req = PutDataMapRequest.create("/" + str);
   req.getDataMap().putInt(str, 1);
   req.getDataMap().putLong("time", new Date().getTime());
   Wearable.DataApi.putDataItem(mGoogleApiClient, req.asPutDataRequest())
       .setResultCallback(
           new ResultCallback<DataApi.DataItemResult>() {
             @Override
             public void onResult(DataApi.DataItemResult dataItemResult) {
               if (dataItemResult.getStatus().isSuccess()) {
                 Log.d("TEST", "Data item set: " + dataItemResult.getDataItem().getUri());
               } else if (dataItemResult.getStatus().isCanceled()) {
                 Log.d("TEST", "canceled");
               } else if (dataItemResult.getStatus().isInterrupted()) {
                 Log.d("TEST", "interrupted");
               }
             }
           });
 }
  /** Permet d'envoyer une image à la montre */
  protected void sendImage(String url, int position) {
    // télécharge l'image
    Bitmap bitmap = getBitmapFromURL(url);
    if (bitmap != null) {
      Asset asset = createAssetFromBitmap(bitmap);

      // créé un emplacement mémoire "image/[url_image]"
      final PutDataMapRequest putDataMapRequest = PutDataMapRequest.create("/image/" + position);

      // ajoute la date de mise à jour, important pour que les données soient mises à jour
      putDataMapRequest.getDataMap().putString("timestamp", new Date().toString());

      // ajoute l'image à la requête
      putDataMapRequest.getDataMap().putAsset("image", asset);

      // envoie la donnée à la montre
      if (mApiClient.isConnected())
        Wearable.DataApi.putDataItem(mApiClient, putDataMapRequest.asPutDataRequest());
    }
  }
  private void sendWeatherDataItem(Bitmap weatherIcon, String highString, String lowString) {

    Asset iconAsset = WearUtils.toAsset(weatherIcon);
    PutDataMapRequest dataMap = PutDataMapRequest.create(AppConstants.PATH_WEATHER_UPDATE);
    dataMap.getDataMap().putAsset(AppConstants.KEY_WEATHER_ICON, iconAsset);
    dataMap.getDataMap().putString(AppConstants.KEY_HIGH_TEMPERATURE, highString);
    dataMap.getDataMap().putString(AppConstants.KEY_LOW_TEMPERATURE, lowString);
    dataMap.getDataMap().putLong(AppConstants.KEY_TIMESTAMP, new Date().getTime());
    PutDataRequest request = dataMap.asPutDataRequest();
    Wearable.DataApi.putDataItem(mGoogleApiClient, request)
        .setResultCallback(
            new ResultCallback<DataApi.DataItemResult>() {
              @Override
              public void onResult(DataApi.DataItemResult dataItemResult) {
                Log.d(
                    LOG_TAG,
                    "Sending image was successful: " + dataItemResult.getStatus().isSuccess());
              }
            });
  }
  /**
   * Closes the connection to Google Play services. No calls can be made using this {@link
   * #mGoogleApiClient} after calling this method. Any method calls that haven't executed yet will
   * be canceled. That is onResult(Result) won't be called, if connection to the service hasn't been
   * established yet all calls already made will be canceled.
   */
  public void disConnect() {
    try {
      if (mDataListener != null) {
        Wearable.DataApi.removeListener(mGoogleApiClient, mDataListener);
      }
      if (mMessageListener != null) {
        Wearable.MessageApi.removeListener(mGoogleApiClient, mMessageListener);
      }
      if (mNodeListener != null) {
        Wearable.NodeApi.removeListener(mGoogleApiClient, mNodeListener);
      }

      if ((mGoogleApiClient != null)
          && (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting())) {
        mGoogleApiClient.disconnect();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /** Permet d'envoyer une liste d'elements */
  protected void sendElements(final List<Element> elements) {

    final PutDataMapRequest putDataMapRequest = PutDataMapRequest.create("/elements/");

    ArrayList<DataMap> elementsDataMap = new ArrayList<>();

    // envoie chaque élémént 1 par 1
    for (int position = 0; position < elements.size(); ++position) {

      DataMap elementDataMap = new DataMap();
      Element element = elements.get(position);

      // créé un emplacement mémoire "element/[position]"

      // ajoute la date de mi[jase à jour
      elementDataMap.putString("timestamp", new Date().toString());

      // ajoute l'element champ par champ
      elementDataMap.putString("titre", element.getTitre());
      elementDataMap.putString("description", element.getDescription());
      elementDataMap.putString("url", element.getUrl());

      // ajoute cette datamap à notre arrayList
      elementsDataMap.add(elementDataMap);
    }

    // place la liste dans la datamap envoyée à la wear
    putDataMapRequest.getDataMap().putDataMapArrayList("/list/", elementsDataMap);

    // envoie la liste à la montre
    if (mApiClient.isConnected())
      Wearable.DataApi.putDataItem(mApiClient, putDataMapRequest.asPutDataRequest());

    // puis envoie les images dans un second temps
    for (int position = 0; position < elements.size(); ++position) {
      // charge l'image associée pour l'envoyer en bluetooth
      sendImage(elements.get(position).getUrl(), position);
    }
  }
 @Override
 public void onConnected(Bundle bundle) {
   Wearable.DataApi.addListener(mGoogleApiClient, this);
 }
 @Override
 protected void onStop() {
   super.onStop();
   Wearable.DataApi.removeListener(mGoogleApiClient, this);
   mGoogleApiClient.disconnect();
 }
 @Override
 public void onConnected(Bundle bundle) {
   Log.d("TAG", "onConnected");
   Wearable.DataApi.addListener(mGoogleApiClient, this);
   Wearable.MessageApi.addListener(mGoogleApiClient, this);
 }
Beispiel #25
0
 @Override
 public void onConnected(Bundle bundle) {
   if (mGoogleApiClient != null) Wearable.DataApi.addListener(mGoogleApiClient, this);
   sendMessage(STATUS);
 }
  /**
   * Intents come in when the service is started & through the broadcast receiver. This processes
   * them just the same, setting up warning booleans and managing the countdown timer.
   *
   * @param intent The intent to process
   */
  private void processIntent(Intent intent) {
    /* If the intent is null, don't bother */
    if (intent == null) {
      return;
    }

    Bundle extras = intent.getExtras();

    /* If keys exist, process them */
    if (extras.containsKey(FamiliarConstants.KEY_FIVE_MINUTE_WARNING)) {
      mFiveMinuteWarning = extras.getBoolean(FamiliarConstants.KEY_FIVE_MINUTE_WARNING);
    }
    if (extras.containsKey(FamiliarConstants.KEY_TEN_MINUTE_WARNING)) {
      mTenMinuteWarning = extras.getBoolean(FamiliarConstants.KEY_TEN_MINUTE_WARNING);
    }
    if (extras.containsKey(FamiliarConstants.KEY_FIFTEEN_MINUTE_WARNING)) {
      mFifteenMinuteWarning = extras.getBoolean(FamiliarConstants.KEY_FIFTEEN_MINUTE_WARNING);
    }
    if (extras.containsKey(FamiliarConstants.KEY_END_TIME)) {

      /* Stop any current countdowns and remove the notification */
      if (mCountDownTimer != null) {
        mCountDownTimer.cancel();
      }
      mNotificationManager.cancel(NOTIFICATION_ID);

      long endTime = extras.getLong(FamiliarConstants.KEY_END_TIME);
      if (endTime == FamiliarConstants.CANCEL_FROM_MOBILE
          || endTime == FamiliarConstants.CANCEL_FROM_WEAR) {
        /* an end time of 0 means kill the notification */
        unregisterReceiver(mBroadcastReceiver);
        CountdownService.this.stopSelfResult(mStartId);
        /* And tell the app in case this was canceled on the app */
        if (endTime == FamiliarConstants.CANCEL_FROM_WEAR) {
          Log.v("MTG", "cancel button");
          /* This came from the cancel button, so tell the mobile */
          if (mGoogleApiClient.isConnected()) {
            PutDataMapRequest putDataMapReq = PutDataMapRequest.create(FamiliarConstants.PATH);
            putDataMapReq
                .getDataMap()
                .putLong(FamiliarConstants.KEY_END_TIME, FamiliarConstants.CANCEL_FROM_WEAR);
            PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
            PendingResult<DataApi.DataItemResult> pendingResult =
                Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq);
            pendingResult.setResultCallback(
                new ResultCallback<DataApi.DataItemResult>() {
                  @Override
                  public void onResult(DataApi.DataItemResult dataItemResult) {
                    Log.v("MTG", "onResult: " + dataItemResult.getStatus().getStatusMessage());
                  }
                });

            Log.v("MTG", "message sent");
          }
        }
      } else {
        /* Display the notification */
        mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build());

        /* Figure out how far we are away from the end time.
         * Assume mobile and wear clocks are in sync */
        long millisInFuture = endTime - System.currentTimeMillis();
        mCountDownTimer =
            new CountDownTimer(millisInFuture, 1000) {
              /**
               * This should tick once every second. It updates the notification
               *
               * @param millisUntilFinished The time until the countdown finishes
               */
              @Override
              public void onTick(long millisUntilFinished) {

                /* Build the string */
                long secondsLeft = (millisUntilFinished / 1000) % 60;
                long minutesLeft = (millisUntilFinished / (1000 * 60)) % 60;
                long hoursLeft = (millisUntilFinished / (1000 * 60 * 60));
                String messageText =
                    String.format("%02d:%02d:%02d", hoursLeft, minutesLeft, secondsLeft);

                /* Because the ID remains unchanged,
                 * the existing notification is updated. */
                mNotificationBuilder.setContentTitle(messageText);
                mNotificationManager.notify(NOTIFICATION_ID, mNotificationBuilder.build());

                /* Vibrate a pattern if the warnings are set up */
                if (mFifteenMinuteWarning
                    && hoursLeft == 0
                    && minutesLeft == 15
                    && secondsLeft == 0) {
                  /* Buzz */
                  mVibrator.vibrate(200);
                  mFifteenMinuteWarning = false;
                } else if (mTenMinuteWarning
                    && hoursLeft == 0
                    && minutesLeft == 10
                    && secondsLeft == 0) {
                  /* Buzz Buzz */
                  mVibrator.vibrate(new long[] {0, 200, 200, 200}, -1);
                  mTenMinuteWarning = false;
                } else if (mFiveMinuteWarning
                    && hoursLeft == 0
                    && minutesLeft == 5
                    && secondsLeft == 0) {
                  /* Buzz Buzz Buzz*/
                  mVibrator.vibrate(new long[] {0, 200, 200, 200, 200, 200}, -1);
                  mFiveMinuteWarning = false;
                }
              }

              /**
               * The countdown finished. Give one good vibration, remove the notification, clean up
               * the service, and call it a day.
               */
              @Override
              public void onFinish() {
                /* BUZZ */
                mVibrator.vibrate(600);
                /* Cleanup */
                mNotificationManager.cancel(NOTIFICATION_ID);
                unregisterReceiver(mBroadcastReceiver);
                CountdownService.this.stopSelfResult(mStartId);
              }
            };

        /* Start the countdown */
        mCountDownTimer.start();
      }
    }
  }