Skip to content

Most visited

Recently visited

navigation
XYZTouristAttractions / Wearable / src / com.example.android.xyztouristattractions / service /

UtilityService.java

1
/*
2
 * Copyright 2015 Google Inc. All rights reserved.
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.xyztouristattractions.service;
18
 
19
import android.app.IntentService;
20
import android.app.NotificationManager;
21
import android.content.Context;
22
import android.content.Intent;
23
import android.util.Log;
24
 
25
import com.example.android.xyztouristattractions.R;
26
import com.example.android.xyztouristattractions.common.Constants;
27
import com.example.android.xyztouristattractions.common.Utils;
28
import com.google.android.gms.common.ConnectionResult;
29
import com.google.android.gms.common.api.GoogleApiClient;
30
import com.google.android.gms.wearable.CapabilityApi;
31
import com.google.android.gms.wearable.Node;
32
import com.google.android.gms.wearable.Wearable;
33
 
34
import java.util.Iterator;
35
import java.util.Set;
36
import java.util.concurrent.TimeUnit;
37
 
38
/**
39
 * A utility IntentService, used for a variety of asynchronous background
40
 * operations that do not necessarily need to be tied to a UI.
41
 */
42
public class UtilityService extends IntentService {
43
 
44
    private static final String TAG = UtilityService.class.getSimpleName();
45
 
46
    private static final String ACTION_CLEAR_NOTIFICATION = "clear_notification";
47
    private static final String ACTION_CLEAR_REMOTE_NOTIFICATIONS = "clear_remote_notifications";
48
    private static final String ACTION_START_DEVICE_ACTIVITY = "start_device_activity";
49
    private static final String EXTRA_START_PATH = "start_path";
50
    private static final String EXTRA_START_ACTIVITY_INFO = "start_activity_info";
51
    private static final long GET_CAPABILITY_TIMEOUT_S = 10;
52
 
53
    public static void clearNotification(Context context) {
54
        Intent intent = new Intent(context, UtilityService.class);
55
        intent.setAction(UtilityService.ACTION_CLEAR_NOTIFICATION);
56
        context.startService(intent);
57
    }
58
 
59
    public static void clearRemoteNotifications(Context context) {
60
        context.startService(getClearRemoteNotificationsIntent(context));
61
    }
62
 
63
    public static Intent getClearRemoteNotificationsIntent(Context context) {
64
        Intent intent = new Intent(context, UtilityService.class);
65
        intent.setAction(UtilityService.ACTION_CLEAR_REMOTE_NOTIFICATIONS);
66
        return intent;
67
    }
68
 
69
    /**
70
     * Trigger a message that asks the master device to start an activity.
71
     *
72
     * @param context the context
73
     * @param path the path that will be sent via the wearable message API
74
     * @param name the tourist attraction name
75
     * @param city the tourist attraction city
76
     */
77
    public static void startDeviceActivity(Context context, String path, String name, String city) {
78
        Intent intent = new Intent(context, UtilityService.class);
79
        intent.setAction(UtilityService.ACTION_START_DEVICE_ACTIVITY);
80
        String extraInfo;
81
        if (Constants.START_ATTRACTION_PATH.equals(path)) {
82
            extraInfo = name;
83
        } else {
84
            extraInfo = name + ", " + city;
85
        }
86
        intent.putExtra(EXTRA_START_ACTIVITY_INFO, extraInfo);
87
        intent.putExtra(EXTRA_START_PATH, path);
88
        context.startService(intent);
89
    }
90
 
91
    public UtilityService() {
92
        super(TAG);
93
    }
94
 
95
    @Override
96
    protected void onHandleIntent(Intent intent) {
97
        String action = intent != null ? intent.getAction() : null;
98
        if (ACTION_CLEAR_NOTIFICATION.equals(action)) {
99
            clearNotificationInternal();
100
        } else if (ACTION_CLEAR_REMOTE_NOTIFICATIONS.equals(action)) {
101
            clearRemoteNotificationsInternal();
102
        } else if (ACTION_START_DEVICE_ACTIVITY.equals(action)) {
103
            startDeviceActivityInternal(intent.getStringExtra(EXTRA_START_PATH),
104
                    intent.getStringExtra(EXTRA_START_ACTIVITY_INFO));
105
        }
106
    }
107
 
108
    /**
109
     * Clear the local notifications
110
     */
111
    private void clearNotificationInternal() {
112
        NotificationManager notificationManager =
113
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
114
        notificationManager.cancel(Constants.WEAR_NOTIFICATION_ID);
115
    }
116
 
117
    /**
118
     * Trigger a message to ask other devices to clear their notifications
119
     */
120
    private void clearRemoteNotificationsInternal() {
121
        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
122
                .addApi(Wearable.API)
123
                .build();
124
 
125
        ConnectionResult connectionResult = googleApiClient.blockingConnect(
126
                Constants.GOOGLE_API_CLIENT_TIMEOUT_S, TimeUnit.SECONDS);
127
 
128
        if (connectionResult.isSuccess() && googleApiClient.isConnected()) {
129
            Iterator<String> itr = Utils.getNodes(googleApiClient).iterator();
130
            while (itr.hasNext()) {
131
                // Loop through all connected nodes
132
                Wearable.MessageApi.sendMessage(
133
                        googleApiClient, itr.next(), Constants.CLEAR_NOTIFICATIONS_PATH, null);
134
            }
135
        }
136
 
137
        googleApiClient.disconnect();
138
    }
139
 
140
    /**
141
     * Sends the actual message to ask other devices that are capable of showing "details" to start
142
     * the appropriate activity
143
     *
144
     * @param path the path to pass to the wearable message API
145
     * @param extraInfo extra info that varies based on the path being sent
146
     */
147
    private void startDeviceActivityInternal(String path, String extraInfo) {
148
        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
149
                .addApi(Wearable.API)
150
                .build();
151
 
152
        ConnectionResult connectionResult = googleApiClient.blockingConnect(
153
                Constants.GOOGLE_API_CLIENT_TIMEOUT_S, TimeUnit.SECONDS);
154
 
155
        if (connectionResult.isSuccess() && googleApiClient.isConnected()) {
156
            CapabilityApi.GetCapabilityResult result = Wearable.CapabilityApi.getCapability(
157
                    googleApiClient,
158
                    getApplicationContext().getString(R.string.show_detail_capability_name),
159
                    CapabilityApi.FILTER_REACHABLE)
160
                    .await(GET_CAPABILITY_TIMEOUT_S, TimeUnit.SECONDS);
161
            if (result.getStatus().isSuccess()) {
162
                Set<Node> nodes = result.getCapability().getNodes();
163
                for (Node node : nodes) {
164
                    Wearable.MessageApi.sendMessage(
165
                            googleApiClient, node.getId(), path, extraInfo.getBytes());
166
                }
167
            } else {
168
                Log.e(TAG, "startDeviceActivityInternal() Failed to get capabilities, status: "
169
                        + result.getStatus().getStatusMessage());
170
            }
171
 
172
            googleApiClient.disconnect();
173
        }
174
    }
175
 
176
}
This site uses cookies to store your preferences for site-specific language and display options.

Hooray!

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.