Skip to content

Most visited

Recently visited

navigation
DataLayer / Wearable / src / com.example.android.wearable.datalayer /

MainActivity.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.datalayer;
18
 
19
import static com.example.android.wearable.datalayer.DataLayerListenerService.LOGD;
20
 
21
import android.app.Activity;
22
import android.app.Fragment;
23
import android.app.FragmentManager;
24
import android.graphics.Bitmap;
25
import android.graphics.BitmapFactory;
26
import android.net.Uri;
27
import android.os.AsyncTask;
28
import android.os.Bundle;
29
import android.support.wearable.view.DotsPageIndicator;
30
import android.support.wearable.view.FragmentGridPagerAdapter;
31
import android.support.wearable.view.GridViewPager;
32
import android.text.TextUtils;
33
import android.util.Log;
34
import android.view.View;
35
import android.view.WindowManager;
36
import android.widget.Toast;
37
 
38
import com.example.android.wearable.datalayer.fragments.AssetFragment;
39
import com.example.android.wearable.datalayer.fragments.DataFragment;
40
import com.example.android.wearable.datalayer.fragments.DiscoveryFragment;
41
import com.google.android.gms.common.ConnectionResult;
42
import com.google.android.gms.common.api.GoogleApiClient;
43
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
44
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
45
import com.google.android.gms.common.api.PendingResult;
46
import com.google.android.gms.common.api.ResultCallback;
47
import com.google.android.gms.wearable.Asset;
48
import com.google.android.gms.wearable.CapabilityApi;
49
import com.google.android.gms.wearable.CapabilityInfo;
50
import com.google.android.gms.wearable.DataApi;
51
import com.google.android.gms.wearable.DataEvent;
52
import com.google.android.gms.wearable.DataEventBuffer;
53
import com.google.android.gms.wearable.DataMapItem;
54
import com.google.android.gms.wearable.MessageApi;
55
import com.google.android.gms.wearable.MessageEvent;
56
import com.google.android.gms.wearable.Node;
57
import com.google.android.gms.wearable.Wearable;
58
 
59
import java.io.InputStream;
60
import java.util.ArrayList;
61
import java.util.HashSet;
62
import java.util.List;
63
import java.util.Map;
64
import java.util.Set;
65
 
66
/**
67
 * The main activity with a view pager, containing three pages:<p/>
68
 * <ul>
69
 * <li>
70
 * Page 1: shows a list of DataItems received from the phone application
71
 * </li>
72
 * <li>
73
 * Page 2: shows the photo that is sent from the phone application
74
 * </li>
75
 * <li>
76
 * Page 3: includes two buttons to show the connected phone and watch devices
77
 * </li>
78
 * </ul>
79
 */
80
public class MainActivity extends Activity implements
81
        ConnectionCallbacks,
82
        OnConnectionFailedListener,
83
        DataApi.DataListener,
84
        MessageApi.MessageListener,
85
        CapabilityApi.CapabilityListener {
86
 
87
    private static final String TAG = "MainActivity";
88
    private static final String CAPABILITY_1_NAME = "capability_1";
89
    private static final String CAPABILITY_2_NAME = "capability_2";
90
 
91
    private GoogleApiClient mGoogleApiClient;
92
    private GridViewPager mPager;
93
    private DataFragment mDataFragment;
94
    private AssetFragment mAssetFragment;
95
 
96
    @Override
97
    public void onCreate(Bundle savedInstanceState) {
98
        super.onCreate(savedInstanceState);
99
        setContentView(R.layout.main_activity);
100
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
101
        setupViews();
102
        mGoogleApiClient = new GoogleApiClient.Builder(this)
103
                .addApi(Wearable.API)
104
                .addConnectionCallbacks(this)
105
                .addOnConnectionFailedListener(this)
106
                .build();
107
    }
108
 
109
    @Override
110
    protected void onResume() {
111
        super.onResume();
112
        mGoogleApiClient.connect();
113
    }
114
 
115
    @Override
116
    protected void onPause() {
117
        if ((mGoogleApiClient != null) && mGoogleApiClient.isConnected()) {
118
            Wearable.DataApi.removeListener(mGoogleApiClient, this);
119
            Wearable.MessageApi.removeListener(mGoogleApiClient, this);
120
            Wearable.CapabilityApi.removeListener(mGoogleApiClient, this);
121
            mGoogleApiClient.disconnect();
122
        }
123
 
124
        super.onPause();
125
    }
126
 
127
    @Override
128
    public void onConnected(Bundle connectionHint) {
129
        LOGD(TAG, "onConnected(): Successfully connected to Google API client");
130
        Wearable.DataApi.addListener(mGoogleApiClient, this);
131
        Wearable.MessageApi.addListener(mGoogleApiClient, this);
132
        Wearable.CapabilityApi.addListener(
133
                mGoogleApiClient, this, Uri.parse("wear://"), CapabilityApi.FILTER_REACHABLE);
134
    }
135
 
136
    @Override
137
    public void onConnectionSuspended(int cause) {
138
        LOGD(TAG, "onConnectionSuspended(): Connection to Google API client was suspended");
139
    }
140
 
141
    @Override
142
    public void onConnectionFailed(ConnectionResult result) {
143
        Log.e(TAG, "onConnectionFailed(): Failed to connect, with result: " + result);
144
    }
145
 
146
    @Override
147
    public void onDataChanged(DataEventBuffer dataEvents) {
148
        LOGD(TAG, "onDataChanged(): " + dataEvents);
149
 
150
        for (DataEvent event : dataEvents) {
151
            if (event.getType() == DataEvent.TYPE_CHANGED) {
152
                String path = event.getDataItem().getUri().getPath();
153
                if (DataLayerListenerService.IMAGE_PATH.equals(path)) {
154
                    DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
155
                    Asset photoAsset = dataMapItem.getDataMap()
156
                            .getAsset(DataLayerListenerService.IMAGE_KEY);
157
                    // Loads image on background thread.
158
                    new LoadBitmapAsyncTask().execute(photoAsset);
159
 
160
                } else if (DataLayerListenerService.COUNT_PATH.equals(path)) {
161
                    LOGD(TAG, "Data Changed for COUNT_PATH");
162
                    mDataFragment.appendItem("DataItem Changed", event.getDataItem().toString());
163
                } else {
164
                    LOGD(TAG, "Unrecognized path: " + path);
165
                }
166
 
167
            } else if (event.getType() == DataEvent.TYPE_DELETED) {
168
                mDataFragment.appendItem("DataItem Deleted", event.getDataItem().toString());
169
            } else {
170
                mDataFragment.appendItem("Unknown data event type", "Type = " + event.getType());
171
            }
172
        }
173
    }
174
 
175
    public void onClicked(View view) {
176
        switch (view.getId()) {
177
            case R.id.capability_2_btn:
178
                showNodes(CAPABILITY_2_NAME);
179
                break;
180
            case R.id.capabilities_1_and_2_btn:
181
                showNodes(CAPABILITY_1_NAME, CAPABILITY_2_NAME);
182
                break;
183
            default:
184
                Log.e(TAG, "Unknown click event registered");
185
        }
186
    }
187
 
188
    /**
189
     * Find the connected nodes that provide at least one of the given capabilities
190
     */
191
    private void showNodes(final String... capabilityNames) {
192
 
193
        PendingResult<CapabilityApi.GetAllCapabilitiesResult> pendingCapabilityResult =
194
                Wearable.CapabilityApi.getAllCapabilities(
195
                        mGoogleApiClient,
196
                        CapabilityApi.FILTER_REACHABLE);
197
 
198
        pendingCapabilityResult.setResultCallback(
199
                new ResultCallback<CapabilityApi.GetAllCapabilitiesResult>() {
200
                    @Override
201
                    public void onResult(
202
                            CapabilityApi.GetAllCapabilitiesResult getAllCapabilitiesResult) {
203
 
204
                        if (!getAllCapabilitiesResult.getStatus().isSuccess()) {
205
                            Log.e(TAG, "Failed to get capabilities");
206
                            return;
207
                        }
208
 
209
                        Map<String, CapabilityInfo> capabilitiesMap =
210
                                getAllCapabilitiesResult.getAllCapabilities();
211
                        Set<Node> nodes = new HashSet<>();
212
 
213
                        if (capabilitiesMap.isEmpty()) {
214
                            showDiscoveredNodes(nodes);
215
                            return;
216
                        }
217
                        for (String capabilityName : capabilityNames) {
218
                            CapabilityInfo capabilityInfo = capabilitiesMap.get(capabilityName);
219
                            if (capabilityInfo != null) {
220
                                nodes.addAll(capabilityInfo.getNodes());
221
                            }
222
                        }
223
                        showDiscoveredNodes(nodes);
224
                    }
225
 
226
                    private void showDiscoveredNodes(Set<Node> nodes) {
227
                        List<String> nodesList = new ArrayList<>();
228
                        for (Node node : nodes) {
229
                            nodesList.add(node.getDisplayName());
230
                        }
231
                        LOGD(TAG, "Connected Nodes: " + (nodesList.isEmpty()
232
                                ? "No connected device was found for the given capabilities"
233
                                : TextUtils.join(",", nodesList)));
234
                        String msg;
235
                        if (!nodesList.isEmpty()) {
236
                            msg = getString(R.string.connected_nodes,
237
                                    TextUtils.join(", ", nodesList));
238
                        } else {
239
                            msg = getString(R.string.no_device);
240
                        }
241
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
242
                    }
243
                });
244
    }
245
 
246
    @Override
247
    public void onMessageReceived(MessageEvent event) {
248
        LOGD(TAG, "onMessageReceived: " + event);
249
        mDataFragment.appendItem("Message", event.toString());
250
    }
251
 
252
    @Override
253
    public void onCapabilityChanged(CapabilityInfo capabilityInfo) {
254
        LOGD(TAG, "onCapabilityChanged: " + capabilityInfo);
255
        mDataFragment.appendItem("onCapabilityChanged", capabilityInfo.toString());
256
    }
257
 
258
    private void setupViews() {
259
        mPager = (GridViewPager) findViewById(R.id.pager);
260
        mPager.setOffscreenPageCount(2);
261
        DotsPageIndicator dotsPageIndicator = (DotsPageIndicator) findViewById(R.id.page_indicator);
262
        dotsPageIndicator.setDotSpacing((int) getResources().getDimension(R.dimen.dots_spacing));
263
        dotsPageIndicator.setPager(mPager);
264
        mDataFragment = new DataFragment();
265
        mAssetFragment = new AssetFragment();
266
        DiscoveryFragment discoveryFragment = new DiscoveryFragment();
267
        List<Fragment> pages = new ArrayList<>();
268
        pages.add(mDataFragment);
269
        pages.add(mAssetFragment);
270
        pages.add(discoveryFragment);
271
        final MyPagerAdapter adapter = new MyPagerAdapter(getFragmentManager(), pages);
272
        mPager.setAdapter(adapter);
273
    }
274
 
275
    /**
276
     * Switches to the page {@code index}. The first page has index 0.
277
     */
278
    private void moveToPage(int index) {
279
        mPager.setCurrentItem(0, index, true);
280
    }
281
 
282
    private class MyPagerAdapter extends FragmentGridPagerAdapter {
283
 
284
        private List<Fragment> mFragments;
285
 
286
        public MyPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
287
            super(fm);
288
            mFragments = fragments;
289
        }
290
 
291
        @Override
292
        public int getRowCount() {
293
            return 1;
294
        }
295
 
296
        @Override
297
        public int getColumnCount(int row) {
298
            return mFragments == null ? 0 : mFragments.size();
299
        }
300
 
301
        @Override
302
        public Fragment getFragment(int row, int column) {
303
            return mFragments.get(column);
304
        }
305
 
306
    }
307
 
308
    /*
309
     * Extracts {@link android.graphics.Bitmap} data from the
310
     * {@link com.google.android.gms.wearable.Asset}
311
     */
312
    private class LoadBitmapAsyncTask extends AsyncTask<Asset, Void, Bitmap> {
313
 
314
        @Override
315
        protected Bitmap doInBackground(Asset... params) {
316
 
317
            if (params.length > 0) {
318
 
319
                Asset asset = params[0];
320
 
321
                InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
322