Home | History | Annotate | Download | only in com.example.android.wearable.geofencing
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.wearable.geofencing;
     18 
     19 import static com.example.android.wearable.geofencing.Constants.CONNECTION_TIME_OUT_MS;
     20 import static com.example.android.wearable.geofencing.Constants.GEOFENCE_DATA_ITEM_PATH;
     21 import static com.example.android.wearable.geofencing.Constants.GEOFENCE_DATA_ITEM_URI;
     22 import static com.example.android.wearable.geofencing.Constants.KEY_GEOFENCE_ID;
     23 import static com.example.android.wearable.geofencing.Constants.TAG;
     24 
     25 import android.app.IntentService;
     26 import android.content.Context;
     27 import android.content.Intent;
     28 import android.os.Bundle;
     29 import android.os.Handler;
     30 import android.os.Looper;
     31 import android.util.Log;
     32 import android.widget.Toast;
     33 
     34 import com.google.android.gms.common.ConnectionResult;
     35 import com.google.android.gms.common.api.GoogleApiClient;
     36 import com.google.android.gms.location.Geofence;
     37 import com.google.android.gms.location.GeofencingEvent;
     38 import com.google.android.gms.wearable.PutDataMapRequest;
     39 import com.google.android.gms.wearable.Wearable;
     40 
     41 import java.util.concurrent.TimeUnit;
     42 
     43 /**
     44  * Listens for geofence transition changes.
     45  */
     46 public class GeofenceTransitionsIntentService extends IntentService
     47         implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
     48 
     49     private GoogleApiClient mGoogleApiClient;
     50 
     51     public GeofenceTransitionsIntentService() {
     52         super(GeofenceTransitionsIntentService.class.getSimpleName());
     53     }
     54 
     55     @Override
     56     public void onCreate() {
     57         super.onCreate();
     58         mGoogleApiClient = new GoogleApiClient.Builder(this)
     59                 .addApi(Wearable.API)
     60                 .addConnectionCallbacks(this)
     61                 .addOnConnectionFailedListener(this)
     62                 .build();
     63     }
     64 
     65     /**
     66      * Handles incoming intents.
     67      * @param intent The Intent sent by Location Services. This Intent is provided to Location
     68      * Services (inside a PendingIntent) when addGeofences() is called.
     69      */
     70     @Override
     71     protected void onHandleIntent(Intent intent) {
     72         GeofencingEvent geoFenceEvent = GeofencingEvent.fromIntent(intent);
     73         if (geoFenceEvent.hasError()) {
     74             int errorCode = geoFenceEvent.getErrorCode();
     75             Log.e(TAG, "Location Services error: " + errorCode);
     76         } else {
     77 
     78             int transitionType = geoFenceEvent.getGeofenceTransition();
     79             if (Geofence.GEOFENCE_TRANSITION_ENTER == transitionType) {
     80                 // Connect to the Google Api service in preparation for sending a DataItem.
     81                 mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
     82                 // Get the geofence id triggered. Note that only one geofence can be triggered at a
     83                 // time in this example, but in some cases you might want to consider the full list
     84                 // of geofences triggered.
     85                 String triggeredGeoFenceId = geoFenceEvent.getTriggeringGeofences().get(0)
     86                         .getRequestId();
     87                 // Create a DataItem with this geofence's id. The wearable can use this to create
     88                 // a notification.
     89                 final PutDataMapRequest putDataMapRequest =
     90                         PutDataMapRequest.create(GEOFENCE_DATA_ITEM_PATH);
     91                 putDataMapRequest.getDataMap().putString(KEY_GEOFENCE_ID, triggeredGeoFenceId);
     92                 putDataMapRequest.setUrgent();
     93                 if (mGoogleApiClient.isConnected()) {
     94                     Wearable.DataApi.putDataItem(
     95                             mGoogleApiClient, putDataMapRequest.asPutDataRequest()).await();
     96                 } else {
     97                     Log.e(TAG, "Failed to send data item: " + putDataMapRequest
     98                             + " - Client disconnected from Google Play Services");
     99                 }
    100                 Toast.makeText(this, getString(R.string.entering_geofence),
    101                         Toast.LENGTH_SHORT).show();
    102                 mGoogleApiClient.disconnect();
    103             } else if (Geofence.GEOFENCE_TRANSITION_EXIT == transitionType) {
    104                 // Delete the data item when leaving a geofence region.
    105                 mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
    106                 Wearable.DataApi.deleteDataItems(mGoogleApiClient, GEOFENCE_DATA_ITEM_URI).await();
    107                 showToast(this, R.string.exiting_geofence);
    108                 mGoogleApiClient.disconnect();
    109             }
    110         }
    111     }
    112 
    113     /**
    114      * Showing a toast message, using the Main thread
    115      */
    116     private void showToast(final Context context, final int resourceId) {
    117         Handler mainThread = new Handler(Looper.getMainLooper());
    118         mainThread.post(new Runnable() {
    119             @Override
    120             public void run() {
    121                 Toast.makeText(context, context.getString(resourceId), Toast.LENGTH_SHORT).show();
    122             }
    123         });
    124     }
    125 
    126     @Override
    127     public void onConnected(Bundle connectionHint) {
    128     }
    129 
    130     @Override
    131     public void onConnectionSuspended(int cause) {
    132     }
    133 
    134     @Override
    135     public void onConnectionFailed(ConnectionResult result) {
    136     }
    137 
    138 }
    139