/* * Copyright 2015 Google Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.xyztouristattractions.service; import android.app.IntentService; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.util.Log; import com.example.android.xyztouristattractions.R; import com.example.android.xyztouristattractions.common.Constants; import com.example.android.xyztouristattractions.common.Utils; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.wearable.CapabilityApi; import com.google.android.gms.wearable.Node; import com.google.android.gms.wearable.Wearable; import java.util.Iterator; import java.util.Set; import java.util.concurrent.TimeUnit; /** * A utility IntentService, used for a variety of asynchronous background * operations that do not necessarily need to be tied to a UI. */ public class UtilityService extends IntentService { private static final String TAG = UtilityService.class.getSimpleName(); private static final String ACTION_CLEAR_NOTIFICATION = "clear_notification"; private static final String ACTION_CLEAR_REMOTE_NOTIFICATIONS = "clear_remote_notifications"; private static final String ACTION_START_DEVICE_ACTIVITY = "start_device_activity"; private static final String EXTRA_START_PATH = "start_path"; private static final String EXTRA_START_ACTIVITY_INFO = "start_activity_info"; private static final long GET_CAPABILITY_TIMEOUT_S = 10; public static void clearNotification(Context context) { Intent intent = new Intent(context, UtilityService.class); intent.setAction(UtilityService.ACTION_CLEAR_NOTIFICATION); context.startService(intent); } public static void clearRemoteNotifications(Context context) { context.startService(getClearRemoteNotificationsIntent(context)); } public static Intent getClearRemoteNotificationsIntent(Context context) { Intent intent = new Intent(context, UtilityService.class); intent.setAction(UtilityService.ACTION_CLEAR_REMOTE_NOTIFICATIONS); return intent; } /** * Trigger a message that asks the master device to start an activity. * * @param context the context * @param path the path that will be sent via the wearable message API * @param name the tourist attraction name * @param city the tourist attraction city */ public static void startDeviceActivity(Context context, String path, String name, String city) { Intent intent = new Intent(context, UtilityService.class); intent.setAction(UtilityService.ACTION_START_DEVICE_ACTIVITY); String extraInfo; if (Constants.START_ATTRACTION_PATH.equals(path)) { extraInfo = name; } else { extraInfo = name + ", " + city; } intent.putExtra(EXTRA_START_ACTIVITY_INFO, extraInfo); intent.putExtra(EXTRA_START_PATH, path); context.startService(intent); } public UtilityService() { super(TAG); } @Override protected void onHandleIntent(Intent intent) { String action = intent != null ? intent.getAction() : null; if (ACTION_CLEAR_NOTIFICATION.equals(action)) { clearNotificationInternal(); } else if (ACTION_CLEAR_REMOTE_NOTIFICATIONS.equals(action)) { clearRemoteNotificationsInternal(); } else if (ACTION_START_DEVICE_ACTIVITY.equals(action)) { startDeviceActivityInternal(intent.getStringExtra(EXTRA_START_PATH), intent.getStringExtra(EXTRA_START_ACTIVITY_INFO)); } } /** * Clear the local notifications */ private void clearNotificationInternal() { NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notificationManager.cancel(Constants.WEAR_NOTIFICATION_ID); } /** * Trigger a message to ask other devices to clear their notifications */ private void clearRemoteNotificationsInternal() { GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .build(); ConnectionResult connectionResult = googleApiClient.blockingConnect( Constants.GOOGLE_API_CLIENT_TIMEOUT_S, TimeUnit.SECONDS); if (connectionResult.isSuccess() && googleApiClient.isConnected()) { Iterator itr = Utils.getNodes(googleApiClient).iterator(); while (itr.hasNext()) { // Loop through all connected nodes Wearable.MessageApi.sendMessage( googleApiClient, itr.next(), Constants.CLEAR_NOTIFICATIONS_PATH, null); } } googleApiClient.disconnect(); } /** * Sends the actual message to ask other devices that are capable of showing "details" to start * the appropriate activity * * @param path the path to pass to the wearable message API * @param extraInfo extra info that varies based on the path being sent */ private void startDeviceActivityInternal(String path, String extraInfo) { GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this) .addApi(Wearable.API) .build(); ConnectionResult connectionResult = googleApiClient.blockingConnect( Constants.GOOGLE_API_CLIENT_TIMEOUT_S, TimeUnit.SECONDS); if (connectionResult.isSuccess() && googleApiClient.isConnected()) { CapabilityApi.GetCapabilityResult result = Wearable.CapabilityApi.getCapability( googleApiClient, getApplicationContext().getString(R.string.show_detail_capability_name), CapabilityApi.FILTER_REACHABLE) .await(GET_CAPABILITY_TIMEOUT_S, TimeUnit.SECONDS); if (result.getStatus().isSuccess()) { Set nodes = result.getCapability().getNodes(); for (Node node : nodes) { Wearable.MessageApi.sendMessage( googleApiClient, node.getId(), path, extraInfo.getBytes()); } } else { Log.e(TAG, "startDeviceActivityInternal() Failed to get capabilities, status: " + result.getStatus().getStatusMessage()); } googleApiClient.disconnect(); } } }