diff options
author | Daniel Sandler <dsandler@google.com> | 2009-11-18 14:21:01 -0500 |
---|---|---|
committer | Daniel Sandler <dsandler@google.com> | 2009-11-18 15:18:43 -0500 |
commit | b95b7a63c403a17c3725e1ccfbd65b4283fd6a0f (patch) | |
tree | 2138630113c66cdf253bc4b21c4608b01b47d577 | |
parent | f1e8069bcd1755d9ef2322b705d8d9d6b83728f0 (diff) | |
download | android_packages_apps_DeskClock-b95b7a63c403a17c3725e1ccfbd65b4283fd6a0f.tar.gz android_packages_apps_DeskClock-b95b7a63c403a17c3725e1ccfbd65b4283fd6a0f.tar.bz2 android_packages_apps_DeskClock-b95b7a63c403a17c3725e1ccfbd65b4283fd6a0f.zip |
Myriad fixes & cleanups in DeskClock.
- Force the weather widget to actually fetch new data at
the moment the device is docked, or when the screensaver
disappears (if the device is plugged in).
- Use Intent.FLAG_ACTIVITY_CLEAR_TOP to launch weather,
music, and gallery to avoid jumping into the middle of
their task stacks (http://b/2267831)
- Fix layout issues with weather, particularly when the
Genie widget is unavailable. (relates to
http://b/2254472)
- Internationalize the error message shown when Genie
malfunctions.
- Clean up weather & time displays to match UX specs more
closely (fonts, shadow crop issues).
- Remove some tabs in XML.
- Internal cleanup: use "query" in the name of functions &
variables related to getting updated weather from Genie;
use "fetch" to refer to downloading new weather data from
the network
-rw-r--r-- | res/layout-land/desk_clock.xml | 11 | ||||
-rw-r--r-- | res/layout/desk_clock_time_date.xml | 12 | ||||
-rw-r--r-- | res/layout/desk_clock_weather.xml | 18 | ||||
-rw-r--r-- | res/values/strings.xml | 5 | ||||
-rw-r--r-- | src/com/android/deskclock/DeskClock.java | 96 |
5 files changed, 85 insertions, 57 deletions
diff --git a/res/layout-land/desk_clock.xml b/res/layout-land/desk_clock.xml index 6ea363b2a..c95619512 100644 --- a/res/layout-land/desk_clock.xml +++ b/res/layout-land/desk_clock.xml @@ -55,7 +55,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:gravity="left" - android:textAppearance="?android:attr/textAppearanceMedium" + android:textAppearance="?android:attr/textAppearanceMedium" android:drawablePadding="6dip" android:drawableLeft="@drawable/ic_lock_idle_alarm" android:shadowColor="#C0000000" @@ -72,7 +72,7 @@ /> <ImageButton android:id="@+id/nightmode_button" - style="@style/RoundTouchButton" + style="@style/RoundTouchButton" android:layout_weight="0" android:layout_height="wrap_content" android:layout_width="wrap_content" @@ -93,14 +93,15 @@ <include layout="@layout/desk_clock_time_date" android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:layout_weight="1" + android:layout_width="0dip" + android:layout_weight="4" /> <include layout="@layout/desk_clock_weather" android:layout_height="wrap_content" - android:layout_width="wrap_content" + android:layout_width="0dip" android:layout_marginLeft="12dip" + android:layout_weight="3" /> diff --git a/res/layout/desk_clock_time_date.xml b/res/layout/desk_clock_time_date.xml index 411115eb3..2c1459514 100644 --- a/res/layout/desk_clock_time_date.xml +++ b/res/layout/desk_clock_time_date.xml @@ -27,12 +27,14 @@ <com.android.deskclock.DigitalClock android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="12dip" + android:layout_marginBottom="8dip" > <TextView android:id="@+id/timeDisplay" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="none" android:gravity="center" android:textSize="106sp" android:textColor="#FFFFFFFF" @@ -40,6 +42,7 @@ android:shadowDx="0" android:shadowDy="0" android:shadowRadius="3.0" + android:paddingBottom="3dip" /> @@ -47,9 +50,10 @@ android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="bottom" - android:textAppearance="?android:attr/textAppearanceMedium" - android:textStyle="bold" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textStyle="bold" android:singleLine="true" + android:ellipsize="none" android:layout_marginLeft="3dip" android:shadowColor="#C0000000" android:shadowDx="0" @@ -63,7 +67,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="left" - android:textAppearance="?android:attr/textAppearanceMedium" + android:textAppearance="?android:attr/textAppearanceMedium" android:shadowColor="#C0000000" android:shadowDx="0" android:shadowDy="0" diff --git a/res/layout/desk_clock_weather.xml b/res/layout/desk_clock_weather.xml index c5ee761d7..6c17162b0 100644 --- a/res/layout/desk_clock_weather.xml +++ b/res/layout/desk_clock_weather.xml @@ -18,9 +18,8 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/weather" android:orientation="vertical" - android:layout_width="fill_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_weight="0" android:gravity="left" > <RelativeLayout android:id="@+id/weather_temp_icon_cluster" @@ -41,7 +40,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textSize="46sp" - android:textColor="?android:attr/textColorPrimary" + android:textColor="?android:attr/textColorPrimary" android:shadowColor="#C0000000" android:shadowDx="0" android:shadowDy="0" @@ -55,8 +54,8 @@ android:layout_width="40sp" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="?android:attr/textColorSecondary" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="?android:attr/textColorSecondary" android:shadowColor="#C0000000" android:shadowDx="0" android:shadowDy="0" @@ -68,14 +67,15 @@ android:layout_width="40sp" android:layout_height="wrap_content" android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceSmall" - android:textColor="?android:attr/textColorPrimary" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textStyle="bold" + android:textColor="?android:attr/textColorPrimary" android:shadowColor="#C0000000" android:shadowDx="0" android:shadowDy="0" android:shadowRadius="3.0" android:layout_alignTop="@id/weather_temperature" - android:layout_marginTop="4sp" + android:layout_marginTop="9sp" android:layout_alignLeft="@id/weather_low_temperature" /> </RelativeLayout> @@ -83,8 +83,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/weather_temp_icon_cluster" + android:maxWidth="300sp" android:gravity="left" - android:singleLine="true" android:textSize="18sp" android:textColor="#ffffffff" android:shadowColor="#c0000000" diff --git a/res/values/strings.xml b/res/values/strings.xml index d14b74022..574b45c9e 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -235,6 +235,11 @@ <!-- A short representation of charging information, e.g "34%" --> <string name="battery_charging_level"><xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g></string> + + <!-- What to show the user if the weather widget exists but fails to + respond. This is a sign of an error; if the weather widget is not + present on the device, we show nothing at all. --> + <string name="weather_fetch_failure">Weather information currently unavailable.</string> </resources> diff --git a/src/com/android/deskclock/DeskClock.java b/src/com/android/deskclock/DeskClock.java index 654d6d93a..0cd65a574 100644 --- a/src/com/android/deskclock/DeskClock.java +++ b/src/com/android/deskclock/DeskClock.java @@ -97,7 +97,7 @@ public class DeskClock extends Activity { // Interval between polls of the weather widget. Its refresh period is // likely to be much longer (~3h), but we want to pick up any changes // within 5 minutes. - private final long FETCH_WEATHER_DELAY = 5 * 60 * 1000; // 5 min + private final long QUERY_WEATHER_DELAY = 5 * 60 * 1000; // 5 min // Delay before engaging the burn-in protection mode (green-on-black). private final long SCREEN_SAVER_TIMEOUT = 10 * 60 * 1000; // 10 min @@ -109,8 +109,12 @@ public class DeskClock extends Activity { private final int SCREEN_SAVER_COLOR = 0xFF308030; private final int SCREEN_SAVER_COLOR_DIM = 0xFF183018; + // Opacity of black layer between clock display and wallpaper. + private final float DIM_BEHIND_AMOUNT_NORMAL = 0.4f; + private final float DIM_BEHIND_AMOUNT_DIMMED = 0.7f; // higher contrast when display dimmed + // Internal message IDs. - private final int FETCH_WEATHER_DATA_MSG = 0x1000; + private final int QUERY_WEATHER_DATA_MSG = 0x1000; private final int UPDATE_WEATHER_DISPLAY_MSG = 0x1001; private final int SCREEN_SAVER_TIMEOUT_MSG = 0x2000; private final int SCREEN_SAVER_MOVE_MSG = 0x2001; @@ -130,6 +134,8 @@ public class DeskClock extends Activity { "description", }; + private static final String ACTION_GENIE_REFRESH = "com.google.android.apps.genie.REFRESH"; + // State variables follow. private DigitalClock mTime; private TextView mDate; @@ -163,8 +169,6 @@ public class DeskClock extends Activity { private int mIdleTimeoutEpoch = 0; - private boolean mWeatherFetchScheduled = false; - private Random mRNG; private PendingIntent mMidnightIntent; @@ -186,11 +190,9 @@ public class DeskClock extends Activity { private final Handler mHandy = new Handler() { @Override public void handleMessage(Message m) { - if (m.what == FETCH_WEATHER_DATA_MSG) { - if (!mWeatherFetchScheduled) return; - mWeatherFetchScheduled = false; - new Thread() { public void run() { fetchWeatherData(); } }.start(); - scheduleWeatherFetchDelayed(FETCH_WEATHER_DELAY); + if (m.what == QUERY_WEATHER_DATA_MSG) { + new Thread() { public void run() { queryWeatherData(); } }.start(); + scheduleWeatherQueryDelayed(QUERY_WEATHER_DELAY); } else if (m.what == UPDATE_WEATHER_DISPLAY_MSG) { updateWeatherDisplay(); } else if (m.what == SCREEN_SAVER_TIMEOUT_MSG) { @@ -257,6 +259,8 @@ public class DeskClock extends Activity { mScreenSaverMode = false; initViews(); doDim(false); // restores previous dim mode + // policy: update weather info when returning from screen saver + if (mPluggedIn) requestWeatherDataFetch(); refreshAll(); } @@ -293,8 +297,8 @@ public class DeskClock extends Activity { mDate.setTextColor(color); mNextAlarm.setTextColor(color); mNextAlarm.setCompoundDrawablesWithIntrinsicBounds( - getResources().getDrawable(mDimmed - ? R.drawable.ic_lock_idle_alarm_saver_dim + getResources().getDrawable(mDimmed + ? R.drawable.ic_lock_idle_alarm_saver_dim : R.drawable.ic_lock_idle_alarm_saver), null, null, null); @@ -317,25 +321,32 @@ public class DeskClock extends Activity { restoreScreen(); } + // Tell the Genie widget to load new data from the network. + private void requestWeatherDataFetch() { + if (DEBUG) Log.d(LOG_TAG, "forcing the Genie widget to update weather now..."); + sendBroadcast(new Intent(ACTION_GENIE_REFRESH).putExtra("requestWeather", true)); + // update the display with any new data + scheduleWeatherQueryDelayed(5000); + } + private boolean supportsWeather() { return (mGenieResources != null); } - private void scheduleWeatherFetchDelayed(long delay) { - if (mWeatherFetchScheduled) return; + private void scheduleWeatherQueryDelayed(long delay) { + // cancel any existing scheduled queries + unscheduleWeatherQuery(); if (DEBUG) Log.d(LOG_TAG, "scheduling weather fetch message for " + delay + "ms from now"); - mWeatherFetchScheduled = true; - - mHandy.sendEmptyMessageDelayed(FETCH_WEATHER_DATA_MSG, delay); + mHandy.sendEmptyMessageDelayed(QUERY_WEATHER_DATA_MSG, delay); } - private void unscheduleWeatherFetch() { - mWeatherFetchScheduled = false; + private void unscheduleWeatherQuery() { + mHandy.removeMessages(QUERY_WEATHER_DATA_MSG); } - private void fetchWeatherData() { + private void queryWeatherData() { // if we couldn't load the weather widget's resources, we simply // assume it's not present on the device. if (mGenieResources == null) return; @@ -392,7 +403,7 @@ public class DeskClock extends Activity { mWeatherIconDrawable = null; mWeatherHighTemperatureString = ""; mWeatherLowTemperatureString = ""; - mWeatherLocationString = "Weather data unavailable."; // TODO: internationalize + mWeatherLocationString = getString(R.string.weather_fetch_failure); } mHandy.sendEmptyMessage(UPDATE_WEATHER_DISPLAY_MSG); @@ -400,7 +411,7 @@ public class DeskClock extends Activity { private void refreshWeather() { if (supportsWeather()) - scheduleWeatherFetchDelayed(0); + scheduleWeatherQueryDelayed(0); updateWeatherDisplay(); // in case we have it cached } @@ -419,6 +430,11 @@ public class DeskClock extends Activity { final boolean pluggedIn = (plugStatus == BATTERY_STATUS_CHARGING || plugStatus == BATTERY_STATUS_FULL); if (pluggedIn != mPluggedIn) { setWakeLock(pluggedIn); + + if (pluggedIn) { + // policy: update weather info when attaching to power + requestWeatherDataFetch(); + } } if (pluggedIn != mPluggedIn || batteryLevel != mBatteryLevel) { mBatteryLevel = batteryLevel; @@ -484,7 +500,7 @@ public class DeskClock extends Activity { if (mDimmed) { winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; - winParams.dimAmount = 0.67f; // pump up contrast in dim mode + winParams.dimAmount = DIM_BEHIND_AMOUNT_DIMMED; // show the window tint tintView.startAnimation(AnimationUtils.loadAnimation(this, @@ -492,7 +508,7 @@ public class DeskClock extends Activity { : R.anim.dim_instant)); } else { winParams.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN); - winParams.dimAmount = 0.5f; // lower contrast in normal mode + winParams.dimAmount = DIM_BEHIND_AMOUNT_NORMAL; // hide the window tint tintView.startAnimation(AnimationUtils.loadAnimation(this, @@ -524,8 +540,8 @@ public class DeskClock extends Activity { am.setRepeating(AlarmManager.RTC, today.getTimeInMillis(), AlarmManager.INTERVAL_DAY, mMidnightIntent); registerReceiver(mIntentReceiver, filter); - doDim(false); - restoreScreen(); + doDim(false); // un-dim when resuming + restoreScreen(); // disable screen saver refreshAll(); // will schedule periodic weather fetch setWakeLock(mPluggedIn); @@ -535,14 +551,13 @@ public class DeskClock extends Activity { Message.obtain(mHandy, SCREEN_SAVER_TIMEOUT_MSG, mIdleTimeoutEpoch, 0), SCREEN_SAVER_TIMEOUT); - final boolean launchedFromDock + final boolean launchedFromDock = getIntent().hasCategory(Intent.CATEGORY_DESK_DOCK); if (supportsWeather() && launchedFromDock && !mInDock) { + // policy: fetch weather if launched via dock connection if (DEBUG) Log.d(LOG_TAG, "Device now docked; forcing weather to refresh right now"); - sendBroadcast( - new Intent("com.google.android.apps.genie.REFRESH") - .putExtra("requestWeather", true)); + requestWeatherDataFetch(); } mInDock = launchedFromDock; @@ -559,7 +574,7 @@ public class DeskClock extends Activity { unregisterReceiver(mIntentReceiver); AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); am.cancel(mMidnightIntent); - unscheduleWeatherFetch(); + unscheduleWeatherQuery(); super.onPause(); } @@ -595,14 +610,17 @@ public class DeskClock extends Activity { mWeatherLocation = (TextView) findViewById(R.id.weather_location); mWeatherIcon = (ImageView) findViewById(R.id.weather_icon); - mNextAlarm = (TextView) findViewById(R.id.nextAlarm); - - final ImageButton alarmButton = (ImageButton) findViewById(R.id.alarm_button); - alarmButton.setOnClickListener(new View.OnClickListener() { + final View.OnClickListener alarmClickListener = new View.OnClickListener() { public void onClick(View v) { startActivity(new Intent(DeskClock.this, AlarmClock.class)); } - }); + }; + + mNextAlarm = (TextView) findViewById(R.id.nextAlarm); + mNextAlarm.setOnClickListener(alarmClickListener); + + final ImageButton alarmButton = (ImageButton) findViewById(R.id.alarm_button); + alarmButton.setOnClickListener(alarmClickListener); final ImageButton galleryButton = (ImageButton) findViewById(R.id.gallery_button); galleryButton.setOnClickListener(new View.OnClickListener() { @@ -612,7 +630,7 @@ public class DeskClock extends Activity { Intent.ACTION_VIEW, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI) .putExtra("slideshow", true) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP)); } catch (android.content.ActivityNotFoundException e) { Log.e(LOG_TAG, "Couldn't launch image browser", e); } @@ -625,7 +643,7 @@ public class DeskClock extends Activity { try { Intent musicAppQuery = getPackageManager() .getLaunchIntentForPackage(MUSIC_PACKAGE_ID) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); if (musicAppQuery != null) { startActivity(musicAppQuery); } @@ -640,7 +658,7 @@ public class DeskClock extends Activity { public void onClick(View v) { startActivity( new Intent(Intent.ACTION_MAIN) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP) .addCategory(Intent.CATEGORY_HOME)); } }); @@ -667,7 +685,7 @@ public class DeskClock extends Activity { Intent genieAppQuery = getPackageManager() .getLaunchIntentForPackage(GENIE_PACKAGE_ID) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); if (genieAppQuery != null) { startActivity(genieAppQuery); } |