/** * Copyright 2010 Mark Wyszomierski */ package com.joelapenna.foursquared; import com.joelapenna.foursquare.Foursquare; import com.joelapenna.foursquare.types.Checkin; import com.joelapenna.foursquare.types.Group; import com.joelapenna.foursquare.types.User; import com.joelapenna.foursquared.app.LoadableListActivity; import com.joelapenna.foursquared.location.LocationUtils; import com.joelapenna.foursquared.preferences.Preferences; import com.joelapenna.foursquared.util.NotificationsUtil; import com.joelapenna.foursquared.widget.FriendListAdapter; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; import java.util.ArrayList; import java.util.List; /** * Shows a list of friends for the user id passed as an intent extra. * * @date March 9, 2010 * @author Mark Wyszomierski (markww@gmail.com) */ public class UserFriendsActivity extends LoadableListActivity { static final String TAG = "UserFriendsActivity"; static final boolean DEBUG = FoursquaredSettings.DEBUG; public static final String EXTRA_USER_ID = Foursquared.PACKAGE_NAME + ".UserFriendsActivity.EXTRA_USER_ID"; public static final String EXTRA_SHOW_ADD_FRIEND_OPTIONS = Foursquared.PACKAGE_NAME + ".UserFriendsActivity.EXTRA_SHOW_ADD_FRIEND_OPTIONS"; private StateHolder mStateHolder; private FriendListAdapter mListAdapter; private BroadcastReceiver mLoggedOutReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (DEBUG) Log.d(TAG, "onReceive: " + intent); finish(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); registerReceiver(mLoggedOutReceiver, new IntentFilter(Foursquared.INTENT_ACTION_LOGGED_OUT)); Object retained = getLastNonConfigurationInstance(); if (retained != null && retained instanceof StateHolder) { mStateHolder = (StateHolder) retained; mStateHolder.setActivityForTaskFriends(this); } else { mStateHolder = new StateHolder(); if (getIntent().getExtras().containsKey(EXTRA_USER_ID) == false) { Log.e(TAG, "UserFriendsActivity requires a userid in its intent extras."); finish(); return; } mStateHolder.setUserId(getIntent().getExtras().getString(EXTRA_USER_ID)); mStateHolder.startTaskFriends(this, mStateHolder.getUserId()); } ensureUi(); } @Override protected void onResume() { super.onResume(); } @Override public void onPause() { super.onPause(); if (isFinishing()) { mStateHolder.cancelTasks(); mListAdapter.removeObserver(); unregisterReceiver(mLoggedOutReceiver); } } @Override public Object onRetainNonConfigurationInstance() { mStateHolder.setActivityForTaskFriends(null); return mStateHolder; } private void ensureUi() { mListAdapter = new FriendListAdapter(this, ((Foursquared) getApplication()).getRemoteResourceManager(), ((Foursquared) getApplication()).getSync()); mListAdapter.setGroup(mStateHolder.getFriends()); ListView listView = getListView(); listView.setAdapter(mListAdapter); listView.setSmoothScrollbarEnabled(true); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { User user = (User) parent.getAdapter().getItem(position); Intent intent = new Intent(UserFriendsActivity.this, UserDetailsActivity.class); intent.putExtra(UserDetailsActivity.EXTRA_USER_PARCEL, user); intent.putExtra(UserDetailsActivity.EXTRA_SHOW_ADD_FRIEND_OPTIONS, true); startActivity(intent); } }); if (mStateHolder.getIsRunningFriendsTask()) { setLoadingView(); } else if (mStateHolder.getFetchedFriendsOnce() && mStateHolder.getFriends().size() == 0) { setEmptyView(); } } private void onFriendsTaskComplete(Group<User> group, Exception ex) { mListAdapter.removeObserver(); mListAdapter = new FriendListAdapter(this, ((Foursquared) getApplication()).getRemoteResourceManager(), ((Foursquared) getApplication()).getSync()); if (group != null) { mStateHolder.setFriends(group); mListAdapter.setGroup(mStateHolder.getFriends()); getListView().setAdapter(mListAdapter); boolean syncPref = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Preferences.PREFERENCE_SYNC_CONTACTS, false); if ( syncPref ) { mStateHolder.startTaskSyncContacts(((Foursquared)getApplication()).getSync(), getApplication().getContentResolver()); } } else { mStateHolder.setFriends(new Group<User>()); mListAdapter.setGroup(mStateHolder.getFriends()); getListView().setAdapter(mListAdapter); NotificationsUtil.ToastReasonForFailure(this, ex); } mStateHolder.setIsRunningFriendsTask(false); mStateHolder.setFetchedFriendsOnce(true); // TODO: We can probably tighten this up by just calling ensureUI() again. if (mStateHolder.getFriends().size() == 0) { setEmptyView(); } } /** * Gets friends of the current user we're working for. */ private static class FriendsTask extends AsyncTask<String, Void, Group<User>> { private UserFriendsActivity mActivity; private Exception mReason; public FriendsTask(UserFriendsActivity activity) { mActivity = activity; } @Override protected void onPreExecute() { mActivity.setLoadingView(); } @Override protected Group<User> doInBackground(String... params) { try { Foursquared foursquared = (Foursquared) mActivity.getApplication(); Foursquare foursquare = foursquared.getFoursquare(); return foursquare.friends( params[0], LocationUtils.createFoursquareLocation(foursquared.getLastKnownLocation())); } catch (Exception e) { mReason = e; } return null; } @Override protected void onPostExecute(Group<User> users) { if (mActivity != null) { mActivity.onFriendsTaskComplete(users, mReason); } } @Override protected void onCancelled() { if (mActivity != null) { mActivity.onFriendsTaskComplete(null, mReason); } } public void setActivity(UserFriendsActivity activity) { mActivity = activity; } } private static class StateHolder { /** User id. */ private String mUserId; /** Friends of the current user. */ private Group<User> mFriends; private FriendsTask mTaskFriends; private AsyncTask<?,?,?> mTaskSyncContacts; private boolean mIsRunningFriendsTask; private boolean mFetchedFriendsOnce; public StateHolder() { mIsRunningFriendsTask = false; mFetchedFriendsOnce = false; mFriends = new Group<User>(); } public String getUserId() { return mUserId; } public void setUserId(String userId) { mUserId = userId; } public Group<User> getFriends() { return mFriends; } public void setFriends(Group<User> friends) { mFriends = friends; } public void startTaskFriends(UserFriendsActivity activity, String userId) { mIsRunningFriendsTask = true; mTaskFriends = new FriendsTask(activity); mTaskFriends.execute(userId); } public void startTaskSyncContacts(Sync sync, ContentResolver resolver) { List<Checkin> checkins = new ArrayList<Checkin>(mFriends.size()); for ( User friend : mFriends ) { Checkin c = friend.getCheckin(); if ( c != null ) { checkins.add(c); } } if ( checkins.size() > 0 ) { mTaskSyncContacts = sync.createSyncTask().execute(); } } public void setActivityForTaskFriends(UserFriendsActivity activity) { if (mTaskFriends != null) { mTaskFriends.setActivity(activity); } } public void setIsRunningFriendsTask(boolean isRunning) { mIsRunningFriendsTask = isRunning; } public boolean getIsRunningFriendsTask() { return mIsRunningFriendsTask; } public void setFetchedFriendsOnce(boolean fetchedOnce) { mFetchedFriendsOnce = fetchedOnce; } public boolean getFetchedFriendsOnce() { return mFetchedFriendsOnce; } public void cancelTasks() { if (mTaskFriends != null) { mTaskFriends.setActivity(null); mTaskFriends.cancel(true); } if (mTaskSyncContacts != null) { mTaskSyncContacts.cancel(true); } } } }