1 /* 2 * Copyright (C) 2011 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.weatherlistwidget; 18 19 import java.util.ArrayList; 20 import java.util.List; 21 22 import android.appwidget.AppWidgetManager; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.ContentUris; 26 import android.database.Cursor; 27 import android.net.Uri; 28 import android.os.Bundle; 29 import android.widget.RemoteViews; 30 import android.widget.RemoteViewsService; 31 32 /** 33 * This is the service that provides the factory to be bound to the collection service. 34 */ 35 public class WeatherWidgetService extends RemoteViewsService { 36 @Override onGetViewFactory(Intent intent)37 public RemoteViewsFactory onGetViewFactory(Intent intent) { 38 return new StackRemoteViewsFactory(this.getApplicationContext(), intent); 39 } 40 } 41 42 /** 43 * This is the factory that will provide data to the collection widget. 44 */ 45 class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory { 46 private Context mContext; 47 private Cursor mCursor; 48 private int mAppWidgetId; 49 StackRemoteViewsFactory(Context context, Intent intent)50 public StackRemoteViewsFactory(Context context, Intent intent) { 51 mContext = context; 52 mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 53 AppWidgetManager.INVALID_APPWIDGET_ID); 54 } 55 onCreate()56 public void onCreate() { 57 // Since we reload the cursor in onDataSetChanged() which gets called immediately after 58 // onCreate(), we do nothing here. 59 } 60 onDestroy()61 public void onDestroy() { 62 if (mCursor != null) { 63 mCursor.close(); 64 } 65 } 66 getCount()67 public int getCount() { 68 return mCursor.getCount(); 69 } 70 getViewAt(int position)71 public RemoteViews getViewAt(int position) { 72 // Get the data for this position from the content provider 73 String day = "Unknown Day"; 74 int temp = 0; 75 if (mCursor.moveToPosition(position)) { 76 final int dayColIndex = mCursor.getColumnIndex(WeatherDataProvider.Columns.DAY); 77 final int tempColIndex = mCursor.getColumnIndex( 78 WeatherDataProvider.Columns.TEMPERATURE); 79 day = mCursor.getString(dayColIndex); 80 temp = mCursor.getInt(tempColIndex); 81 } 82 83 // Return a proper item with the proper day and temperature 84 final String formatStr = mContext.getResources().getString(R.string.item_format_string); 85 final int itemId = R.layout.widget_item; 86 RemoteViews rv = new RemoteViews(mContext.getPackageName(), itemId); 87 rv.setTextViewText(R.id.widget_item, String.format(formatStr, temp, day)); 88 89 // Set the click intent so that we can handle it and show a toast message 90 final Intent fillInIntent = new Intent(); 91 final Bundle extras = new Bundle(); 92 extras.putString(WeatherWidgetProvider.EXTRA_DAY_ID, day); 93 fillInIntent.putExtras(extras); 94 rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent); 95 96 return rv; 97 } getLoadingView()98 public RemoteViews getLoadingView() { 99 // We aren't going to return a default loading view in this sample 100 return null; 101 } 102 getViewTypeCount()103 public int getViewTypeCount() { 104 // Technically, we have two types of views (the dark and light background views) 105 return 2; 106 } 107 getItemId(int position)108 public long getItemId(int position) { 109 return position; 110 } 111 hasStableIds()112 public boolean hasStableIds() { 113 return true; 114 } 115 onDataSetChanged()116 public void onDataSetChanged() { 117 // Refresh the cursor 118 if (mCursor != null) { 119 mCursor.close(); 120 } 121 mCursor = mContext.getContentResolver().query(WeatherDataProvider.CONTENT_URI, null, null, 122 null, null); 123 } 124 } 125