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