/** * Copyright 2010 Mark Wyszomierski */ package com.joelapenna.foursquared; import com.facebook.android.Facebook; import com.facebook.android.FacebookUtil; import com.facebook.android.FacebookWebViewActivity; import com.facebook.android.Facebook.PreparedUrl; import com.joelapenna.foursquare.Foursquare; import com.joelapenna.foursquare.types.FriendInvitesResult; import com.joelapenna.foursquare.types.Group; import com.joelapenna.foursquare.types.User; import com.joelapenna.foursquared.util.AddressBookEmailBuilder; import com.joelapenna.foursquared.util.AddressBookUtils; import com.joelapenna.foursquared.util.NotificationsUtil; import com.joelapenna.foursquared.util.AddressBookEmailBuilder.ContactSimple; import com.joelapenna.foursquared.widget.FriendSearchAddFriendAdapter; import com.joelapenna.foursquared.widget.FriendSearchInviteNonFoursquareUserAdapter; import com.joelapenna.foursquared.widget.SeparatedListAdapter; import org.json.JSONArray; import org.json.JSONObject; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.DialogInterface.OnDismissListener; import android.os.AsyncTask; import android.os.Bundle; import android.text.Editable; import android.text.InputType; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.Window; import android.view.View.OnClickListener; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.TextView.OnEditorActionListener; import java.util.ArrayList; import java.util.List; /** * Lets the user search for friends via first+last name, phone number, or * twitter names. Once a list of matching users is found, the user can click on * elements in the list to send a friend request to them. When the request is * successfully sent, that user is removed from the list. You can add the * INPUT_TYPE key to the intent while launching the activity to control what * type of friend search the activity will perform. Pass in one of the following * values: * <ul> * <li>INPUT_TYPE_NAME_OR_PHONE</li> * <li>INPUT_TYPE_TWITTERNAME</li> * <li>INPUT_TYPE_ADDRESSBOOK</li> * <li>INPUT_TYPE_ADDRESSBOOK_INVITE</li> * </ul> * * @date February 11, 2010 * @author Mark Wyszomierski (markww@gmail.com), foursquare. */ public class AddFriendsByUserInputActivity extends Activity { private static final String TAG = "AddFriendsByUserInputActivity"; private static final boolean DEBUG = FoursquaredSettings.DEBUG; private static final int DIALOG_ID_CONFIRM_INVITE_ALL = 1; public static final String INPUT_TYPE = "com.joelapenna.foursquared.AddFriendsByUserInputActivity.INPUT_TYPE"; public static final int INPUT_TYPE_NAME_OR_PHONE = 0; public static final int INPUT_TYPE_TWITTERNAME = 1; public static final int INPUT_TYPE_ADDRESSBOOK = 2; public static final int INPUT_TYPE_ADDRESSBOOK_INVITE = 3; public static final int INPUT_TYPE_FACEBOOK = 4; private static final int ACTIVITY_RESULT_FACEBOOK_WEBVIEW_ACTIVITY = 5; private TextView mTextViewInstructions; private TextView mTextViewAdditionalInstructions; private EditText mEditInput; private Button mBtnSearch; private ListView mListView; private ProgressDialog mDlgProgress; private int mInputType; private SeparatedListAdapter mListAdapter; private StateHolder mStateHolder; private BroadcastReceiver mLoggedOutReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (DEBUG) Log.d(TAG, "onReceive: " + intent); finish(); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (DEBUG) Log.d(TAG, "onCreate()"); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.add_friends_by_user_input_activity); registerReceiver(mLoggedOutReceiver, new IntentFilter(Foursquared.INTENT_ACTION_LOGGED_OUT)); mTextViewInstructions = (TextView) findViewById(R.id.addFriendInstructionsTextView); mTextViewAdditionalInstructions = (TextView) findViewById(R.id.addFriendInstructionsAdditionalTextView); mEditInput = (EditText) findViewById(R.id.addFriendInputEditText); mBtnSearch = (Button) findViewById(R.id.addFriendSearchButton); mListView = (ListView) findViewById(R.id.addFriendResultsListView); mListAdapter = new SeparatedListAdapter(this); mListView.setAdapter(mListAdapter); mListView.setItemsCanFocus(true); mBtnSearch.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startSearch(mEditInput.getText().toString()); } }); mEditInput.addTextChangedListener(mNamesFieldWatcher); mEditInput.setOnEditorActionListener(new OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_NULL) { startSearch(mEditInput.getText().toString()); } return false; } }); mBtnSearch.setEnabled(false); mInputType = getIntent().getIntExtra(INPUT_TYPE, INPUT_TYPE_NAME_OR_PHONE); switch (mInputType) { case INPUT_TYPE_TWITTERNAME: mTextViewInstructions.setText(getResources().getString( R.string.add_friends_by_twitter_instructions)); mEditInput.setHint(getResources().getString(R.string.add_friends_by_twitter_hint)); mEditInput.setInputType(InputType.TYPE_CLASS_TEXT); break; case INPUT_TYPE_ADDRESSBOOK: mTextViewInstructions.setText(getResources().getString( R.string.add_friends_by_addressbook_instructions)); mTextViewAdditionalInstructions.setText(getResources().getString( R.string.add_friends_by_addressbook_additional_instructions)); mEditInput.setVisibility(View.GONE); mBtnSearch.setVisibility(View.GONE); break; case INPUT_TYPE_ADDRESSBOOK_INVITE: mTextViewInstructions.setText(getResources().getString( R.string.add_friends_by_addressbook_instructions)); mTextViewAdditionalInstructions.setText(getResources().getString( R.string.add_friends_by_addressbook_additional_instructions)); mEditInput.setVisibility(View.GONE); mBtnSearch.setVisibility(View.GONE); break; case INPUT_TYPE_FACEBOOK: mTextViewInstructions.setText(getResources().getString( R.string.add_friends_by_facebook_instructions)); mTextViewAdditionalInstructions.setText(getResources().getString( R.string.add_friends_by_facebook_additional_instructions)); mEditInput.setVisibility(View.GONE); mBtnSearch.setVisibility(View.GONE); break; default: mTextViewInstructions.setText(getResources().getString( R.string.add_friends_by_name_or_phone_instructions)); mEditInput.setHint(getResources().getString(R.string.add_friends_by_name_or_phone_hint)); mEditInput.setInputType(InputType.TYPE_TEXT_FLAG_CAP_WORDS); break; } Object retained = getLastNonConfigurationInstance(); if (retained != null && retained instanceof StateHolder) { mStateHolder = (StateHolder) retained; mStateHolder.setActivityForTaskFindFriends(this); mStateHolder.setActivityForTaskFriendRequest(this); mStateHolder.setActivityForTaskSendInvite(this); // If we have run before, restore matches divider. if (mStateHolder.getRanOnce()) { populateListFromStateHolder(); } } else { mStateHolder = new StateHolder(); // If we are scanning the address book, or a facebook search, we should // kick off immediately. switch (mInputType) { case INPUT_TYPE_ADDRESSBOOK: case INPUT_TYPE_ADDRESSBOOK_INVITE: startSearch(""); break; case INPUT_TYPE_FACEBOOK: startFacebookWebViewActivity(); break; } } } @Override public void onResume() { super.onResume(); if (mStateHolder.getIsRunningTaskFindFriends()) { startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources().getString(R.string.add_friends_progress_bar_message_find)); } else if (mStateHolder.getIsRunningTaskSendFriendRequest()) { startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources() .getString(R.string.add_friends_progress_bar_message_send_request)); } else if (mStateHolder.getIsRunningTaskSendInvite()) { startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources() .getString(R.string.add_friends_progress_bar_message_send_invite)); } } @Override public void onPause() { super.onPause(); stopProgressBar(); if (isFinishing()) { mListAdapter.removeObserver(); } } @Override public void onDestroy() { super.onDestroy(); unregisterReceiver(mLoggedOutReceiver); } @Override public Object onRetainNonConfigurationInstance() { mStateHolder.setActivityForTaskFindFriends(null); mStateHolder.setActivityForTaskFriendRequest(null); mStateHolder.setActivityForTaskSendInvite(null); return mStateHolder; } private void userAdd(User user) { startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources().getString(R.string.add_friends_progress_bar_message_send_request)); mStateHolder.startTaskSendFriendRequest(AddFriendsByUserInputActivity.this, user.getId()); } private void userInfo(User user) { Intent intent = new Intent(AddFriendsByUserInputActivity.this, UserDetailsActivity.class); intent.putExtra(UserDetailsActivity.EXTRA_USER_PARCEL, user); startActivity(intent); } private void userInvite(ContactSimple contact) { startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources().getString(R.string.add_friends_progress_bar_message_send_invite)); mStateHolder.startTaskSendInvite(AddFriendsByUserInputActivity.this, contact.mEmail, false); } private void inviteAll() { startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources().getString(R.string.add_friends_progress_bar_message_send_invite)); mStateHolder.startTaskSendInvite( AddFriendsByUserInputActivity.this, mStateHolder.getUsersNotOnFoursquareAsCommaSepString(), true); } private void startSearch(String input) { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mEditInput.getWindowToken(), 0); mEditInput.setEnabled(false); mBtnSearch.setEnabled(false); startProgressBar(getResources().getString(R.string.add_friends_activity_label), getResources().getString(R.string.add_friends_progress_bar_message_find)); mStateHolder.startTaskFindFriends(AddFriendsByUserInputActivity.this, input); } private void startFacebookWebViewActivity() { Intent intent = new Intent(this, FacebookWebViewActivity.class); intent.putExtra(FacebookWebViewActivity.INTENT_EXTRA_ACTION, Facebook.LOGIN); intent.putExtra(FacebookWebViewActivity.INTENT_EXTRA_KEY_APP_ID, getResources().getString(R.string.facebook_api_key)); intent.putExtra(FacebookWebViewActivity.INTENT_EXTRA_KEY_PERMISSIONS, new String[] {});//"publish_stream", "read_stream", "offline_access"}); intent.putExtra(FacebookWebViewActivity.INTENT_EXTRA_KEY_DEBUG, false); intent.putExtra(FacebookWebViewActivity.INTENT_EXTRA_KEY_CLEAR_COOKIES, true); startActivityForResult(intent, ACTIVITY_RESULT_FACEBOOK_WEBVIEW_ACTIVITY); } private void startProgressBar(String title, String message) { if (mDlgProgress == null) { mDlgProgress = ProgressDialog.show(this, title, message); } mDlgProgress.show(); } private void stopProgressBar() { if (mDlgProgress != null) { mDlgProgress.dismiss(); mDlgProgress = null; } } @Override protected Dialog onCreateDialog(int id) { switch (id) { case DIALOG_ID_CONFIRM_INVITE_ALL: AlertDialog dlgInfo = new AlertDialog.Builder(this) .setTitle(getResources().getString(R.string.add_friends_contacts_title_invite_all)) .setIcon(0) .setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { inviteAll(); } }) .setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }) .setMessage(getResources().getString(R.string.add_friends_contacts_message_invite_all, String.valueOf(mStateHolder.getUsersNotOnFoursquare().size()))) .create(); dlgInfo.setOnDismissListener(new OnDismissListener() { public void onDismiss(DialogInterface dialog) { removeDialog(DIALOG_ID_CONFIRM_INVITE_ALL); } }); return dlgInfo; } return null; } /** * Listen for FacebookWebViewActivity finishing, inspect success/failure and returned * request parameters. */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == ACTIVITY_RESULT_FACEBOOK_WEBVIEW_ACTIVITY) { // If RESULT_OK, means the request was attempted, but we still have to check the return status. if (resultCode == RESULT_OK) { // Check return status. if (data.getBooleanExtra(FacebookWebViewActivity.INTENT_RESULT_KEY_RESULT_STATUS, false)) { // If ok, the result bundle will contain all data from the webview. Bundle bundle = data.getBundleExtra(FacebookWebViewActivity.INTENT_RESULT_KEY_RESULT_BUNDLE); // We can switch on the action here, the activity echoes it back to us for convenience. String suppliedAction = data.getStringExtra(FacebookWebViewActivity.INTENT_RESULT_KEY_SUPPLIED_ACTION); if (suppliedAction.equals(Facebook.LOGIN)) { // We can now start a task to fetch foursquare friends using their facebook id. mStateHolder.startTaskFindFriends( AddFriendsByUserInputActivity.this, bundle.getString(Facebook.TOKEN)); } } else { // Error running the operation, report to user perhaps. String error = data.getStringExtra(FacebookWebViewActivity.INTENT_RESULT_KEY_ERROR); Log.e(TAG, error); Toast.makeText(this, error, Toast.LENGTH_LONG).show(); finish(); } } else { // If the user cancelled enterting their facebook credentials, exit here too. finish(); } } } private void populateListFromStateHolder() { mListAdapter.removeObserver(); mListAdapter = new SeparatedListAdapter(this); if (mStateHolder.getUsersOnFoursquare().size() + mStateHolder.getUsersNotOnFoursquare().size() > 0) { if (mStateHolder.getUsersOnFoursquare().size() > 0) { FriendSearchAddFriendAdapter adapter = new FriendSearchAddFriendAdapter( this, mButtonRowClickHandler, ((Foursquared)getApplication()).getRemoteResourceManager()); adapter.setGroup(mStateHolder.getUsersOnFoursquare()); mListAdapter.addSection( getResources().getString(R.string.add_friends_contacts_found_on_foursqare), adapter); } if (mStateHolder.getUsersNotOnFoursquare().size() > 0) { FriendSearchInviteNonFoursquareUserAdapter adapter = new FriendSearchInviteNonFoursquareUserAdapter( this, mAdapterListenerInvites); adapter.setContacts(mStateHolder.getUsersNotOnFoursquare()); mListAdapter.addSection( getResources().getString(R.string.add_friends_contacts_not_found_on_foursqare), adapter); } } else { Toast.makeText(this, getResources().getString(R.string.add_friends_no_matches), Toast.LENGTH_SHORT).show(); } mListView.setAdapter(mListAdapter); } private void onFindFriendsTaskComplete(FindFriendsResult result, Exception ex) { if (result != null) { mStateHolder.setUsersOnFoursquare(result.getUsersOnFoursquare()); mStateHolder.setUsersNotOnFoursquare(result.getUsersNotOnFoursquare()); if (result.getUsersOnFoursquare().size() + result.getUsersNotOnFoursquare().size() < 1) { Toast.makeText(this, getResources().getString(R.string.add_friends_no_matches), Toast.LENGTH_SHORT).show(); } } else { NotificationsUtil.ToastReasonForFailure(AddFriendsByUserInputActivity.this, ex); } populateListFromStateHolder(); mEditInput.setEnabled(true); mBtnSearch.setEnabled(true); mStateHolder.setIsRunningTaskFindFriends(false); stopProgressBar(); } private void onSendFriendRequestTaskComplete(User friendRequestRecipient, Exception ex) { if (friendRequestRecipient != null) { // We do a linear search to find the row to remove, ouch. int position = 0; for (User it : mStateHolder.getUsersOnFoursquare()) { if (it.getId().equals(friendRequestRecipient.getId())) { mStateHolder.getUsersOnFoursquare().remove(position); break; } position++; } mListAdapter.notifyDataSetChanged(); Toast.makeText(AddFriendsByUserInputActivity.this, getResources().getString(R.string.add_friends_request_sent_ok), Toast.LENGTH_SHORT).show(); } else { NotificationsUtil.ToastReasonForFailure(AddFriendsByUserInputActivity.this, ex); } mEditInput.setEnabled(true); mBtnSearch.setEnabled(true); mStateHolder.setIsRunningTaskSendFriendRequest(false); stopProgressBar(); } private void onSendInviteTaskComplete(String email, boolean isAllEmails, Exception ex) { if (email != null) { if (isAllEmails) { mStateHolder.getUsersNotOnFoursquare().clear(); Toast.makeText(AddFriendsByUserInputActivity.this, getResources().getString(R.string.add_friends_invites_sent_ok), Toast.LENGTH_SHORT).show(); } else { // We do a linear search to find the row to remove, ouch. int position = 0; for (ContactSimple it : mStateHolder.getUsersNotOnFoursquare()) { if (it.mEmail.equals(email)) { mStateHolder.getUsersNotOnFoursquare().remove(position); break; } position++; } Toast.makeText(AddFriendsByUserInputActivity.this, getResources().getString(R.string.add_friends_invite_sent_ok), Toast.LENGTH_SHORT).show(); } mListAdapter.notifyDataSetChanged(); } else { NotificationsUtil.ToastReasonForFailure(AddFriendsByUserInputActivity.this, ex); } mEditInput.setEnabled(true); mBtnSearch.setEnabled(true); mStateHolder.setIsRunningTaskSendInvite(false); stopProgressBar(); } private static class FindFriendsTask extends AsyncTask<String, Void, FindFriendsResult> { private AddFriendsByUserInputActivity mActivity; private Exception mReason; public FindFriendsTask(AddFriendsByUserInputActivity activity) { mActivity = activity; } public void setActivity(AddFriendsByUserInputActivity activity) { mActivity = activity; } @Override protected void onPreExecute() { mActivity.startProgressBar(mActivity.getResources().getString( R.string.add_friends_activity_label), mActivity.getResources().getString( R.string.add_friends_progress_bar_message_find)); } @Override protected FindFriendsResult doInBackground(String... params) { try { Foursquared foursquared = (Foursquared) mActivity.getApplication(); Foursquare foursquare = foursquared.getFoursquare(); FindFriendsResult result = new FindFriendsResult(); switch (mActivity.mInputType) { case INPUT_TYPE_TWITTERNAME: result.setUsersOnFoursquare(foursquare.findFriendsByTwitter(params[0])); break; case INPUT_TYPE_ADDRESSBOOK: scanAddressBook(result, foursquare, foursquared, false); break; case INPUT_TYPE_ADDRESSBOOK_INVITE: scanAddressBook(result, foursquare, foursquared, true); break; case INPUT_TYPE_FACEBOOK: // For facebook, we need to first get all friend uids, then use that with the foursquare api. String facebookFriendIds = getFacebookFriendIds(params[0]); if (TextUtils.isEmpty(facebookFriendIds)) { result.setUsersOnFoursquare(new Group<User>()); } result.setUsersOnFoursquare(foursquare.findFriendsByFacebook(facebookFriendIds)); break; default: // Combine searches for name/phone, results returned in one list. Group<User> users = new Group<User>(); users.addAll(foursquare.findFriendsByPhone(params[0])); users.addAll(foursquare.findFriendsByName(params[0])); result.setUsersOnFoursquare(users); break; } return result; } catch (Exception e) { if (DEBUG) Log.d(TAG, "FindFriendsTask: Exception doing add friends by name", e); mReason = e; } return null; } private String getFacebookFriendIds(String facebookToken) { Facebook facebook = new Facebook(); facebook.setAccessToken(facebookToken); String friendsAsJson = ""; try { PreparedUrl purl = facebook.requestUrl("me/friends"); friendsAsJson = FacebookUtil.openUrl(purl.getUrl(), purl.getHttpMethod(), purl.getParameters()); } catch (Exception ex) { Log.e(TAG, "Error getting facebook friends as json.", ex); return friendsAsJson; } // {"data":[{"name":"Friends Name","id":"12345"}]} StringBuilder sb = new StringBuilder(2048); try { JSONObject json = new JSONObject(friendsAsJson); JSONArray friends = json.getJSONArray("data"); for (int i = 0, m = friends.length(); i < m; i++) { JSONObject friend = friends.getJSONObject(i); sb.append(friend.get("id")); sb.append(","); } if (sb.length() > 0 && sb.charAt(sb.length()-1) == ',') { sb.deleteCharAt(sb.length()-1); } } catch (Exception ex) { Log.e(TAG, "Error deserializing facebook friends json object.", ex); } return sb.toString(); } private void scanAddressBook(FindFriendsResult result, Foursquare foursquare, Foursquared foursquared, boolean invites) throws Exception { AddressBookUtils addr = AddressBookUtils.addressBookUtils(); AddressBookEmailBuilder bld = addr.getAllContactsEmailAddressesInfo(mActivity); String phones = addr.getAllContactsPhoneNumbers(mActivity); String emails = bld.getEmailsCommaSeparated(); if (!TextUtils.isEmpty(phones) || !TextUtils.isEmpty(emails)) { FriendInvitesResult xml = foursquare.findFriendsByPhoneOrEmail(phones, emails); result.setUsersOnFoursquare(xml.getContactsOnFoursquare()); if (invites) { // Get a contact name for each email address we can send an invite to. List<ContactSimple> contactsNotOnFoursquare = new ArrayList<ContactSimple>(); for (String it : xml.getContactEmailsNotOnFoursquare()) { ContactSimple contact = new ContactSimple(); contact.mEmail = it; contact.mName = bld.getNameForEmail(it); contactsNotOnFoursquare.add(contact); } result.setUsersNotOnFoursquare(contactsNotOnFoursquare); } } } @Override protected void onPostExecute(FindFriendsResult result) { if (DEBUG) Log.d(TAG, "FindFriendsTask: onPostExecute()"); if (mActivity != null) { mActivity.onFindFriendsTaskComplete(result, mReason); } } @Override protected void onCancelled() { if (mActivity != null) { mActivity.onFindFriendsTaskComplete( null, new Exception("Friend search cancelled.")); } } } private static class SendFriendRequestTask extends AsyncTask<String, Void, User> { private AddFriendsByUserInputActivity mActivity; private Exception mReason; public SendFriendRequestTask(AddFriendsByUserInputActivity activity) { mActivity = activity; } public void setActivity(AddFriendsByUserInputActivity activity) { mActivity = activity; } @Override protected void onPreExecute() { mActivity.startProgressBar(mActivity.getResources().getString( R.string.add_friends_activity_label), mActivity.getResources().getString( R.string.add_friends_progress_bar_message_send_request)); } @Override protected User doInBackground(String... params) { try { Foursquared foursquared = (Foursquared) mActivity.getApplication(); Foursquare foursquare = foursquared.getFoursquare(); User user = foursquare.friendSendrequest(params[0]); return user; } catch (Exception e) { if (DEBUG) Log.d(TAG, "SendFriendRequestTask: Exception doing send friend request.", e); mReason = e; } return null; } @Override protected void onPostExecute(User user) { if (DEBUG) Log.d(TAG, "SendFriendRequestTask: onPostExecute()"); if (mActivity != null) { mActivity.onSendFriendRequestTaskComplete(user, mReason); } } @Override protected void onCancelled() { if (mActivity != null) { mActivity.onSendFriendRequestTaskComplete(null, new Exception( "Friend invitation cancelled.")); } } } private static class SendInviteTask extends AsyncTask<String, Void, String> { private AddFriendsByUserInputActivity mActivity; private boolean mIsAllEmails; private Exception mReason; public SendInviteTask(AddFriendsByUserInputActivity activity, boolean isAllEmails) { mActivity = activity; mIsAllEmails = isAllEmails; } public void setActivity(AddFriendsByUserInputActivity activity) { mActivity = activity; } @Override protected void onPreExecute() { mActivity.startProgressBar(mActivity.getResources().getString( R.string.add_friends_activity_label), mActivity.getResources().getString( R.string.add_friends_progress_bar_message_send_invite)); } @Override protected String doInBackground(String... params) { try { Foursquared foursquared = (Foursquared) mActivity.getApplication(); Foursquare foursquare = foursquared.getFoursquare(); foursquare.inviteByEmail(params[0]); return params[0]; } catch (Exception e) { Log.e(TAG, "SendInviteTask: Exception sending invite.", e); mReason = e; } return null; } @Override protected void onPostExecute(String email) { if (DEBUG) Log.d(TAG, "SendInviteTask: onPostExecute()"); if (mActivity != null) { mActivity.onSendInviteTaskComplete(email, mIsAllEmails, mReason); } } @Override protected void onCancelled() { if (mActivity != null) { mActivity.onSendInviteTaskComplete(null, mIsAllEmails, new Exception("Invite send cancelled.")); } } } private static class StateHolder { FindFriendsTask mTaskFindFriends; SendFriendRequestTask mTaskSendFriendRequest; SendInviteTask mTaskSendInvite; Group<User> mUsersOnFoursquare; List<ContactSimple> mUsersNotOnFoursquare; boolean mIsRunningTaskFindFriends; boolean mIsRunningTaskSendFriendRequest; boolean mIsRunningTaskSendInvite; boolean mRanOnce; public StateHolder() { mUsersOnFoursquare = new Group<User>(); mUsersNotOnFoursquare = new ArrayList<ContactSimple>(); mIsRunningTaskFindFriends = false; mIsRunningTaskSendFriendRequest = false; mIsRunningTaskSendInvite = false; mRanOnce = false; } public Group<User> getUsersOnFoursquare() { return mUsersOnFoursquare; } public void setUsersOnFoursquare(Group<User> usersOnFoursquare) { mUsersOnFoursquare = usersOnFoursquare; mRanOnce = true; } public List<ContactSimple> getUsersNotOnFoursquare() { return mUsersNotOnFoursquare; } public void setUsersNotOnFoursquare(List<ContactSimple> usersNotOnFoursquare) { mUsersNotOnFoursquare = usersNotOnFoursquare; } public void startTaskFindFriends(AddFriendsByUserInputActivity activity, String input) { mIsRunningTaskFindFriends = true; mTaskFindFriends = new FindFriendsTask(activity); mTaskFindFriends.execute(input); } public void startTaskSendFriendRequest(AddFriendsByUserInputActivity activity, String userId) { mIsRunningTaskSendFriendRequest = true; mTaskSendFriendRequest = new SendFriendRequestTask(activity); mTaskSendFriendRequest.execute(userId); } public void startTaskSendInvite(AddFriendsByUserInputActivity activity, String email, boolean isAllEmails) { mIsRunningTaskSendInvite = true; mTaskSendInvite = new SendInviteTask(activity, isAllEmails); mTaskSendInvite.execute(email); } public void setActivityForTaskFindFriends(AddFriendsByUserInputActivity activity) { if (mTaskFindFriends != null) { mTaskFindFriends.setActivity(activity); } } public void setActivityForTaskFriendRequest(AddFriendsByUserInputActivity activity) { if (mTaskSendFriendRequest != null) { mTaskSendFriendRequest.setActivity(activity); } } public void setActivityForTaskSendInvite(AddFriendsByUserInputActivity activity) { if (mTaskSendInvite != null) { mTaskSendInvite.setActivity(activity); } } public void setIsRunningTaskFindFriends(boolean isRunning) { mIsRunningTaskFindFriends = isRunning; } public void setIsRunningTaskSendFriendRequest(boolean isRunning) { mIsRunningTaskSendFriendRequest = isRunning; } public void setIsRunningTaskSendInvite(boolean isRunning) { mIsRunningTaskSendInvite = isRunning; } public boolean getIsRunningTaskFindFriends() { return mIsRunningTaskFindFriends; } public boolean getIsRunningTaskSendFriendRequest() { return mIsRunningTaskSendFriendRequest; } public boolean getIsRunningTaskSendInvite() { return mIsRunningTaskSendInvite; } public boolean getRanOnce() { return mRanOnce; } public String getUsersNotOnFoursquareAsCommaSepString() { StringBuilder sb = new StringBuilder(2048); for (ContactSimple it : mUsersNotOnFoursquare) { if (sb.length() > 0) { sb.append(","); } sb.append(it.mEmail); } return sb.toString(); } } private TextWatcher mNamesFieldWatcher = new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { mBtnSearch.setEnabled(!TextUtils.isEmpty(s)); } }; /** * This handler will be called when the user clicks on buttons in one of the * listview's rows. */ private FriendSearchAddFriendAdapter.ButtonRowClickHandler mButtonRowClickHandler = new FriendSearchAddFriendAdapter.ButtonRowClickHandler() { @Override public void onBtnClickAdd(User user) { userAdd(user); } @Override public void onInfoAreaClick(User user) { userInfo(user); } }; private FriendSearchInviteNonFoursquareUserAdapter.AdapterListener mAdapterListenerInvites = new FriendSearchInviteNonFoursquareUserAdapter.AdapterListener() { @Override public void onBtnClickInvite(ContactSimple contact) { userInvite(contact); } @Override public void onInfoAreaClick(ContactSimple contact) { // We could popup an intent for this contact so they can see // who we're talking about? } @Override public void onInviteAll() { showDialog(DIALOG_ID_CONFIRM_INVITE_ALL); } }; private static class FindFriendsResult { private Group<User> mUsersOnFoursquare; private List<ContactSimple> mUsersNotOnFoursquare; public FindFriendsResult() { mUsersOnFoursquare = new Group<User>(); mUsersNotOnFoursquare = new ArrayList<ContactSimple>(); } public Group<User> getUsersOnFoursquare() { return mUsersOnFoursquare; } public void setUsersOnFoursquare(Group<User> users) { if (users != null) { mUsersOnFoursquare = users; } } public List<ContactSimple> getUsersNotOnFoursquare() { return mUsersNotOnFoursquare; } public void setUsersNotOnFoursquare(List<ContactSimple> usersNotOnFoursquare) { if (usersNotOnFoursquare != null) { mUsersNotOnFoursquare = usersNotOnFoursquare; } } } }