Skip to content

Most visited

Recently visited

navigation
FindMyPhone / Wearable / src / com.example.android.wearable.findphone /

DisconnectListenerService.java

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.Notification;
20
import android.app.NotificationManager;
21
import android.os.Bundle;
22
import android.util.Log;
23
 
24
import com.google.android.gms.common.api.GoogleApiClient;
25
import com.google.android.gms.common.api.ResultCallback;
26
import com.google.android.gms.wearable.CapabilityApi;
27
import com.google.android.gms.wearable.CapabilityInfo;
28
import com.google.android.gms.wearable.Node;
29
import com.google.android.gms.wearable.Wearable;
30
import com.google.android.gms.wearable.WearableListenerService;
31
 
32
import java.util.List;
33
import java.util.Set;
34
 
35
/**
36
 * Listens for changes in connectivity between this wear device and the phone. More precisely, we
37
 * need to distinguish the case that the wear device and the phone are connected directly from all
38
 * other possible cases. To this end, the phone app has registered itself to provide the "find_me"
39
 * capability and we need to look for connected nodes that provide this capability AND are nearby,
40
 * to exclude a connection through the cloud. The proper way would have been to use the
41
 * {@code onCapabilitiesChanged()} callback but currently that callback cannot discover the case
42
 * where a connection switches from wifi to direct; this shortcoming will be addressed in future
43
 * updates but for now we will use the {@code onConnectedNodes()} callback.
44
 */
45
public class DisconnectListenerService extends WearableListenerService
46
        implements GoogleApiClient.ConnectionCallbacks {
47
 
48
    private static final String TAG = "ExampleFindPhoneApp";
49
 
50
    private static final int FORGOT_PHONE_NOTIFICATION_ID = 1;
51
 
52
    /* the capability that the phone app would provide */
53
    private static final String FIND_ME_CAPABILITY_NAME = "find_me";
54
 
55
    private GoogleApiClient mGoogleApiClient;
56
 
57
    @Override
58
    public void onCreate() {
59
        super.onCreate();
60
        mGoogleApiClient = new GoogleApiClient.Builder(this)
61
                .addApi(Wearable.API)
62
                .addConnectionCallbacks(this)
63
                .build();
64
    }
65
 
66
    @Override
67
    public void onConnectedNodes(List<Node> connectedNodes) {
68
        // After we are notified by this callback, we need to query for the nodes that provide the
69
        // "find_me" capability and are directly connected.
70
        if (mGoogleApiClient.isConnected()) {
71
            setOrUpdateNotification();
72
        } else if (!mGoogleApiClient.isConnecting()) {
73
            mGoogleApiClient.connect();
74
        }
75
    }
76
 
77
    private void setOrUpdateNotification() {
78
        Wearable.CapabilityApi.getCapability(
79
                mGoogleApiClient, FIND_ME_CAPABILITY_NAME,
80
                CapabilityApi.FILTER_REACHABLE).setResultCallback(
81
                new ResultCallback<CapabilityApi.GetCapabilityResult>() {
82
                    @Override
83
                    public void onResult(CapabilityApi.GetCapabilityResult result) {
84
                        if (result.getStatus().isSuccess()) {
85
                            updateFindMeCapability(result.getCapability());
86
                        } else {
87
                            Log.e(TAG,
88
                                    "setOrUpdateNotification() Failed to get capabilities, "
89
                                            + "status: "
90
                                            + result.getStatus().getStatusMessage());
91
                        }
92
                    }
93
                });
94
    }
95
 
96
    private void updateFindMeCapability(CapabilityInfo capabilityInfo) {
97
        Set<Node> connectedNodes = capabilityInfo.getNodes();
98
        if (connectedNodes.isEmpty()) {
99
            setupLostConnectivityNotification();
100
        } else {
101
            for (Node node : connectedNodes) {
102
                // we are only considering those nodes that are directly connected
103
                if (node.isNearby()) {
104
                    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
105
                            .cancel(FORGOT_PHONE_NOTIFICATION_ID);
106
                }
107
            }
108
        }
109
    }
110
 
111
    /**
112
     * Creates a notification to inform user that the connectivity to phone has been lost (possibly
113
     * left the phone behind).
114
     */
115
    private void setupLostConnectivityNotification() {
116
        Notification.Builder notificationBuilder = new Notification.Builder(this)
117
                .setContentTitle(getString(R.string.left_phone_title))
118
                .setContentText(getString(R.string.left_phone_content))
119
                .setVibrate(new long[]{0, 200})  // Vibrate for 200 milliseconds.
120
                .setSmallIcon(R.drawable.ic_launcher)
121
                .setLocalOnly(true)
122
                .setPriority(Notification.PRIORITY_MAX);
123
        Notification card = notificationBuilder.build();
124
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE))
125
                .notify(FORGOT_PHONE_NOTIFICATION_ID, card);
126
    }
127
 
128
    @Override
129
    public void onConnected(Bundle bundle) {
130
        setOrUpdateNotification();
131
    }
132
 
133
    @Override
134
    public void onConnectionSuspended(int cause) {
135
 
136
    }
137
 
138
    @Override
139
    public void onDestroy() {
140
        if (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting()) {
141
            mGoogleApiClient.disconnect();
142
        }
143
        super.onDestroy();
144
    }
145
}
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?