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.findphone;
18 
19 import android.app.IntentService;
20 import android.content.Intent;
21 import android.os.Bundle;
22 import android.util.Log;
23 
24 import com.google.android.gms.common.ConnectionResult;
25 import com.google.android.gms.common.api.GoogleApiClient;
26 import com.google.android.gms.wearable.DataItemBuffer;
27 import com.google.android.gms.wearable.DataMap;
28 import com.google.android.gms.wearable.PutDataMapRequest;
29 import com.google.android.gms.wearable.Wearable;
30 
31 import java.util.concurrent.TimeUnit;
32 
33 /**
34  * Creates a sound on the paired phone to find it.
35  */
36 public class FindPhoneService extends IntentService implements GoogleApiClient.ConnectionCallbacks,
37         GoogleApiClient.OnConnectionFailedListener {
38 
39     private static final String TAG = "ExampleFindPhoneApp";
40 
41     private static final String FIELD_ALARM_ON = "alarm_on";
42     private static final String PATH_SOUND_ALARM = "/sound_alarm";
43     public static final String ACTION_TOGGLE_ALARM = "action_toggle_alarm";
44     public static final String ACTION_CANCEL_ALARM = "action_alarm_off";
45 
46     // Timeout for making a connection to GoogleApiClient (in milliseconds).
47     private static final long CONNECTION_TIME_OUT_MS = 100;
48     private GoogleApiClient mGoogleApiClient;
49 
FindPhoneService()50     public FindPhoneService() {
51         super(FindPhoneService.class.getSimpleName());
52     }
53 
54     @Override
onCreate()55     public void onCreate() {
56         super.onCreate();
57         mGoogleApiClient = new GoogleApiClient.Builder(this)
58                 .addApi(Wearable.API)
59                 .addConnectionCallbacks(this)
60                 .addOnConnectionFailedListener(this)
61                 .build();
62     }
63 
64     @Override
onHandleIntent(Intent intent)65     protected void onHandleIntent(Intent intent) {
66         mGoogleApiClient.blockingConnect(CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
67         if (Log.isLoggable(TAG, Log.VERBOSE)) {
68             Log.v(TAG, "FindPhoneService.onHandleIntent");
69         }
70         if (mGoogleApiClient.isConnected()) {
71             // Set the alarm off by default.
72             boolean alarmOn = false;
73             if (intent.getAction().equals(ACTION_TOGGLE_ALARM)) {
74                 // Get current state of the alarm.
75                 DataItemBuffer result = Wearable.DataApi.getDataItems(mGoogleApiClient).await();
76                 if (result.getStatus().isSuccess()) {
77                     if (result.getCount() == 1) {
78                         alarmOn = DataMap.fromByteArray(result.get(0).getData())
79                                 .getBoolean(FIELD_ALARM_ON, false);
80                     } else {
81                         Log.e(TAG, "Unexpected number of DataItems found.\n"
82                                  + "\tExpected: 1\n"
83                                  + "\tActual: " + result.getCount());
84                     }
85                 } else if (Log.isLoggable(TAG, Log.DEBUG)) {
86                     Log.d(TAG, "onHandleIntent: failed to get current alarm state");
87                 }
88                 result.close();
89                 // Toggle alarm.
90                 alarmOn = !alarmOn;
91                 // Change notification text based on new value of alarmOn.
92                 String notificationText = alarmOn ? getString(R.string.turn_alarm_off)
93                                                   : getString(R.string.turn_alarm_on);
94                 FindPhoneActivity.updateNotification(this, notificationText);
95             }
96             // Use alarmOn boolean to update the DataItem - phone will respond accordingly
97             // when it receives the change.
98             PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(PATH_SOUND_ALARM);
99             putDataMapRequest.getDataMap().putBoolean(FIELD_ALARM_ON, alarmOn);
100             Wearable.DataApi.putDataItem(mGoogleApiClient, putDataMapRequest.asPutDataRequest())
101                     .await();
102         } else {
103             Log.e(TAG, "Failed to toggle alarm on phone - Client disconnected from Google Play "
104                      + "Services");
105         }
106         mGoogleApiClient.disconnect();
107     }
108 
109     @Override
onConnected(Bundle connectionHint)110     public void onConnected(Bundle connectionHint) {
111     }
112 
113     @Override
onConnectionSuspended(int cause)114     public void onConnectionSuspended(int cause) {
115     }
116 
117     @Override
onConnectionFailed(ConnectionResult result)118     public void onConnectionFailed(ConnectionResult result) {
119     }
120 
121 }
122