From 06718466ea42b1b2329e63fc043cc5a818a2a96d Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Fri, 22 Feb 2013 14:58:57 -0800 Subject: [PATCH] Add lock screen widget. Fix issue with 4x1 widget not displaying properly. --- MyTracks/res/xml/track_widget_info.xml | 4 +- .../apps/mytracks/util/Api16Adapter.java | 51 +++++++++++++++++++ .../apps/mytracks/util/Api8Adapter.java | 12 +++++ .../apps/mytracks/util/ApiAdapter.java | 22 +++++++- .../apps/mytracks/util/ApiAdapterFactory.java | 9 ++-- .../mytracks/widgets/TrackWidgetProvider.java | 47 +++++++++-------- 6 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java diff --git a/MyTracks/res/xml/track_widget_info.xml b/MyTracks/res/xml/track_widget_info.xml index 33f3feaf0..f6ede7b21 100644 --- a/MyTracks/res/xml/track_widget_info.xml +++ b/MyTracks/res/xml/track_widget_info.xml @@ -16,10 +16,12 @@ limitations under the License. --> + android:updatePeriodMillis="0" + android:widgetCategory="keyguard|home_screen" /> diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java new file mode 100644 index 000000000..7ce6f17f5 --- /dev/null +++ b/MyTracks/src/com/google/android/apps/mytracks/util/Api16Adapter.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.android.apps.mytracks.util; + +import com.google.android.apps.mytracks.widgets.TrackWidgetProvider; + +import android.annotation.TargetApi; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProviderInfo; +import android.os.Bundle; + +/** + * API level 16 specific implementation of the {@link ApiAdapter}. + * + * @author Jimmy Shih + */ +@TargetApi(16) +public class Api16Adapter extends Api14Adapter { + + private static final String APP_WIDGET_SIZE_KEY = "app_widget_size_key"; + + @Override + public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) { + Bundle bundle = appWidgetManager.getAppWidgetOptions(appWidgetId); + boolean isKeyguard = bundle.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1) + == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD; + return bundle.getInt(APP_WIDGET_SIZE_KEY, isKeyguard ? TrackWidgetProvider.KEYGUARD_DEFAULT_SIZE + : TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE); + } + + @Override + public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size) { + Bundle bundle = new Bundle(); + bundle.putInt(APP_WIDGET_SIZE_KEY, size); + appWidgetManager.updateAppWidgetOptions(appWidgetId, bundle); + } +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java index b8c768821..3279e52eb 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/Api8Adapter.java @@ -18,10 +18,12 @@ package com.google.android.apps.mytracks.util; import com.google.android.apps.mytracks.Constants; import com.google.android.apps.mytracks.ContextualActionModeCallback; import com.google.android.apps.mytracks.services.sensors.BluetoothConnectionManager; +import com.google.android.apps.mytracks.widgets.TrackWidgetProvider; import com.google.api.client.http.HttpTransport; import com.google.api.client.http.apache.ApacheHttpTransport; import android.app.Activity; +import android.appwidget.AppWidgetManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.SharedPreferences.Editor; @@ -136,4 +138,14 @@ public class Api8Adapter implements ApiAdapter { // Return false and allow the framework to handle the search key. return false; } + + @Override + public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId) { + return TrackWidgetProvider.HOME_SCREEN_DEFAULT_SIZE; + } + + @Override + public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size) { + // Do nothing + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java index 908cb3537..d4949c47d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapter.java @@ -19,6 +19,7 @@ import com.google.android.apps.mytracks.ContextualActionModeCallback; import com.google.api.client.http.HttpTransport; import android.app.Activity; +import android.appwidget.AppWidgetManager; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import android.content.SharedPreferences; @@ -169,5 +170,24 @@ public interface ApiAdapter { * * @param menu the search menu */ - public boolean handleSearchKey(MenuItem menu); + public boolean handleSearchKey(MenuItem menu); + + /** + * Gets the app widget size. + *

+ * Due to changes in API level 16. + * + * @param appWidgetManager the app widget manager + * @param appWidgetId the app widget id + */ + public int getAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId); + + /** + * Sets the app widget size. + * + * @param appWidgetManager the app widget manager. + * @param appWidgetId the app widgit id + * @param size the size + */ + public void setAppWidgetSize(AppWidgetManager appWidgetManager, int appWidgetId, int size); } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java index d1ebdffe8..5b60e1e5a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiAdapterFactory.java @@ -31,21 +31,18 @@ public class ApiAdapterFactory { */ public static ApiAdapter getApiAdapter() { if (apiAdapter == null) { - if (Build.VERSION.SDK_INT >= 14) { + if (Build.VERSION.SDK_INT >= 16) { + apiAdapter = new Api16Adapter(); + } else if (Build.VERSION.SDK_INT >= 14) { apiAdapter = new Api14Adapter(); - return apiAdapter; } else if (Build.VERSION.SDK_INT >= 11) { apiAdapter = new Api11Adapter(); - return apiAdapter; } else if (Build.VERSION.SDK_INT >= 10) { apiAdapter = new Api10Adapter(); - return apiAdapter; } else if (Build.VERSION.SDK_INT >= 9) { apiAdapter = new Api9Adapter(); - return apiAdapter; } else { apiAdapter = new Api8Adapter(); - return apiAdapter; } } return apiAdapter; diff --git a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java index 2c14eeac8..16cbc0e64 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java +++ b/MyTracks/src/com/google/android/apps/mytracks/widgets/TrackWidgetProvider.java @@ -22,6 +22,7 @@ import com.google.android.apps.mytracks.content.MyTracksProviderUtils; import com.google.android.apps.mytracks.content.Track; import com.google.android.apps.mytracks.services.ControlRecordingService; import com.google.android.apps.mytracks.stats.TripStatistics; +import com.google.android.apps.mytracks.util.ApiAdapterFactory; import com.google.android.apps.mytracks.util.IntentUtils; import com.google.android.apps.mytracks.util.PreferencesUtils; import com.google.android.apps.mytracks.util.StringUtils; @@ -31,13 +32,13 @@ import android.annotation.TargetApi; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; +import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.SystemClock; import android.support.v4.app.TaskStackBuilder; -import android.util.SparseIntArray; import android.view.View; import android.widget.RemoteViews; @@ -51,14 +52,13 @@ import android.widget.RemoteViews; */ public class TrackWidgetProvider extends AppWidgetProvider { + public static final int KEYGUARD_DEFAULT_SIZE = 1; + public static final int HOME_SCREEN_DEFAULT_SIZE = 2; + private static final int TWO_CELLS = 110; private static final int THREE_CELLS = 180; private static final int FOUR_CELLS = 250; - // Array of appwidget id to height size in cells - private static final SparseIntArray HEIGHT_SIZE = new SparseIntArray(); - private static final int DEFAULT_SIZE = 2; - private static final int[] ITEM1_IDS = { R.id.track_widget_item1_label, R.id.track_widget_item1_value, R.id.track_widget_item1_unit, R.id.track_widget_item1_chronometer }; @@ -86,8 +86,9 @@ public class TrackWidgetProvider extends AppWidgetProvider { int[] appWidgetIds = appWidgetManager.getAppWidgetIds( new ComponentName(context, TrackWidgetProvider.class)); for (int appWidgetId : appWidgetIds) { - RemoteViews remoteViews = getRemoteViews( - context, trackId, HEIGHT_SIZE.get(appWidgetId, DEFAULT_SIZE)); + int size = ApiAdapterFactory.getApiAdapter() + .getAppWidgetSize(appWidgetManager, appWidgetId); + RemoteViews remoteViews = getRemoteViews(context, trackId, size); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } } @@ -99,19 +100,24 @@ public class TrackWidgetProvider extends AppWidgetProvider { Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { if (newOptions != null) { int size; - int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); - if (height == 0) { - size = 2; - } else if (height >= FOUR_CELLS) { - size = 4; - } else if (height >= THREE_CELLS) { - size = 3; - } else if (height >= TWO_CELLS) { - size = 2; - } else { + if (newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY, -1) + == AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD) { size = 1; + } else { + int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); + if (height == 0) { + size = 2; + } else if (height >= FOUR_CELLS) { + size = 4; + } else if (height >= THREE_CELLS) { + size = 3; + } else if (height >= TWO_CELLS) { + size = 2; + } else { + size = 1; + } } - HEIGHT_SIZE.put(appWidgetId, size); + ApiAdapterFactory.getApiAdapter().setAppWidgetSize(appWidgetManager, appWidgetId, size); RemoteViews remoteViews = getRemoteViews(context, -1L, size); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); } @@ -126,8 +132,9 @@ public class TrackWidgetProvider extends AppWidgetProvider { */ public static void updateAppWidget( Context context, AppWidgetManager appWidgetManager, int appWidgetId) { - RemoteViews remoteViews = getRemoteViews( - context, -1L, HEIGHT_SIZE.get(appWidgetId, DEFAULT_SIZE)); + int size = ApiAdapterFactory.getApiAdapter().getAppWidgetSize(appWidgetManager, appWidgetId); + ApiAdapterFactory.getApiAdapter().setAppWidgetSize(appWidgetManager, appWidgetId, size); + RemoteViews remoteViews = getRemoteViews(context, -1L, size); appWidgetManager.updateAppWidget(appWidgetId, remoteViews); }