/* * Copyright (C) 2009 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.joelapenna.foursquared.appwidget.stats; import android.app.PendingIntent; import android.app.Service; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.util.Log; import android.widget.RemoteViews; import android.widget.Toast; import com.joelapenna.foursquare.Foursquare; import com.joelapenna.foursquare.error.FoursquareError; import com.joelapenna.foursquare.error.FoursquareException; import com.joelapenna.foursquare.parsers.StatsParser; import com.joelapenna.foursquare.types.User; import com.joelapenna.foursquared.Foursquared; import com.joelapenna.foursquared.R; import com.joelapenna.foursquared.location.LocationUtils; import java.io.IOException; /** * UpdateService performs the AppWidget refresh and defines the views * which are updated in the RemoteViews object. The actual resources * are set within the UpdateService subclass for each widget. This * class is based on the Wiktionary Simple example provided the AOSP. * * @author Nick Burton (charlesnicholasburton [at] gmail.com) */ public abstract class UpdateService extends Service { protected static final String TAG = "UpdateService"; protected int mLayoutResource; protected int mLayoutId; protected Class<? extends AppWidgetProvider> mWidgetProviderClass; protected Class<? extends UpdateService> mUpdateServiceClass; private String mRefreshToastExtra; private boolean mShowRefreshToast = false; private static final String LEADER_BOARD_URL = "http://foursquare.com/iphone/me?uid="; private static final String LEADER_BOARD_SCOPE = "&view=all&scope=friends"; private User mUser = null; private UserStats mUserStats = null; private Context mContext; private Foursquared mFoursquared; @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); mContext = getApplicationContext(); //Toast 'refreshing widget' if user clicked widget, otherwise nothing. mRefreshToastExtra = getString(R.string.stats_widget_show_toast_extra); mShowRefreshToast = intent.getBooleanExtra(mRefreshToastExtra, mShowRefreshToast); if(mShowRefreshToast){ Toast.makeText(mContext, R.string.stats_widget_refresh_text, Toast.LENGTH_LONG).show(); } //These would actually come from SharedPrefs inside the Foursquare app. // TODO: hook in preferences // mEmail = getString(R.string.stats_widget_email); // mPword = getString(R.string.stats_widget_pword); //Set layout resource ids, specific to the widget provider size. setLayoutResources(); mFoursquared = (Foursquared)getApplication(); if (mFoursquared.isReady()) { //Build the removeViews objects then stop. RemoteViews updateViews = buildUpdate(mContext); pushUpdate(updateViews); } stopSelf(); } /** * Ids for each view are set in each subclass. */ protected abstract void setLayoutResources(); protected abstract void updateUserStats(RemoteViews views,UserStats userStats); protected abstract void updateUserRank(RemoteViews views,UserRank userRank); private void pushUpdate(RemoteViews updateViews){ ComponentName thisWidget = new ComponentName(this, mWidgetProviderClass); AppWidgetManager manager = AppWidgetManager.getInstance(this); manager.updateAppWidget(thisWidget, updateViews); } public RemoteViews buildUpdate(Context context) { RemoteViews updateViews = null; updateViews = new RemoteViews(context.getPackageName(), mLayoutResource); try { FoursquareHelper.prepareUserAgent(context); Foursquare.Location loc = LocationUtils.createFoursquareLocation(mFoursquared.getLastKnownLocation()); mUser = mFoursquared.getFoursquare().user(null, true, true, loc); String lastInitial = null; if ( mUser.getLastname() != null && !"".equals(mUser.getLastname()) ) { lastInitial = mUser.getLastname().charAt(0) + "."; } String username = mUser.getFirstname() + (lastInitial == null ? "" : " "+lastInitial); mUserStats = new UserStats(String.valueOf(mUser.getMayorCount()), String.valueOf(mUser.getBadges().size()), mUser.getCheckin().getVenue().getName(), mUser.getId(), username); //Update userStats performed in subclass, based on relevant view id. updateUserStats(updateViews,mUserStats); } catch (FoursquareException e) { Log.e(TAG, "Foursquare problem encountered", e); } catch (IOException e) { Log.e(TAG, "Couldn't contact API", e); } try { HTMLParser parser = new HTMLParser(this,mUserStats.getUserName()); String url = LEADER_BOARD_URL+mUser.getId()+LEADER_BOARD_SCOPE; parser.parse(url); UserRank userRank = parser.getUserRank(); updateUserRank(updateViews,userRank); } catch (FoursquareHelper.ParseException e) { Log.e(TAG, "Could not parse HTML response", e); } // When user clicks on widget, re-run the service Intent updateIntent = new Intent(this, mUpdateServiceClass); updateIntent.putExtra(mRefreshToastExtra, true); PendingIntent pendingIntent; int flag = PendingIntent.FLAG_UPDATE_CURRENT; pendingIntent = PendingIntent.getService(this, 0, updateIntent, flag); updateViews.setOnClickPendingIntent(mLayoutId, pendingIntent); return updateViews; } @Override public IBinder onBind(Intent intent) { // We don't need to bind to this service return null; } }