Skip to content

Most visited

Recently visited

navigation
WatchFace / Wearable / src / com.example.android.wearable.watchface /

InteractiveWatchFaceService.java

1
/*
2
 * Copyright (C) 2015 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.watchface;
18
 
19
import android.content.res.Resources;
20
import android.graphics.Canvas;
21
import android.graphics.Color;
22
import android.graphics.Paint;
23
import android.graphics.Rect;
24
import android.graphics.Typeface;
25
import android.os.Bundle;
26
import android.support.wearable.watchface.CanvasWatchFaceService;
27
import android.support.wearable.watchface.WatchFaceStyle;
28
import android.util.Log;
29
import android.view.SurfaceHolder;
30
import android.view.WindowInsets;
31
 
32
/**
33
 * Demonstrates interactive watch face capabilities, i.e., touching the display and registering
34
 * three different events: touch, touch-cancel and tap. The watch face UI will show the count of
35
 * these events as they occur. See the {@code onTapCommand} below.
36
 */
37
public class InteractiveWatchFaceService extends CanvasWatchFaceService {
38
 
39
    private static final String TAG = "InteractiveWatchFace";
40
 
41
    private static final Typeface BOLD_TYPEFACE =
42
            Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
43
    private static final Typeface NORMAL_TYPEFACE =
44
            Typeface.create(Typeface.SANS_SERIF, Typeface.NORMAL);
45
 
46
    @Override
47
    public Engine onCreateEngine() {
48
        return new Engine();
49
    }
50
 
51
    private class Engine extends CanvasWatchFaceService.Engine {
52
 
53
        private Paint mTextPaint;
54
        private final Paint mPeekCardBackgroundPaint = new Paint();
55
 
56
        private float mXOffset;
57
        private float mYOffset;
58
        private float mTextSpacingHeight;
59
        private int mScreenTextColor = Color.WHITE;
60
 
61
        private int mTouchCommandTotal;
62
        private int mTouchCancelCommandTotal;
63
        private int mTapCommandTotal;
64
 
65
        private int mTouchCoordinateX;
66
        private int mTouchCoordinateY;
67
 
68
        private final Rect mCardBounds = new Rect();
69
 
70
        /**
71
         * Whether the display supports fewer bits for each color in ambient mode. When true, we
72
         * disable anti-aliasing in ambient mode.
73
         */
74
        private boolean mLowBitAmbient;
75
 
76
        @Override
77
        public void onCreate(SurfaceHolder holder) {
78
            if (Log.isLoggable(TAG, Log.DEBUG)) {
79
                Log.d(TAG, "onCreate");
80
            }
81
            super.onCreate(holder);
82
 
83
            /** Accepts tap events via WatchFaceStyle (setAcceptsTapEvents(true)). */
84
            setWatchFaceStyle(new WatchFaceStyle.Builder(InteractiveWatchFaceService.this)
85
                    .setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE)
86
                    .setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
87
                    .setShowSystemUiTime(false)
88
                    .setAcceptsTapEvents(true)
89
                    .build());
90
 
91
            Resources resources = InteractiveWatchFaceService.this.getResources();
92
            mTextSpacingHeight = resources.getDimension(R.dimen.interactive_text_size);
93
 
94
            mTextPaint = new Paint();
95
            mTextPaint.setColor(mScreenTextColor);
96
            mTextPaint.setTypeface(BOLD_TYPEFACE);
97
            mTextPaint.setAntiAlias(true);
98
 
99
            mTouchCommandTotal = 0;
100
            mTouchCancelCommandTotal = 0;
101
            mTapCommandTotal = 0;
102
 
103
            mTouchCoordinateX = 0;
104
            mTouchCoordinateX = 0;
105
        }
106
 
107
        @Override
108
        public void onApplyWindowInsets(WindowInsets insets) {
109
            if (Log.isLoggable(TAG, Log.DEBUG)) {
110
                Log.d(TAG, "onApplyWindowInsets: " + (insets.isRound() ? "round" : "square"));
111
            }
112
            super.onApplyWindowInsets(insets);
113
 
114
            /** Loads offsets / text size based on device type (square vs. round). */
115
            Resources resources = InteractiveWatchFaceService.this.getResources();
116
            boolean isRound = insets.isRound();
117
            mXOffset = resources.getDimension(
118
                    isRound ? R.dimen.interactive_x_offset_round : R.dimen.interactive_x_offset);
119
            mYOffset = resources.getDimension(
120
                    isRound ? R.dimen.interactive_y_offset_round : R.dimen.interactive_y_offset);
121
 
122
            float textSize = resources.getDimension(
123
                    isRound ? R.dimen.interactive_text_size_round : R.dimen.interactive_text_size);
124
 
125
            mTextPaint.setTextSize(textSize);
126
        }
127
 
128
        @Override
129
        public void onPeekCardPositionUpdate(Rect bounds) {
130
            super.onPeekCardPositionUpdate(bounds);
131
            if (Log.isLoggable(TAG, Log.DEBUG)) {
132
                Log.d(TAG, "onPeekCardPositionUpdate: " + bounds);
133
            }
134
            super.onPeekCardPositionUpdate(bounds);
135
            if (!bounds.equals(mCardBounds)) {
136
                mCardBounds.set(bounds);
137
                invalidate();
138
            }
139
        }
140
 
141
        @Override
142
        public void onPropertiesChanged(Bundle properties) {
143
            super.onPropertiesChanged(properties);
144
 
145
            boolean burnInProtection = properties.getBoolean(PROPERTY_BURN_IN_PROTECTION, false);
146
            mTextPaint.setTypeface(burnInProtection ? NORMAL_TYPEFACE : BOLD_TYPEFACE);
147
 
148
            mLowBitAmbient = properties.getBoolean(PROPERTY_LOW_BIT_AMBIENT, false);
149
 
150
            if (Log.isLoggable(TAG, Log.DEBUG)) {
151
                Log.d(TAG, "onPropertiesChanged: burn-in protection = " + burnInProtection
152
                        + ", low-bit ambient = " + mLowBitAmbient);
153
            }
154
        }
155
 
156
        @Override
157
        public void onAmbientModeChanged(boolean inAmbientMode) {
158
            super.onAmbientModeChanged(inAmbientMode);
159
            if (Log.isLoggable(TAG, Log.DEBUG)) {
160
                Log.d(TAG, "onAmbientModeChanged: " + inAmbientMode);
161
            }
162
 
163
            if (mLowBitAmbient) {
164
                boolean antiAlias = !inAmbientMode;
165
                mTextPaint.setAntiAlias(antiAlias);
166
            }
167
            invalidate();
168
        }
169
 
170
        /*
171
         * Captures tap event (and tap type) and increments correct tap type total.
172
         */
173
        @Override
174
        public void onTapCommand(int tapType, int x, int y, long eventTime) {
175
            if (Log.isLoggable(TAG, Log.DEBUG)) {
176
                Log.d(TAG, "Tap Command: " + tapType);
177
            }
178
 
179
            mTouchCoordinateX = x;
180
            mTouchCoordinateY = y;
181
 
182
            switch(tapType) {
183
                case TAP_TYPE_TOUCH:
184
                    mTouchCommandTotal++;
185
                    break;
186
                case TAP_TYPE_TOUCH_CANCEL:
187
                    mTouchCancelCommandTotal++;
188
                    break;
189
                case TAP_TYPE_TAP:
190
                    mTapCommandTotal++;
191
                    break;
192
            }
193
 
194
            invalidate();
195
        }
196
 
197
        @Override
198
        public void onDraw(Canvas canvas, Rect bounds) {
199
            /** Draws background */
200
            canvas.drawColor(Color.BLACK);
201
 
202
            canvas.drawText(
203
                    "TAP: " + String.valueOf(mTapCommandTotal),
204
                    mXOffset,
205
                    mYOffset,
206
                    mTextPaint);
207
 
208
            canvas.drawText(
209
                    "CANCEL: " + String.valueOf(mTouchCancelCommandTotal),
210
                    mXOffset,
211
                    mYOffset + mTextSpacingHeight,
212
                    mTextPaint);
213
 
214
            canvas.drawText(
215
                    "TOUCH: " + String.valueOf(mTouchCommandTotal),
216
                    mXOffset,
217
                    mYOffset + (mTextSpacingHeight * 2),
218
                    mTextPaint);
219
 
220
            canvas.drawText(
221
                    "X, Y: " + mTouchCoordinateX + ", " + mTouchCoordinateY,
222
                    mXOffset,
223
                    mYOffset + (mTextSpacingHeight * 3),
224
                    mTextPaint
225
            );
226
 
227
            /** Covers area under peek card */
228
            if (isInAmbientMode()) {
229
                canvas.drawRect(mCardBounds, mPeekCardBackgroundPaint);
230
            }
231
        }
232
    }
233
}
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!