packages/wallpapers/Basic
Revision | a7cbc26594244e4e5c0cf4889c1b45fa2741831e (tree) |
---|---|
Zeit | 2009-08-13 07:24:53 |
Autor | Romain Guy <romainguy@andr...> |
Commiter | Romain Guy |
Add Polar Clock wallpaper
@@ -34,6 +34,15 @@ | ||
34 | 34 | </intent-filter> |
35 | 35 | </service> |
36 | 36 | |
37 | + <service | |
38 | + android:label="@string/wallpaper_clock" | |
39 | + android:name="com.android.wallpaper.polarclock.PolarClockWallpaper" | |
40 | + android:permission="android.permission.BIND_WALLPAPER"> | |
41 | + <intent-filter> | |
42 | + <action android:name="android.service.wallpaper.WallpaperService" /> | |
43 | + </intent-filter> | |
44 | + </service> | |
45 | + | |
37 | 46 | </application> |
38 | 47 | |
39 | 48 | </manifest> |
@@ -28,4 +28,6 @@ | ||
28 | 28 | |
29 | 29 | <!-- Wallpaper showing grass and the sky --> |
30 | 30 | <string name="wallpaper_grass">Grass</string> |
31 | + <!-- Wallpaper showing a clock --> | |
32 | + <string name="wallpaper_clock">Polar clock</string> | |
31 | 33 | </resources> |
@@ -0,0 +1,225 @@ | ||
1 | +/* | |
2 | + * Copyright (C) 2009 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.android.wallpaper.polarclock; | |
18 | + | |
19 | +import android.service.wallpaper.WallpaperService; | |
20 | +import android.graphics.Canvas; | |
21 | +import android.graphics.Rect; | |
22 | +import android.graphics.Paint; | |
23 | +import android.graphics.Color; | |
24 | +import android.graphics.RectF; | |
25 | +import android.view.SurfaceHolder; | |
26 | +import android.content.IntentFilter; | |
27 | +import android.content.Intent; | |
28 | +import android.content.BroadcastReceiver; | |
29 | +import android.content.Context; | |
30 | +import android.os.Handler; | |
31 | +import android.os.SystemClock; | |
32 | +import android.text.format.Time; | |
33 | + | |
34 | +import java.util.TimeZone; | |
35 | + | |
36 | +public class PolarClockWallpaper extends WallpaperService { | |
37 | + private final Handler mHandler = new Handler(); | |
38 | + private final Runnable mDrawClock = new Runnable() { | |
39 | + public void run() { | |
40 | + mEngine.drawFrame(true); | |
41 | + } | |
42 | + }; | |
43 | + | |
44 | + private TimeWatcher mWatcher; | |
45 | + private IntentFilter mFilter; | |
46 | + private ClockEngine mEngine; | |
47 | + | |
48 | + @Override | |
49 | + public void onCreate() { | |
50 | + super.onCreate(); | |
51 | + | |
52 | + mFilter = new IntentFilter(); | |
53 | + mFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED); | |
54 | + | |
55 | + mWatcher = new TimeWatcher(); | |
56 | + } | |
57 | + | |
58 | + @Override | |
59 | + public void onDestroy() { | |
60 | + super.onDestroy(); | |
61 | + unregisterReceiver(mWatcher); | |
62 | + mHandler.removeCallbacks(mDrawClock); | |
63 | + } | |
64 | + | |
65 | + public Engine onCreateEngine() { | |
66 | + mEngine = new ClockEngine(); | |
67 | + return mEngine; | |
68 | + } | |
69 | + | |
70 | + class TimeWatcher extends BroadcastReceiver { | |
71 | + public void onReceive(Context context, Intent intent) { | |
72 | + final String timeZone = intent.getStringExtra("time-zone"); | |
73 | + mEngine.mCalendar = new Time(TimeZone.getTimeZone(timeZone).getID()); | |
74 | + mEngine.drawFrame(true); | |
75 | + } | |
76 | + } | |
77 | + | |
78 | + class ClockEngine extends Engine { | |
79 | + private static final float SATURATION = 0.8f; | |
80 | + private static final float BRIGHTNESS = 0.9f; | |
81 | + | |
82 | + private static final float RING_THICKNESS = 24.0f; | |
83 | + private static final float SMALL_GAP = 14.0f; | |
84 | + private static final float LARGE_GAP = 38.0f; | |
85 | + | |
86 | + private static final int COLORS_CACHE_COUNT = 720; | |
87 | + | |
88 | + private float mStartTime; | |
89 | + private Time mCalendar; | |
90 | + | |
91 | + private final Paint mPaint = new Paint(); | |
92 | + private final RectF mRect = new RectF(); | |
93 | + private final int[] mColors; | |
94 | + | |
95 | + ClockEngine() { | |
96 | + mColors = new int[COLORS_CACHE_COUNT]; | |
97 | + | |
98 | + final int[] colors = mColors; | |
99 | + final int count = colors.length; | |
100 | + | |
101 | + for (int i = 0; i < count; i++) { | |
102 | + colors[i] = Color.HSBtoColor(i / (float) COLORS_CACHE_COUNT, SATURATION, BRIGHTNESS); | |
103 | + } | |
104 | + } | |
105 | + | |
106 | + @Override | |
107 | + public void onCreate(SurfaceHolder surfaceHolder) { | |
108 | + super.onCreate(surfaceHolder); | |
109 | + | |
110 | + mCalendar = new Time(); | |
111 | + mCalendar.setToNow(); | |
112 | + mStartTime = mCalendar.second * 1000.0f; | |
113 | + | |
114 | + final Paint paint = mPaint; | |
115 | + paint.setAntiAlias(true); | |
116 | + paint.setStrokeWidth(RING_THICKNESS); | |
117 | + paint.setStrokeCap(Paint.Cap.ROUND); | |
118 | + paint.setStyle(Paint.Style.STROKE); | |
119 | + } | |
120 | + | |
121 | + @Override | |
122 | + public void onVisibilityChanged(boolean visible) { | |
123 | + if (visible) { | |
124 | + registerReceiver(mWatcher, mFilter, null, mHandler); | |
125 | + mCalendar = new Time(); | |
126 | + mCalendar.setToNow(); | |
127 | + mStartTime = mCalendar.second * 1000.0f; | |
128 | + } else { | |
129 | + unregisterReceiver(mWatcher); | |
130 | + mHandler.removeCallbacks(mDrawClock); | |
131 | + } | |
132 | + drawFrame(visible); | |
133 | + } | |
134 | + | |
135 | + @Override | |
136 | + public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { | |
137 | + super.onSurfaceChanged(holder, format, width, height); | |
138 | + drawFrame(true); | |
139 | + } | |
140 | + | |
141 | + @Override | |
142 | + public void onSurfaceCreated(SurfaceHolder holder) { | |
143 | + super.onSurfaceCreated(holder); | |
144 | + } | |
145 | + | |
146 | + @Override | |
147 | + public void onSurfaceDestroyed(SurfaceHolder holder) { | |
148 | + super.onSurfaceDestroyed(holder); | |
149 | + drawFrame(false); | |
150 | + } | |
151 | + | |
152 | + void drawFrame(boolean redraw) { | |
153 | + final SurfaceHolder holder = getSurfaceHolder(); | |
154 | + final Rect frame = holder.getSurfaceFrame(); | |
155 | + final int width = frame.width(); | |
156 | + final int height = frame.height(); | |
157 | + | |
158 | + Canvas c = null; | |
159 | + try { | |
160 | + c = holder.lockCanvas(); | |
161 | + if (c != null) { | |
162 | + final Time calendar = mCalendar; | |
163 | + final Paint paint = mPaint; | |
164 | + final int[] colors = mColors; | |
165 | + | |
166 | + calendar.setToNow(); | |
167 | + calendar.normalize(false); | |
168 | + | |
169 | + c.drawColor(0xffffffff); | |
170 | + c.translate(width / 2.0f, height/ 2.0f); | |
171 | + c.rotate(-90.0f); | |
172 | + | |
173 | + // Draw seconds | |
174 | + float size = width / 2.0f / 2.0f - RING_THICKNESS; | |
175 | + final RectF rect = mRect; | |
176 | + rect.set(-size, -size, size, size); | |
177 | + | |
178 | + float angle = ((mStartTime + SystemClock.elapsedRealtime()) % 60000) / 60000.0f; | |
179 | + paint.setColor(colors[((int) (angle * COLORS_CACHE_COUNT))]); | |
180 | + c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); | |
181 | + | |
182 | + // Draw minutes | |
183 | + size -= (SMALL_GAP + RING_THICKNESS); | |
184 | + rect.set(-size, -size, size, size); | |
185 | + | |
186 | + angle = ((calendar.minute * 60.0f + calendar.second) % 3600) / 3600.0f; | |
187 | + paint.setColor(colors[((int) (angle * COLORS_CACHE_COUNT))]); | |
188 | + c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); | |
189 | + | |
190 | + // Draw hours | |
191 | + size -= (SMALL_GAP + RING_THICKNESS); | |
192 | + rect.set(-size, -size, size, size); | |
193 | + | |
194 | + angle = ((calendar.hour * 60.0f + calendar.minute) % 1440) / 1440.0f; | |
195 | + paint.setColor(colors[((int) (angle * COLORS_CACHE_COUNT))]); | |
196 | + c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); | |
197 | + | |
198 | + // Draw day | |
199 | + size -= (LARGE_GAP + RING_THICKNESS); | |
200 | + rect.set(-size, -size, size, size); | |
201 | + | |
202 | + angle = (calendar.monthDay - 1) / | |
203 | + (float) (calendar.getActualMaximum(Time.MONTH_DAY) - 1); | |
204 | + paint.setColor(colors[((int) (angle * COLORS_CACHE_COUNT))]); | |
205 | + c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); | |
206 | + | |
207 | + // Draw month | |
208 | + size -= (SMALL_GAP + RING_THICKNESS); | |
209 | + rect.set(-size, -size, size, size); | |
210 | + | |
211 | + angle = (calendar.month - 1) / 11.0f; | |
212 | + paint.setColor(colors[((int) (angle * COLORS_CACHE_COUNT))]); | |
213 | + c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); | |
214 | + } | |
215 | + } finally { | |
216 | + if (c != null) holder.unlockCanvasAndPost(c); | |
217 | + } | |
218 | + | |
219 | + mHandler.removeCallbacks(mDrawClock); | |
220 | + if (redraw) { | |
221 | + mHandler.postDelayed(mDrawClock, 1000 / 25); | |
222 | + } | |
223 | + } | |
224 | + } | |
225 | +} |