Skip to content

Most visited

Recently visited

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

AttractionsActivity.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.ui;
18
 
19
import android.app.Activity;
20
import android.content.Context;
21
import android.graphics.Rect;
22
import android.net.Uri;
23
import android.os.AsyncTask;
24
import android.os.Bundle;
25
import android.support.v4.view.GestureDetectorCompat;
26
import android.support.wearable.view.DismissOverlayView;
27
import android.support.wearable.view.DotsPageIndicator;
28
import android.support.wearable.view.GridViewPager;
29
import android.util.Log;
30
import android.view.GestureDetector;
31
import android.view.MotionEvent;
32
import android.view.View;
33
import android.view.WindowInsets;
34
import android.widget.FrameLayout;
35
import android.widget.ProgressBar;
36
 
37
import com.example.android.xyztouristattractions.R;
38
import com.example.android.xyztouristattractions.common.Attraction;
39
import com.example.android.xyztouristattractions.common.Constants;
40
import com.example.android.xyztouristattractions.common.Utils;
41
import com.example.android.xyztouristattractions.service.UtilityService;
42
import com.google.android.gms.common.ConnectionResult;
43
import com.google.android.gms.common.api.GoogleApiClient;
44
import com.google.android.gms.maps.model.LatLng;
45
import com.google.android.gms.wearable.DataApi;
46
import com.google.android.gms.wearable.DataMap;
47
import com.google.android.gms.wearable.DataMapItem;
48
import com.google.android.gms.wearable.Wearable;
49
 
50
import java.util.ArrayList;
51
import java.util.Iterator;
52
import java.util.List;
53
import java.util.concurrent.TimeUnit;
54
 
55
/**
56
 * The main Wear activity that displays nearby attractions in a
57
 * {@link android.support.wearable.view.GridViewPager}. Each row shows
58
 * one attraction and each column shows information or actions for that
59
 * particular attraction.
60
 */
61
public class AttractionsActivity extends Activity
62
        implements AttractionsGridPagerAdapter.OnChromeFadeListener {
63
    private static final String TAG = AttractionsActivity.class.getSimpleName();
64
 
65
    private GestureDetectorCompat mGestureDetector;
66
    private DismissOverlayView mDismissOverlayView;
67
    private GridViewPager mGridViewPager;
68
    private AttractionsGridPagerAdapter mAdapter;
69
    private DotsPageIndicator mDotsPageIndicator;
70
    private ProgressBar mProgressBar;
71
    private Rect mInsets = new Rect(0, 0, 0, 0);
72
 
73
    private ArrayList<Attraction> mAttractions = new ArrayList<Attraction>();
74
 
75
    @Override
76
    protected void onCreate(Bundle savedInstanceState) {
77
        super.onCreate(savedInstanceState);
78
 
79
        setContentView(R.layout.activity_main);
80
        final FrameLayout topFrameLayout = (FrameLayout) findViewById(R.id.topFrameLayout);
81
        mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
82
        mGridViewPager = (GridViewPager) findViewById(R.id.gridViewPager);
83
        mDotsPageIndicator = (DotsPageIndicator) findViewById(R.id.dotsPageIndicator);
84
        mAdapter = new AttractionsGridPagerAdapter(this, mAttractions);
85
        mAdapter.setOnChromeFadeListener(this);
86
        mGridViewPager.setAdapter(mAdapter);
87
        mDotsPageIndicator.setPager(mGridViewPager);
88
        mDotsPageIndicator.setOnPageChangeListener(mAdapter);
89
 
90
        topFrameLayout.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
91
            @Override
92
            public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
93
                // Call through to super implementation
94
                insets = topFrameLayout.onApplyWindowInsets(insets);
95
 
96
                boolean round = insets.isRound();
97
 
98
                // Store system window insets regardless of screen shape
99
                mInsets.set(insets.getSystemWindowInsetLeft(),
100
                        insets.getSystemWindowInsetTop(),
101
                        insets.getSystemWindowInsetRight(),
102
                        insets.getSystemWindowInsetBottom());
103
 
104
                if (round) {
105
                    // On a round screen calculate the square inset to use.
106
                    // Alternatively could use BoxInsetLayout, although calculating
107
                    // the inset ourselves lets us position views outside the center
108
                    // box. For example, slightly lower on the round screen (by giving
109
                    // up some horizontal space).
110
                    mInsets = Utils.calculateBottomInsetsOnRoundDevice(
111
                            getWindowManager().getDefaultDisplay(), mInsets);
112
 
113
                    // Boost the dots indicator up by the bottom inset
114
                    FrameLayout.LayoutParams params =
115
                            (FrameLayout.LayoutParams) mDotsPageIndicator.getLayoutParams();
116
                    params.bottomMargin = mInsets.bottom;
117
                    mDotsPageIndicator.setLayoutParams(params);
118
                }
119
 
120
                mAdapter.setInsets(mInsets);
121
                return insets;
122
            }
123
        });
124
 
125
        // Set up the DismissOverlayView
126
        mDismissOverlayView = (DismissOverlayView) findViewById(R.id.dismiss_overlay);
127
        mDismissOverlayView.setIntroText(getString(R.string.exit_intro_text));
128
        mDismissOverlayView.showIntroIfNecessary();
129
        mGestureDetector = new GestureDetectorCompat(this, new LongPressListener());
130
 
131
        Uri attractionsUri = getIntent().getParcelableExtra(Constants.EXTRA_ATTRACTIONS_URI);
132
        if (attractionsUri != null) {
133
            new FetchDataAsyncTask(this).execute(attractionsUri);
134
            UtilityService.clearNotification(this);
135
            UtilityService.clearRemoteNotifications(this);
136
        } else {
137
            finish();
138
        }
139
    }
140
 
141
    @Override
142
    public boolean dispatchTouchEvent(MotionEvent event) {
143
        return mGestureDetector.onTouchEvent(event) || super.dispatchTouchEvent(event);
144
    }
145
 
146
    @Override
147
    public boolean onTouchEvent(MotionEvent event) {
148
        return mGestureDetector.onTouchEvent(event) || super.onTouchEvent(event);
149
    }
150
 
151
    @Override
152
    public void onChromeFadeIn() {
153
        // As the custom UI chrome fades in, also fade the DotsPageIndicator in
154
        mDotsPageIndicator.animate().alpha(1).setDuration(
155
                AttractionsGridPagerAdapter.FADE_IN_TIME_MS).start();
156
    }
157
 
158
    @Override
159
    public void onChromeFadeOut() {
160
        // As the custom UI chrome fades out, also fade the DotsPageIndicator out
161
        mDotsPageIndicator.animate().alpha(0).setDuration(
162
                AttractionsGridPagerAdapter.FADE_OUT_TIME_MS).start();
163
    }
164
 
165
    private class LongPressListener extends GestureDetector.SimpleOnGestureListener {
166
        @Override
167
        public void onLongPress(MotionEvent event) {
168
            mDismissOverlayView.show();
169
        }
170
    }
171
 
172
    /**
173
     * A background task to load the attraction data via the Wear DataApi.
174
     * This can take a second or two sometimes as several images need to
175
     * be loaded.
176
     */
177
    private class FetchDataAsyncTask extends
178
            AsyncTask<Uri, Void, ArrayList<Attraction>> {
179
 
180
        private Context mContext;
181
 
182
        public FetchDataAsyncTask(Context context) {
183
            mContext = context;
184
        }
185
 
186
        @Override
187
        protected ArrayList<Attraction> doInBackground(Uri... params) {
188
            mAttractions.clear();
189
 
190
            // Connect to Play Services and the Wearable API
191
            GoogleApiClient googleApiClient = new GoogleApiClient.Builder(mContext)
192
                    .addApi(Wearable.API)
193
                    .build();
194
 
195
            ConnectionResult connectionResult = googleApiClient.blockingConnect(
196
                    Constants.GOOGLE_API_CLIENT_TIMEOUT_S, TimeUnit.SECONDS);
197
 
198
            if (!connectionResult.isSuccess() || !googleApiClient.isConnected()) {
199
                Log.e(TAG, String.format(Constants.GOOGLE_API_CLIENT_ERROR_MSG,
200
                        connectionResult.getErrorCode()));
201
                return null;
202
            }
203
 
204
            Uri attractionsUri = params[0];
205
            DataApi.DataItemResult dataItemResult =
206
                    Wearable.DataApi.getDataItem(googleApiClient, attractionsUri).await();
207
 
208
            if (dataItemResult.getStatus().isSuccess() && dataItemResult.getDataItem() != null) {
209
                DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItemResult.getDataItem());
210
                List<DataMap> attractionsData =
211
                        dataMapItem.getDataMap().getDataMapArrayList(Constants.EXTRA_ATTRACTIONS);
212
 
213
                // Loop through each attraction, adding them to the list
214
                Iterator<DataMap> itr = attractionsData.iterator();
215
                while (itr.hasNext()) {
216
                    DataMap attractionData = itr.next();
217
 
218
                    Attraction attraction = new Attraction();
219
                    attraction.name = attractionData.getString(Constants.EXTRA_TITLE);
220
                    attraction.description =
221
                            attractionData.getString(Constants.EXTRA_DESCRIPTION);
222
                    attraction.city = attractionData.get(Constants.EXTRA_CITY);
223
                    attraction.distance =
224
                            attractionData.getString(Constants.EXTRA_DISTANCE);
225
                    attraction.location = new LatLng(
226
                            attractionData.getDouble(Constants.EXTRA_LOCATION_LAT),
227
                            attractionData.getDouble(Constants.EXTRA_LOCATION_LNG));
228
                    attraction.image = Utils.loadBitmapFromAsset(googleApiClient,
229
                            attractionData.getAsset(Constants.EXTRA_IMAGE));
230
                    attraction.secondaryImage = Utils.loadBitmapFromAsset(googleApiClient,
231
                            attractionData.getAsset(Constants.EXTRA_IMAGE_SECONDARY));
232
 
233
                    mAttractions.add(attraction);
234
                }
235
            }
236
 
237
            googleApiClient.disconnect();
238
 
239
            return mAttractions;
240
        }
241
 
242
        @Override
243
        protected void onPostExecute(ArrayList<Attraction> result) {
244
            if (result != null && result.size() > 0) {
245
                // Update UI based on the result of the background processing
246
                mAdapter.setData(result);
247
                mAdapter.notifyDataSetChanged();
248
                mProgressBar.setVisibility(View.GONE);
249
                mDotsPageIndicator.setVisibility(View.VISIBLE);
250
                mGridViewPager.setVisibility(View.VISIBLE);
251
            } else {
252
                finish();
253
            }
254
        }
255
    }
256
}
This site uses cookies to store your preferences for site-specific language and display options.

Hooray!