From d86ea2c0e0b43210caa8692537fb57fee92e2a91 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 17 Apr 2013 13:42:05 -0700 Subject: [PATCH] DO NOT MERGE Deferring new collections widget apis. Revert "Updating WeatherListWidget to the new collections widget api." This reverts commit b28878a5b8ec8a27d4efde59aab35702f3267c85. --- samples/WeatherListWidget/AndroidManifest.xml | 2 +- .../WeatherListWidget/res/xml/widgetinfo.xml | 2 +- .../WeatherWidgetProvider.java | 63 +++------ .../WeatherWidgetService.java | 124 ++++++++++++++++++ 4 files changed, 141 insertions(+), 50 deletions(-) create mode 100644 samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java diff --git a/samples/WeatherListWidget/AndroidManifest.xml b/samples/WeatherListWidget/AndroidManifest.xml index 878f11009..7b1638f9c 100644 --- a/samples/WeatherListWidget/AndroidManifest.xml +++ b/samples/WeatherListWidget/AndroidManifest.xml @@ -36,7 +36,7 @@ - diff --git a/samples/WeatherListWidget/res/xml/widgetinfo.xml b/samples/WeatherListWidget/res/xml/widgetinfo.xml index db644572c..2e419439d 100644 --- a/samples/WeatherListWidget/res/xml/widgetinfo.xml +++ b/samples/WeatherListWidget/res/xml/widgetinfo.xml @@ -21,6 +21,6 @@ android:initialLayout="@layout/widget_layout" android:resizeMode="vertical" android:minResizeWidth="280dp" - android:minResizeHeight="40dp" + android:minResizeHeight="70dp" android:previewImage="@drawable/preview"> diff --git a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java index 42f3e5f6c..ea3f944d3 100644 --- a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java +++ b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetProvider.java @@ -19,23 +19,21 @@ package com.example.android.weatherlistwidget; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; -import android.content.ComponentName; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; import android.content.Context; import android.content.Intent; -import android.database.ContentObserver; +import android.content.ComponentName; +import android.content.ContentValues; +import android.content.ContentResolver; +import android.content.ContentUris; import android.database.Cursor; +import android.database.ContentObserver; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; -import android.util.Log; import android.widget.RemoteViews; import android.widget.Toast; -import java.util.ArrayList; import java.util.Random; /** @@ -75,6 +73,7 @@ public class WeatherWidgetProvider extends AppWidgetProvider { private static final int sMaxDegrees = 96; private boolean mIsLargeLayout = true; + private int mHeaderWeatherState = 0; public WeatherWidgetProvider() { // Start the worker thread @@ -117,7 +116,6 @@ public class WeatherWidgetProvider extends AppWidgetProvider { final Cursor c = r.query(WeatherDataProvider.CONTENT_URI, null, null, null, null); final int count = c.getCount(); - c.close(); // We disable the data changed observer temporarily since each of the updates // will trigger an onChange() in our data observer. @@ -133,13 +131,12 @@ public class WeatherWidgetProvider extends AppWidgetProvider { final AppWidgetManager mgr = AppWidgetManager.getInstance(context); final ComponentName cn = new ComponentName(context, WeatherWidgetProvider.class); - int[] appWidgetIds = mgr.getAppWidgetIds(cn); - for (int i = 0; i < appWidgetIds.length; ++i) { - RemoteViews layout = buildLayout(context, appWidgetIds[i], mIsLargeLayout); - mgr.updateAppWidget(appWidgetIds[i], layout); - } + mgr.notifyAppWidgetViewDataChanged(mgr.getAppWidgetIds(cn), R.id.weather_list); } }); + + final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); } else if (action.equals(CLICK_ACTION)) { // Show a toast final int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, @@ -152,46 +149,16 @@ public class WeatherWidgetProvider extends AppWidgetProvider { super.onReceive(ctx, intent); } - private ArrayList getListOfCities(Context context) { - final String packageName = context.getPackageName(); - ArrayList citiesList = new ArrayList(); - Cursor c = context.getContentResolver().query(WeatherDataProvider.CONTENT_URI, null, - null, null, null); - final String itemFormatStr = context.getResources().getString(R.string.item_format_string); - while (c.moveToNext()) { - int tempColIndex = c.getColumnIndex(WeatherDataProvider.Columns.TEMPERATURE); - int temp = c.getInt(tempColIndex); - int dayColIndex = c.getColumnIndex(WeatherDataProvider.Columns.DAY); - String day = c.getString(dayColIndex); - - RemoteViews rvRow = new RemoteViews(packageName, R.layout.widget_item); - rvRow.setTextViewText(R.id.widget_item, String.format(itemFormatStr, temp, day)); - - // Set the click intent so that we can handle it and show a toast message - final Intent fillInIntent = new Intent(); - final Bundle extras = new Bundle(); - extras.putString(WeatherWidgetProvider.EXTRA_DAY_ID, day); - fillInIntent.putExtras(extras); - rvRow.setOnClickFillInIntent(R.id.widget_item, fillInIntent); - - citiesList.add(rvRow); - } - c.close(); - return citiesList; - } - private RemoteViews buildLayout(Context context, int appWidgetId, boolean largeLayout) { - final String packageName = context.getPackageName(); - RemoteViews rv; if (largeLayout) { // Specify the service to provide data for the collection widget. Note that we need to // embed the appWidgetId via the data otherwise it will be ignored. - rv = new RemoteViews(packageName, R.layout.widget_layout); - - // Set the list of RemoteViews - ArrayList citiesList = getListOfCities(context); - rv.setRemoteAdapter(R.id.weather_list, citiesList, 1); + final Intent intent = new Intent(context, WeatherWidgetService.class); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout); + rv.setRemoteAdapter(appWidgetId, R.id.weather_list, intent); // Set the empty view to be displayed if the collection is empty. It must be a sibling // view of the collection view. diff --git a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java new file mode 100644 index 000000000..4780e8031 --- /dev/null +++ b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * 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.example.android.weatherlistwidget; + +import java.util.ArrayList; +import java.util.List; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.content.ContentUris; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +/** + * This is the service that provides the factory to be bound to the collection service. + */ +public class WeatherWidgetService extends RemoteViewsService { + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return new StackRemoteViewsFactory(this.getApplicationContext(), intent); + } +} + +/** + * This is the factory that will provide data to the collection widget. + */ +class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { + private Context mContext; + private Cursor mCursor; + private int mAppWidgetId; + + public StackRemoteViewsFactory(Context context, Intent intent) { + mContext = context; + mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + } + + public void onCreate() { + // Since we reload the cursor in onDataSetChanged() which gets called immediately after + // onCreate(), we do nothing here. + } + + public void onDestroy() { + if (mCursor != null) { + mCursor.close(); + } + } + + public int getCount() { + return mCursor.getCount(); + } + + public RemoteViews getViewAt(int position) { + // Get the data for this position from the content provider + String day = "Unknown Day"; + int temp = 0; + if (mCursor.moveToPosition(position)) { + final int dayColIndex = mCursor.getColumnIndex(WeatherDataProvider.Columns.DAY); + final int tempColIndex = mCursor.getColumnIndex( + WeatherDataProvider.Columns.TEMPERATURE); + day = mCursor.getString(dayColIndex); + temp = mCursor.getInt(tempColIndex); + } + + // Return a proper item with the proper day and temperature + final String formatStr = mContext.getResources().getString(R.string.item_format_string); + final int itemId = R.layout.widget_item; + RemoteViews rv = new RemoteViews(mContext.getPackageName(), itemId); + rv.setTextViewText(R.id.widget_item, String.format(formatStr, temp, day)); + + // Set the click intent so that we can handle it and show a toast message + final Intent fillInIntent = new Intent(); + final Bundle extras = new Bundle(); + extras.putString(WeatherWidgetProvider.EXTRA_DAY_ID, day); + fillInIntent.putExtras(extras); + rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); + + return rv; + } + public RemoteViews getLoadingView() { + // We aren't going to return a default loading view in this sample + return null; + } + + public int getViewTypeCount() { + // Technically, we have two types of views (the dark and light background views) + return 2; + } + + public long getItemId(int position) { + return position; + } + + public boolean hasStableIds() { + return true; + } + + public void onDataSetChanged() { + // Refresh the cursor + if (mCursor != null) { + mCursor.close(); + } + mCursor = mContext.getContentResolver().query(WeatherDataProvider.CONTENT_URI, null, null, + null, null); + } +}