Skip to content

Most visited

Recently visited

navigation
RuntimePermissionsWear / Wearable / src / com.example.android.wearable.runtimepermissions /

IncomingRequestWearService.java

1
/*
2
 * Copyright (C) 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.wearable.runtimepermissions;
18
 
19
import android.Manifest;
20
import android.content.Intent;
21
import android.content.pm.PackageManager;
22
import android.hardware.Sensor;
23
import android.hardware.SensorManager;
24
import android.support.v4.app.ActivityCompat;
25
import android.util.Log;
26
 
27
import com.example.android.wearable.runtimepermissions.common.Constants;
28
 
29
import com.google.android.gms.common.ConnectionResult;
30
import com.google.android.gms.common.api.GoogleApiClient;
31
import com.google.android.gms.common.api.PendingResult;
32
import com.google.android.gms.wearable.CapabilityApi;
33
import com.google.android.gms.wearable.CapabilityInfo;
34
import com.google.android.gms.wearable.DataMap;
35
import com.google.android.gms.wearable.MessageApi;
36
import com.google.android.gms.wearable.MessageEvent;
37
import com.google.android.gms.wearable.Node;
38
import com.google.android.gms.wearable.Wearable;
39
import com.google.android.gms.wearable.WearableListenerService;
40
 
41
import java.util.List;
42
import java.util.Set;
43
import java.util.concurrent.TimeUnit;
44
 
45
/**
46
 * Handles all incoming requests for wear data (and permissions) from phone devices.
47
 */
48
public class IncomingRequestWearService extends WearableListenerService {
49
 
50
    private static final String TAG = "IncomingRequestService";
51
 
52
    public IncomingRequestWearService() {
53
        Log.d(TAG, "IncomingRequestWearService()");
54
    }
55
 
56
    @Override
57
    public void onCreate() {
58
        super.onCreate();
59
        Log.d(TAG, "onCreate()");
60
    }
61
 
62
    @Override
63
    public void onMessageReceived(MessageEvent messageEvent) {
64
        Log.d(TAG, "onMessageReceived(): " + messageEvent);
65
 
66
        String messagePath = messageEvent.getPath();
67
 
68
        if (messagePath.equals(Constants.MESSAGE_PATH_WEAR)) {
69
            DataMap dataMap = DataMap.fromByteArray(messageEvent.getData());
70
 
71
            int requestType = dataMap.getInt(Constants.KEY_COMM_TYPE);
72
 
73
            if (requestType == Constants.COMM_TYPE_REQUEST_PROMPT_PERMISSION) {
74
                promptUserForSensorPermission();
75
 
76
            } else if (requestType == Constants.COMM_TYPE_REQUEST_DATA) {
77
                respondWithSensorInformation();
78
            }
79
        }
80
    }
81
 
82
    private void promptUserForSensorPermission() {
83
        Log.d(TAG, "promptUserForSensorPermission()");
84
 
85
        boolean sensorPermissionApproved =
86
                ActivityCompat.checkSelfPermission(this, Manifest.permission.BODY_SENSORS)
87
                        == PackageManager.PERMISSION_GRANTED;
88
 
89
        if (sensorPermissionApproved) {
90
            DataMap dataMap = new DataMap();
91
            dataMap.putInt(Constants.KEY_COMM_TYPE,
92
                    Constants.COMM_TYPE_RESPONSE_USER_APPROVED_PERMISSION);
93
            sendMessage(dataMap);
94
        } else {
95
            // Launch Activity to grant sensor permissions.
96
            Intent startIntent = new Intent(this, MainWearActivity.class);
97
            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
98
            startIntent.putExtra(MainWearActivity.EXTRA_PROMPT_PERMISSION_FROM_PHONE, true);
99
            startActivity(startIntent);
100
        }
101
    }
102
 
103
    private void respondWithSensorInformation() {
104
        Log.d(TAG, "respondWithSensorInformation()");
105
 
106
        boolean sensorPermissionApproved =
107
                ActivityCompat.checkSelfPermission(this, Manifest.permission.BODY_SENSORS)
108
                        == PackageManager.PERMISSION_GRANTED;
109
 
110
        if (!sensorPermissionApproved) {
111
            DataMap dataMap = new DataMap();
112
            dataMap.putInt(Constants.KEY_COMM_TYPE,
113
                    Constants.COMM_TYPE_RESPONSE_PERMISSION_REQUIRED);
114
            sendMessage(dataMap);
115
        } else {
116
            /* To keep the sample simple, we are only displaying the number of sensors. You could do
117
             * something much more complicated.
118
             */
119
            SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
120
            List<Sensor> sensorList = sensorManager.getSensorList(Sensor.TYPE_ALL);
121
            int numberOfSensorsOnDevice = sensorList.size();
122
 
123
            String sensorSummary = numberOfSensorsOnDevice + " sensors on wear device(s)!";
124
            DataMap dataMap = new DataMap();
125
            dataMap.putInt(Constants.KEY_COMM_TYPE,
126
                    Constants.COMM_TYPE_RESPONSE_DATA);
127
            dataMap.putString(Constants.KEY_PAYLOAD, sensorSummary);
128
            sendMessage(dataMap);
129
        }
130
    }
131
 
132
    private void sendMessage(DataMap dataMap) {
133
 
134
        Log.d(TAG, "sendMessage(): " + dataMap);
135
 
136
        GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
137
                .addApi(Wearable.API)
138
                .build();
139
        ConnectionResult connectionResult =
140
                googleApiClient.blockingConnect(
141
                        Constants.CONNECTION_TIME_OUT_MS,
142
                        TimeUnit.MILLISECONDS);
143
 
144
        if (!connectionResult.isSuccess()) {
145
            Log.d(TAG, "Google API Client failed to connect.");
146
            return;
147
        }
148
 
149
        PendingResult<CapabilityApi.GetCapabilityResult> pendingCapabilityResult =
150
                Wearable.CapabilityApi.getCapability(
151
                        googleApiClient,
152
                        Constants.CAPABILITY_PHONE_APP,
153
                        CapabilityApi.FILTER_REACHABLE);
154
 
155
        CapabilityApi.GetCapabilityResult getCapabilityResult =
156
                pendingCapabilityResult.await(
157
                        Constants.CONNECTION_TIME_OUT_MS,
158
                        TimeUnit.MILLISECONDS);
159
 
160
        if (!getCapabilityResult.getStatus().isSuccess()) {
161
            Log.d(TAG, "CapabilityApi failed to return any results.");
162
            googleApiClient.disconnect();
163
            return;
164
        }
165
 
166
        CapabilityInfo capabilityInfo = getCapabilityResult.getCapability();
167
        String phoneNodeId = pickBestNodeId(capabilityInfo.getNodes());
168
 
169
        PendingResult<MessageApi.SendMessageResult> pendingMessageResult =
170
                Wearable.MessageApi.sendMessage(
171
                        googleApiClient,
172
                        phoneNodeId,
173
                        Constants.MESSAGE_PATH_PHONE,
174
                        dataMap.toByteArray());
175
 
176
        MessageApi.SendMessageResult sendMessageResult =
177
                pendingMessageResult.await(Constants.CONNECTION_TIME_OUT_MS, TimeUnit.MILLISECONDS);
178
 
179
        if (!sendMessageResult.getStatus().isSuccess()) {
180
            Log.d(TAG, "Sending message failed, onResult: " + sendMessageResult.getStatus());
181
        } else {
182
            Log.d(TAG, "Message sent successfully");
183
        }
184
 
185
        googleApiClient.disconnect();
186
    }
187
 
188
    /*
189
     * There should only ever be one phone in a node set (much less w/ the correct capability), so
190
     * I am just grabbing the first one (which should be the only one).
191
     */
192
    private String pickBestNodeId(Set<Node> nodes) {
193
 
194
        Log.d(TAG, "pickBestNodeId: " + nodes);
195
 
196
 
197
        String bestNodeId = null;
198
        /* Find a nearby node or pick one arbitrarily. There should be only one phone connected
199
         * that supports this sample.
200
         */
201
        for (Node node : nodes) {
202
            if (node.isNearby()) {
203
                return node.getId();
204
            }
205
            bestNodeId = node.getId();
206
        }
207
        return bestNodeId;
208
    }
209
}
This site uses cookies to store your preferences for site-specific language and display options.

Hooray!