[markww-foursquared] push by markww - Adding support for adding friends, responding to friend requests. on 2010-02-19 00:24 GMT

1 view
Skip to first unread message

markww-fo...@googlecode.com

unread,
Feb 18, 2010, 7:25:17 PM2/18/10
to foursqu...@googlegroups.com
Revision: ab3e9aca49
Author: mar...@gmail.com
Date: Thu Feb 18 19:20:08 2010
Log: Adding support for adding friends, responding to friend requests.
http://code.google.com/r/markww-foursquared/source/detail?r=ab3e9aca49

Added:
/main/res/layout/add_friends_activity.xml
/main/res/layout/add_friends_by_user_input_activity.xml
/main/res/layout/add_friends_list_item.xml
/main/res/layout/friend_request_list_item.xml
/main/res/layout/friend_requests_activity.xml
/main/src/com/joelapenna/foursquared/AddFriendsActivity.java
/main/src/com/joelapenna/foursquared/AddFriendsByUserInputActivity.java
/main/src/com/joelapenna/foursquared/FriendRequestsActivity.java
/main/src/com/joelapenna/foursquared/util/AddressBookUtils.java
/main/src/com/joelapenna/foursquared/util/AddressBookUtils3and4.java
/main/src/com/joelapenna/foursquared/util/AddressBookUtils5.java
/main/src/com/joelapenna/foursquared/widget/FriendRequestsAdapter.java

/main/src/com/joelapenna/foursquared/widget/FriendSearchAddFriendAdapter.java
Modified:
/main/AndroidManifest.xml
/main/res/values/strings.xml
/main/src/com/joelapenna/foursquare/Foursquare.java
/main/src/com/joelapenna/foursquare/FoursquareHttpApiV1.java
/main/src/com/joelapenna/foursquared/PreferenceActivity.java
/main/src/com/joelapenna/foursquared/widget/BaseGroupAdapter.java

=======================================
--- /dev/null
+++ /main/res/layout/add_friends_activity.xml Thu Feb 18 19:20:08 2010
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ >
+ <ScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/add_friends_instructions"
+ android:paddingBottom="20dip" />
+
+ <Button
+ android:id="@+id/findFriendsByAddressBook"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/add_friends_by_address_book" />
+
+ <Button
+ android:id="@+id/findFriendsByTwitter"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/add_friends_by_twitter_btn_label" />
+
+ <Button
+ android:id="@+id/findFriendsByName"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/add_friends_by_name_btn_label" />
+
+ <Button
+ android:id="@+id/findFriendsByPhoneNumber"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/add_friends_by_phonenumber_btn_label" />
+
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
=======================================
--- /dev/null
+++ /main/res/layout/add_friends_by_user_input_activity.xml Thu Feb 18
19:20:08 2010
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingBottom="8dip"
+ >
+
+ <TextView
+ android:id="@+id/addFriendInstructionsTextView"
+ style="@style/listSeparatorTextViewStyle" />
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="20dip" >
+
+ <TextView
+ android:id="@+id/addFriendInstructionsAdditionalTextView"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+
+ <EditText
+ android:id="@+id/addFriendInputEditText"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textCapWords"
+ android:imeOptions="actionNext"
+ android:hint="@string/add_friends_by_name_hint" />
+
+ <Button
+ android:id="@+id/addFriendSearchButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_vertical"
+ android:layout_gravity="right"
+ android:text=" Search " />
+
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/addFriendResultsMatchesTitleTextView"
+ android:text="Matches"
+ android:visibility="gone"
+ style="@style/listSeparatorTextViewStyle" />
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:paddingTop="8dip"
+ >
+
+ <ListView
+ android:id="@+id/addFriendResultsListView"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:dividerHeight="1dip"
+ android:drawSelectorOnTop="false"
+ android:scrollbars="vertical" />
+
+ </LinearLayout>
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /main/res/layout/add_friends_list_item.xml Thu Feb 18 19:20:08 2010
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2009 Joe LaPenna -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/addFriendListItemBackground"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:paddingRight="12dip"
+ >
+ <TextView
+ android:id="@+id/addFriendListItemName"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textColor="@color/black_end"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:layout_gravity="center_vertical"
+ android:paddingLeft="5dip" />
+<!--
+ <ImageView
+ android:id="@+id/addFriendListItemAddButton"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_gravity="right"
+ android:gravity="center_vertical"
+ android:src="@drawable/recent_checkins_tab_unselected" />
+ -->
+
+ <Button
+ android:id="@+id/addFriendListItemAddButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:text="Add" />
+
+ <Button
+ android:id="@+id/addFriendListItemInfoButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:text="Info" />
+
+ <!--
+ android:text="@string/add_friends_by_address_book"
+ -->
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /main/res/layout/friend_request_list_item.xml Thu Feb 18 19:20:08 2010
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2009 Joe LaPenna -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/addFriendListItemBackground"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:paddingRight="12dip"
+ >
+ <TextView
+ android:id="@+id/addFriendListItemName"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textColor="@color/black_end"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:layout_gravity="center_vertical"
+ android:paddingLeft="5dip" />
+
+ <Button
+ android:id="@+id/friendRequestInfoButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:text="Info" />
+
+ <Button
+ android:id="@+id/friendRequestApproveButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:text="Approve" />
+
+ <Button
+ android:id="@+id/friendRequestDenyButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:text="Deny" />
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /main/res/layout/friend_requests_activity.xml Thu Feb 18 19:20:08 2010
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ >
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_height="fill_parent"
+ android:layout_width="fill_parent" />
+
+ <LinearLayout
+ android:id="@android:id/empty"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/black_end"
+ android:textAppearance="@android:style/TextAppearance.Small"
+ android:text="You have no new friend requests."
+ />
+ </LinearLayout>
+
+</LinearLayout>
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/AddFriendsActivity.java Thu Feb 18
19:20:08 2010
@@ -0,0 +1,98 @@
+/**
+ * Copyright 2009 Joe LaPenna
+ */
+
+package com.joelapenna.foursquared;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+/**
+ * Presents the user with a list of different methods for adding foursquare
+ * friends.
+ *
+ * @date February 11, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class AddFriendsActivity extends Activity {
+ private static final String TAG = "AddFriendsActivity";
+ private static final boolean DEBUG = FoursquaredSettings.DEBUG;
+
+ 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()");
+ setContentView(R.layout.add_friends_activity);
+ registerReceiver(mLoggedOutReceiver, new
IntentFilter(Foursquared.INTENT_ACTION_LOGGED_OUT));
+
+ Button btnAddFriendsByAddressBook = (Button)
findViewById(R.id.findFriendsByAddressBook);
+ btnAddFriendsByAddressBook.setOnClickListener(new
OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ Intent intent = new Intent(AddFriendsActivity.this,
+ AddFriendsByUserInputActivity.class);
+ intent.putExtra(AddFriendsByUserInputActivity.INPUT_TYPE,
+
AddFriendsByUserInputActivity.INPUT_TYPE_ADDRESSBOOK);
+ startActivity(intent);
+ }
+ });
+
+ Button btnAddFriendsByTwitter = (Button)
findViewById(R.id.findFriendsByTwitter);
+ btnAddFriendsByTwitter.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ Intent intent = new Intent(AddFriendsActivity.this,
+ AddFriendsByUserInputActivity.class);
+ intent.putExtra(AddFriendsByUserInputActivity.INPUT_TYPE,
+
AddFriendsByUserInputActivity.INPUT_TYPE_TWITTERNAME);
+ startActivity(intent);
+ }
+ });
+
+ Button btnAddFriendsByName = (Button)
findViewById(R.id.findFriendsByName);
+ btnAddFriendsByName.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ Intent intent = new Intent(AddFriendsActivity.this,
+ AddFriendsByUserInputActivity.class);
+ intent.putExtra(AddFriendsByUserInputActivity.INPUT_TYPE,
+
AddFriendsByUserInputActivity.INPUT_TYPE_USERNAMES);
+ startActivity(intent);
+ }
+ });
+
+ Button btnAddFriendsByPhoneNumber = (Button)
findViewById(R.id.findFriendsByPhoneNumber);
+ btnAddFriendsByPhoneNumber.setOnClickListener(new
OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ Intent intent = new Intent(AddFriendsActivity.this,
+ AddFriendsByUserInputActivity.class);
+ intent.putExtra(AddFriendsByUserInputActivity.INPUT_TYPE,
+
AddFriendsByUserInputActivity.INPUT_TYPE_PHONENUMBERS);
+ startActivity(intent);
+ }
+ });
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mLoggedOutReceiver);
+ }
+}
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/AddFriendsByUserInputActivity.java
Thu Feb 18 19:20:08 2010
@@ -0,0 +1,515 @@
+/**
+ * Copyright 2009 Joe LaPenna
+ */
+
+package com.joelapenna.foursquared;
+
+import com.joelapenna.foursquare.Foursquare;
+import com.joelapenna.foursquare.types.Group;
+import com.joelapenna.foursquare.types.User;
+import com.joelapenna.foursquared.util.AddressBookUtils;
+import com.joelapenna.foursquared.util.NotificationsUtil;
+import com.joelapenna.foursquared.widget.FriendSearchAddFriendAdapter;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.view.Window;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+/**
+ * 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_USERNAMES</li>
+ * <li>INPUT_TYPE_PHONENUMBERS</li>
+ * <li>INPUT_TYPE_TWITTERNAME</li>
+ * <li>INPUT_TYPE_ADDRESSBOOK</li>
+ * </ul>
+ *
+ * @date February 11, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class AddFriendsByUserInputActivity extends Activity {
+ private static final String TAG = "AddFriendsByUserInputActivity";
+ private static final boolean DEBUG = FoursquaredSettings.DEBUG;
+
+ public static final String INPUT_TYPE
= "com.joelapenna.foursquared.AddFriendsByUserInputActivity.INPUT_TYPE";
+ public static final int INPUT_TYPE_USERNAMES = 0;
+ public static final int INPUT_TYPE_PHONENUMBERS = 1;
+ public static final int INPUT_TYPE_TWITTERNAME = 2;
+ public static final int INPUT_TYPE_ADDRESSBOOK = 3;
+
+ private TextView mTextViewInstructions;
+ private TextView mTextViewAdditionalInstructions;
+ private EditText mEditInput;
+ private Button mBtnSearch;
+ private TextView mTextViewMatches;
+ private ListView mListView;
+ private ProgressDialog mDlgProgress;
+
+ private int mInputType;
+ private FriendSearchAddFriendAdapter 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);
+ mTextViewMatches = (TextView)
findViewById(R.id.addFriendResultsMatchesTitleTextView);
+ mListView = (ListView) findViewById(R.id.addFriendResultsListView);
+
+ mListAdapter = new FriendSearchAddFriendAdapter(this,
+ new FriendSearchAddFriendAdapter.ButtonRowClickHandler() {
+ @Override
+ public void onBtnClickAdd(User user) {
+ userAdd(user);
+ }
+
+ @Override
+ public void onBtnClickInfo(User user) {
+ userInfo(user);
+ }
+ });
+ mListView.setAdapter(mListAdapter);
+ mListView.setItemsCanFocus(true);
+
+ mBtnSearch.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ 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,
mEditInput
+ .getText().toString());
+ }
+ });
+ mEditInput.addTextChangedListener(mNamesFieldWatcher);
+ mBtnSearch.setEnabled(false);
+
+ mInputType = getIntent().getIntExtra(INPUT_TYPE,
INPUT_TYPE_USERNAMES);
+ switch (mInputType) {
+ case INPUT_TYPE_PHONENUMBERS:
+ mTextViewInstructions.setText(getResources().getString(
+ R.string.add_friends_by_phonenumber_instructions));
+ mEditInput.setHint(getResources().getString(
+ R.string.add_friends_by_phonenumber_hint));
+ break;
+ 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));
+ 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;
+ default:
+ mTextViewInstructions.setText(getResources().getString(
+ R.string.add_friends_by_name_instructions));
+
mEditInput.setHint(getResources().getString(R.string.add_friends_by_name_hint));
+ break;
+ }
+
+ Object retained = getLastNonConfigurationInstance();
+ if (retained != null && retained instanceof StateHolder) {
+ mStateHolder = (StateHolder) retained;
+ mStateHolder.setActivityForTaskFindFriends(this);
+ mStateHolder.setActivityForTaskFriendRequest(this);
+
+ // If we have run before, restore matches divider.
+ if (mStateHolder.getRanOnce()) {
+ mTextViewMatches.setVisibility(View.VISIBLE);
+ }
+ } else {
+ mStateHolder = new StateHolder();
+
+ // If we are scanning the address book, we should kick it off
+ // immediately.
+ if (mInputType == INPUT_TYPE_ADDRESSBOOK) {
+ 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, "");
+ }
+ }
+ }
+
+ @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));
+ }
+
+ mListAdapter.setGroup(mStateHolder.getFoundFriends());
+ mListAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ stopProgressBar();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mLoggedOutReceiver);
+ }
+
+ @Override
+ public Object onRetainNonConfigurationInstance() {
+ mStateHolder.setActivityForTaskFindFriends(null);
+ mStateHolder.setActivityForTaskFriendRequest(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,
UserActivity.class);
+ intent.putExtra(UserActivity.EXTRA_USER, user.getId());
+ intent.setData(Uri.parse("http://foursquare.com/user/" +
user.getId()));
+ startActivity(intent);
+ }
+
+ 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;
+ }
+ }
+
+ private void onFindFriendsTaskComplete(Group<User> users, Exception
ex) {
+ try {
+ // Populate the list control below now.
+ if (users != null) {
+ mStateHolder.setFoundFriends(users);
+ mListAdapter.setGroup(mStateHolder.getFoundFriends());
+ mListAdapter.notifyDataSetChanged();
+ mTextViewMatches.setVisibility(View.VISIBLE);
+ if (users.size() < 1) {
+ mTextViewMatches.setVisibility(View.GONE);
+ Toast.makeText(this,
getResources().getString(R.string.add_friends_no_matches),
+ Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ // If error, feed list adapter empty user group.
+ mListAdapter.setGroup(new Group<User>());
+ mListAdapter.notifyDataSetChanged();
+
NotificationsUtil.ToastReasonForFailure(AddFriendsByUserInputActivity.this,
ex);
+ }
+ } finally {
+ mEditInput.setEnabled(true);
+ mBtnSearch.setEnabled(true);
+ mStateHolder.setIsRunningTaskFindFriends(false);
+ stopProgressBar();
+ }
+ }
+
+ private void onSendFriendRequestTaskComplete(User
friendRequestRecipient, Exception ex) {
+ try {
+ // If sending the request was successful, then we need to
remove
+ // that user from the
+ // list adapter. We do a linear search to find the matching
row.
+ if (friendRequestRecipient != null) {
+ int position = 0;
+ for (User it : mStateHolder.getFoundFriends()) {
+ if (it.getId().equals(friendRequestRecipient.getId()))
{
+ mListAdapter.removeItem(position);
+ break;
+ }
+ position++;
+ }
+
+ Toast.makeText(AddFriendsByUserInputActivity.this,
+
getResources().getString(R.string.add_friends_request_sent_ok),
+ Toast.LENGTH_SHORT).show();
+
+ } else {
+ // If error, feed adapter empty user group.
+ mListAdapter.setGroup(new Group<User>());
+ mListAdapter.notifyDataSetChanged();
+
NotificationsUtil.ToastReasonForFailure(AddFriendsByUserInputActivity.this,
ex);
+ }
+ } finally {
+ mEditInput.setEnabled(true);
+ mBtnSearch.setEnabled(true);
+ mStateHolder.setIsRunningTaskSendFriendRequest(false);
+ stopProgressBar();
+ }
+ }
+
+ private static class FindFriendsTask extends AsyncTask<String, Void,
Group<User>> {
+
+ 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 Group<User> doInBackground(String... params) {
+ try {
+ Foursquared foursquared = (Foursquared)
mActivity.getApplication();
+ Foursquare foursquare = foursquared.getFoursquare();
+
+ Group<User> users = null;
+ switch (mActivity.mInputType) {
+ case INPUT_TYPE_PHONENUMBERS:
+ users = foursquare.addFriendsByPhone(params[0]);
+ break;
+ case INPUT_TYPE_TWITTERNAME:
+ users = foursquare.addFriendsByTwitter(params[0]);
+ break;
+ case INPUT_TYPE_ADDRESSBOOK:
+ AddressBookUtils addr =
AddressBookUtils.addressBookUtils();
+ String addresses =
addr.getAllContactsPhoneNumbers(mActivity);
+ if (addresses != null && addresses.length() > 0) {
+ users =
foursquare.addFriendsByPhone(addresses);
+ } else {
+ // No contacts in their contacts book, just
say no
+ // matches by supplying an empty group.
+ users = new Group<User>();
+ }
+ break;
+ default:
+ users = foursquare.addFriendsByName(params[0]);
+ break;
+ }
+ return users;
+ } catch (Exception e) {
+ if (DEBUG) Log.d(TAG, "FindFriendsTask: Exception doing
add friends by name", e);
+ mReason = e;
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Group<User> users) {
+ if (DEBUG) Log.d(TAG, "FindFriendsTask: onPostExecute()");
+ if (mActivity != null) {
+ mActivity.onFindFriendsTaskComplete(users, 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 StateHolder {
+ FindFriendsTask mTaskFindFriends;
+ SendFriendRequestTask mTaskSendFriendRequest;
+ Group<User> mFoundFriends;
+ boolean mIsRunningTaskFindFriends;
+ boolean mIsRunningTaskSendFriendRequest;
+ boolean mRanOnce;
+
+ public StateHolder() {
+ mFoundFriends = new Group<User>();
+ mIsRunningTaskFindFriends = false;
+ mIsRunningTaskSendFriendRequest = false;
+ mRanOnce = false;
+ }
+
+ public void setFoundFriends(Group<User> foundFriends) {
+ mFoundFriends = foundFriends;
+ mRanOnce = true;
+ }
+
+ public Group<User> getFoundFriends() {
+ return mFoundFriends;
+ }
+
+ 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
setActivityForTaskFindFriends(AddFriendsByUserInputActivity activity) {
+ if (mTaskFindFriends != null) {
+ mTaskFindFriends.setActivity(activity);
+ }
+ }
+
+ public void
setActivityForTaskFriendRequest(AddFriendsByUserInputActivity activity) {
+ if (mTaskSendFriendRequest != null) {
+ mTaskSendFriendRequest.setActivity(activity);
+ }
+ }
+
+ public void setIsRunningTaskFindFriends(boolean isRunning) {
+ mIsRunningTaskFindFriends = isRunning;
+ }
+
+ public void setIsRunningTaskSendFriendRequest(boolean isRunning) {
+ mIsRunningTaskSendFriendRequest = isRunning;
+ }
+
+ public boolean getIsRunningTaskFindFriends() {
+ return mIsRunningTaskFindFriends;
+ }
+
+ public boolean getIsRunningTaskSendFriendRequest() {
+ return mIsRunningTaskSendFriendRequest;
+ }
+
+ public boolean getRanOnce() {
+ return mRanOnce;
+ }
+ }
+
+ 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));
+ }
+ };
+}
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/FriendRequestsActivity.java Thu
Feb 18 19:20:08 2010
@@ -0,0 +1,404 @@
+/**
+ * Copyright 2009 Joe LaPenna
+ */
+
+package com.joelapenna.foursquared;
+
+import com.joelapenna.foursquare.Foursquare;
+import com.joelapenna.foursquare.types.Group;
+import com.joelapenna.foursquare.types.User;
+import com.joelapenna.foursquared.util.NotificationsUtil;
+import com.joelapenna.foursquared.widget.FriendRequestsAdapter;
+
+import android.app.ListActivity;
+import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
+
+/**
+ * Presents the user with a list of pending friend requests that they can
+ * approve or deny.
+ *
+ * @date February 12, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class FriendRequestsActivity extends ListActivity {
+ private static final String TAG = "FriendRequestsActivity";
+ private static final boolean DEBUG = FoursquaredSettings.DEBUG;
+
+ private static final int MENU_REFRESH = 0;
+
+ private StateHolder mStateHolder;
+ private ProgressDialog mDlgProgress;
+ private FriendRequestsAdapter mListAdapter;
+
+ 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()");
+ setContentView(R.layout.friend_requests_activity);
+ registerReceiver(mLoggedOutReceiver, new
IntentFilter(Foursquared.INTENT_ACTION_LOGGED_OUT));
+
+ mListAdapter = new FriendRequestsAdapter(this,
+ new FriendRequestsAdapter.ButtonRowClickHandler() {
+ @Override
+ public void onBtnClickDeny(User user) {
+ denyFriendRequest(user);
+ }
+
+ @Override
+ public void onBtnClickApprove(User user) {
+ approveFriendRequest(user);
+ }
+
+ @Override
+ public void onBtnClickInfo(User user) {
+ infoFriendRequest(user);
+ }
+ });
+ getListView().setAdapter(mListAdapter);
+ getListView().setItemsCanFocus(true);
+
+ Object retained = getLastNonConfigurationInstance();
+ if (retained != null && retained instanceof StateHolder) {
+ mStateHolder = (StateHolder) retained;
+ mStateHolder.setActivityForTaskFriendRequests(this);
+ mStateHolder.setActivityForTaskSendDecision(this);
+ } else {
+ mStateHolder = new StateHolder();
+
+ // If we are scanning the address book, we should kick it off
+ // immediately.
+
startProgressBar(getResources().getString(R.string.friend_requests_activity_label),
+
getResources().getString(R.string.add_friends_progress_bar_message_find));
+
mStateHolder.startTaskFriendRequests(FriendRequestsActivity.this);
+ }
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ if (mStateHolder.getIsRunningFriendRequest()) {
+
startProgressBar(getResources().getString(R.string.friend_requests_activity_label),
+
getResources().getString(R.string.add_friends_progress_bar_message_find));
+ } else if (mStateHolder.getIsRunningSendDecision()) {
+
startProgressBar(getResources().getString(R.string.friend_requests_activity_label),
+ getResources()
+ .getString(R.string.add_friends_progress_bar_message_send_request));
+ }
+
+ mListAdapter.setGroup(mStateHolder.getFoundFriendRequests());
+ mListAdapter.notifyDataSetChanged();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ stopProgressBar();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mLoggedOutReceiver);
+ }
+
+ @Override
+ public Object onRetainNonConfigurationInstance() {
+ mStateHolder.setActivityForTaskFriendRequests(null);
+ mStateHolder.setActivityForTaskSendDecision(null);
+ return mStateHolder;
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ menu.add(Menu.NONE, MENU_REFRESH, Menu.NONE,
R.string.refresh_label).setIcon(
+ R.drawable.ic_menu_refresh);
+
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_REFRESH:
+
startProgressBar(getResources().getString(R.string.friend_requests_activity_label),
+
getResources().getString(R.string.add_friends_progress_bar_message_find));
+
mStateHolder.startTaskFriendRequests(FriendRequestsActivity.this);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ 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;
+ }
+ }
+
+ private void infoFriendRequest(User user) {
+ Intent intent = new Intent(this, UserActivity.class);
+ intent.putExtra(UserActivity.EXTRA_USER, user.getId());
+ intent.setData(Uri.parse("http://foursquare.com/user/" +
user.getId()));
+ startActivity(intent);
+ }
+
+ private void approveFriendRequest(User user) {
+
startProgressBar(getResources().getString(R.string.friend_requests_activity_label),
+
getResources().getString(R.string.add_friends_progress_bar_message_find));
+ mStateHolder.startTaskSendDecision(FriendRequestsActivity.this,
true, user.getId());
+ }
+
+ private void denyFriendRequest(User user) {
+
startProgressBar(getResources().getString(R.string.friend_requests_activity_label),
+
getResources().getString(R.string.add_friends_progress_bar_message_find));
+ mStateHolder.startTaskSendDecision(FriendRequestsActivity.this,
false, user.getId());
+ }
+
+ private void onFriendRequestsTaskComplete(Group<User> users, Exception
ex) {
+ try {
+ // Populate the list control below now.
+ if (users != null) {
+ mStateHolder.setFoundFriendRequests(users);
+
+
mListAdapter.setGroup(mStateHolder.getFoundFriendRequests());
+ mListAdapter.notifyDataSetChanged();
+ } else {
+ // If error, feed list adapter empty user group.
+ mListAdapter.setGroup(new Group<User>());
+ mListAdapter.notifyDataSetChanged();
+
NotificationsUtil.ToastReasonForFailure(FriendRequestsActivity.this, ex);
+ }
+ } finally {
+ mStateHolder.setIsRunningFriendRequest(false);
+ stopProgressBar();
+ }
+ }
+
+ private void onFriendRequestDecisionTaskComplete(User user, Exception
ex) {
+ try {
+ // If sending the request was successful, then we need to
remove
+ // that user from the
+ // list adapter. We do a linear search to find the matching
row.
+ if (user != null) {
+ int position = 0;
+ for (User it : mStateHolder.getFoundFriendRequests()) {
+ if (it.getId().equals(user.getId())) {
+ mListAdapter.removeItem(position);
+ break;
+ }
+ position++;
+ }
+
+ Toast.makeText(this,
+
getResources().getString(R.string.friend_requests_decision_sent_ok),
+ Toast.LENGTH_SHORT).show();
+
+ } else {
+ NotificationsUtil.ToastReasonForFailure(this, ex);
+ }
+ } finally {
+ mStateHolder.setIsRunningSendDecision(false);
+ stopProgressBar();
+ }
+ }
+
+ private static class GetFriendRequestsTask extends AsyncTask<Void,
Void, Group<User>> {
+
+ private FriendRequestsActivity mActivity;
+ private Exception mReason;
+
+ public GetFriendRequestsTask(FriendRequestsActivity activity) {
+ mActivity = activity;
+ }
+
+ public void setActivity(FriendRequestsActivity 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 Group<User> doInBackground(Void... params) {
+ try {
+ Foursquared foursquared = (Foursquared)
mActivity.getApplication();
+ Foursquare foursquare = foursquared.getFoursquare();
+
+ return foursquare.friendRequests();
+ } catch (Exception e) {
+ if (DEBUG) Log.d(TAG, "FindFriendsTask: Exception doing
add friends by name", e);
+ mReason = e;
+ }
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(Group<User> users) {
+ if (DEBUG) Log.d(TAG, "FindFriendsTask: onPostExecute()");
+ if (mActivity != null) {
+ mActivity.onFriendRequestsTaskComplete(users, mReason);
+ }
+ }
+
+ @Override
+ protected void onCancelled() {
+ if (mActivity != null) {
+ mActivity.onFriendRequestsTaskComplete(null, new Exception(
+ "Friend search cancelled."));
+ }
+ }
+ }
+
+ private static class SendFriendRequestDecisionTask extends
AsyncTask<String, Void, User> {
+
+ private FriendRequestsActivity mActivity;
+ private Exception mReason;
+
+ public SendFriendRequestDecisionTask(FriendRequestsActivity
activity) {
+ mActivity = activity;
+ }
+
+ public void setActivity(FriendRequestsActivity 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 = null;
+ if (Boolean.parseBoolean(params[0]) == true) {
+ user = foursquare.friendApprove(params[1]);
+ } else {
+ user = foursquare.friendDeny(params[1]);
+ }
+ 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.onFriendRequestDecisionTaskComplete(user,
mReason);
+ }
+ }
+
+ @Override
+ protected void onCancelled() {
+ if (mActivity != null) {
+ mActivity.onFriendRequestDecisionTaskComplete(null, new
Exception(
+ "Friend request cancelled."));
+ }
+ }
+ }
+
+ private static class StateHolder {
+ GetFriendRequestsTask mTaskFriendRequests;
+ SendFriendRequestDecisionTask mTaskSendDecision;
+ Group<User> mFoundFriends;
+ boolean mIsRunningFriendRequests;
+ boolean mIsRunningSendDecision;
+
+ public StateHolder() {
+ mFoundFriends = new Group<User>();
+ mIsRunningFriendRequests = false;
+ mIsRunningSendDecision = false;
+ }
+
+ public void setFoundFriendRequests(Group<User> foundFriends) {
+ mFoundFriends = foundFriends;
+ }
+
+ public Group<User> getFoundFriendRequests() {
+ return mFoundFriends;
+ }
+
+ public void startTaskFriendRequests(FriendRequestsActivity
activity) {
+ mIsRunningFriendRequests = true;
+ mTaskFriendRequests = new GetFriendRequestsTask(activity);
+ mTaskFriendRequests.execute();
+ }
+
+ public void startTaskSendDecision(FriendRequestsActivity activity,
boolean approve,
+ String userId) {
+ mIsRunningSendDecision = true;
+ mTaskSendDecision = new
SendFriendRequestDecisionTask(activity);
+ mTaskSendDecision.execute(String.valueOf(approve), userId);
+ }
+
+ public void
setActivityForTaskFriendRequests(FriendRequestsActivity activity) {
+ if (mTaskFriendRequests != null) {
+ mTaskFriendRequests.setActivity(activity);
+ }
+ }
+
+ public void setActivityForTaskSendDecision(FriendRequestsActivity
activity) {
+ if (mTaskSendDecision != null) {
+ mTaskSendDecision.setActivity(activity);
+ }
+ }
+
+ public void setIsRunningFriendRequest(boolean isRunning) {
+ mIsRunningFriendRequests = isRunning;
+ }
+
+ public boolean getIsRunningFriendRequest() {
+ return mIsRunningFriendRequests;
+ }
+
+ public void setIsRunningSendDecision(boolean isRunning) {
+ mIsRunningSendDecision = isRunning;
+ }
+
+ public boolean getIsRunningSendDecision() {
+ return mIsRunningSendDecision;
+ }
+ }
+}
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/util/AddressBookUtils.java Thu Feb
18 19:20:08 2010
@@ -0,0 +1,27 @@
+
+package com.joelapenna.foursquared.util;
+
+import android.app.Activity;
+
+/**
+ * Acts as an interface to the contacts API which has changed between SDK
4 to
+ * 5.
+ *
+ * @date February 14, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public abstract class AddressBookUtils {
+ public abstract String getAllContactsPhoneNumbers(Activity activity);
+
+ public static AddressBookUtils addressBookUtils() {
+
+ // TODO: Reenable use of AddressBookUtils5 when project level
updated.
+ return new AddressBookUtils3and4();
+
+ /*
+ * int sdk = new Integer(Build.VERSION.SDK).intValue(); if (sdk <
5) {
+ * return new AddressBookUtils3and4(); } else { return new
+ * AddressBookUtils5(); }
+ */
+ }
+}
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/util/AddressBookUtils3and4.java
Thu Feb 18 19:20:08 2010
@@ -0,0 +1,41 @@
+
+package com.joelapenna.foursquared.util;
+
+import android.app.Activity;
+import android.database.Cursor;
+import android.provider.Contacts;
+import android.provider.Contacts.PhonesColumns;
+
+/**
+ * Implementation of address book functions for sdk levels 3 and 4.
+ *
+ * @date February 14, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class AddressBookUtils3and4 extends AddressBookUtils {
+ public AddressBookUtils3and4() {
+ }
+
+ @Override
+ public String getAllContactsPhoneNumbers(Activity activity) {
+ StringBuilder sb = new StringBuilder(1024);
+
+ String[] PROJECTION = new String[] {
+ PhonesColumns.NUMBER
+ };
+
+ Cursor c = activity.managedQuery(Contacts.Phones.CONTENT_URI,
PROJECTION, null, null,
+ Contacts.Phones.DEFAULT_SORT_ORDER);
+
+ if (c.moveToFirst()) {
+ sb.append(c.getString(0));
+ while (c.moveToNext()) {
+ sb.append(",");
+ sb.append(c.getString(0));
+ }
+ }
+ c.close();
+
+ return sb.toString();
+ }
+}
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/util/AddressBookUtils5.java Thu
Feb 18 19:20:08 2010
@@ -0,0 +1,31 @@
+
+package com.joelapenna.foursquared.util;
+
+import android.app.Activity;
+
+/**
+ * Implementation of address book functions for sdk level 5 and above.
+ *
+ * @date February 14, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class AddressBookUtils5 extends AddressBookUtils {
+ public AddressBookUtils5() {
+ }
+
+ @Override
+ public String getAllContactsPhoneNumbers(Activity activity) {
+
+ throw new IllegalStateException(
+ "AddressBookUtils5.getAllContactsPhoneNumbers() not
implemented.");
+
+ // TODO: Need to update project to API 5 to use new contacts api.
+ /*
+ * StringBuilder sb = new StringBuilder(1024); String[] PROJECTION
= new
+ * String[] { Contacts._ID, Contacts.DISPLAY_NAME, Phone.NUMBER };
+ * Cursor c = activity.managedQuery(Phone.CONTENT_URI, PROJECTION,
null,
+ * null, null); if (c.moveToFirst()) { while (c.moveToNext()) { } }
+ * return sb.toString();
+ */
+ }
+}
=======================================
--- /dev/null
+++ /main/src/com/joelapenna/foursquared/widget/FriendRequestsAdapter.java
Thu Feb 18 19:20:08 2010
@@ -0,0 +1,125 @@
+/**
+ * Copyright 2008 Joe LaPenna
+ */
+
+package com.joelapenna.foursquared.widget;
+
+import com.joelapenna.foursquare.types.User;
+import com.joelapenna.foursquared.R;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * @date February 15, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class FriendRequestsAdapter extends BaseGroupAdapter<User> {
+
+ private LayoutInflater mInflater;
+ private int mLayoutToInflate;
+ private ButtonRowClickHandler mClickListener;
+
+ public FriendRequestsAdapter(Context context, ButtonRowClickHandler
clickListener) {
+ super(context);
+ mInflater = LayoutInflater.from(context);
+ mLayoutToInflate = R.layout.friend_request_list_item;
+ mClickListener = clickListener;
+ }
+
+ public FriendRequestsAdapter(Context context, int layoutResource) {
+ super(context);
+ mInflater = LayoutInflater.from(context);
+ mLayoutToInflate = layoutResource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // A ViewHolder keeps references to children views to avoid
unnecessary
+ // calls to findViewById() on each row.
+ ViewHolder holder;
+
+ // When convertView is not null, we can reuse it directly, there
is no
+ // need to re-inflate it. We only inflate a new View when the
+ // convertView supplied by ListView is null.
+ if (convertView == null) {
+ convertView = mInflater.inflate(mLayoutToInflate, null);
+
+ // Creates a ViewHolder and store references to the two
children
+ // views we want to bind data to.
+ holder = new ViewHolder();
+ holder.main = (LinearLayout)
convertView.findViewById(R.id.addFriendListItemBackground);
+ holder.name = (TextView)
convertView.findViewById(R.id.addFriendListItemName);
+ holder.info = (Button)
convertView.findViewById(R.id.friendRequestInfoButton);
+ holder.approve = (Button)
convertView.findViewById(R.id.friendRequestApproveButton);
+ holder.deny = (Button)
convertView.findViewById(R.id.friendRequestDenyButton);
+
+ convertView.setTag(holder);
+
+ holder.info.setOnClickListener(mOnClickListenerInfo);
+ holder.approve.setOnClickListener(mOnClickListenerApprove);
+ holder.deny.setOnClickListener(mOnClickListenerDeny);
+ } else {
+ // Get the ViewHolder back to get fast access to the TextView
+ // and the ImageView.
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ User user = (User) getItem(position);
+ holder.name.setText(user.getFirstname() + " "
+ + (user.getLastname() != null ? user.getLastname() : ""));
+ holder.info.setTag(new Integer(position));
+ holder.approve.setTag(new Integer(position));
+ holder.deny.setTag(new Integer(position));
+
+ return convertView;
+ }
+
+ private OnClickListener mOnClickListenerInfo = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Integer position = (Integer) v.getTag();
+ mClickListener.onBtnClickInfo((User) getItem(position));
+ }
+ };
+
+ private OnClickListener mOnClickListenerApprove = new
OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Integer position = (Integer) v.getTag();
+ mClickListener.onBtnClickApprove((User) getItem(position));
+ }
+ };
+
+ private OnClickListener mOnClickListenerDeny = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mClickListener != null) {
+ Integer position = (Integer) v.getTag();
+ mClickListener.onBtnClickDeny((User) getItem(position));
+ }
+ }
+ };
+
+ static class ViewHolder {
+ LinearLayout main;
+ TextView name;
+ Button info;
+ Button approve;
+ Button deny;
+ }
+
+ public interface ButtonRowClickHandler {
+ public void onBtnClickInfo(User user);
+
+ public void onBtnClickApprove(User user);
+
+ public void onBtnClickDeny(User user);
+ }
+}
=======================================
--- /dev/null
+++
/main/src/com/joelapenna/foursquared/widget/FriendSearchAddFriendAdapter.java
Thu Feb 18 19:20:08 2010
@@ -0,0 +1,111 @@
+/**
+ * Copyright 2008 Joe LaPenna
+ */
+
+package com.joelapenna.foursquared.widget;
+
+import com.joelapenna.foursquare.types.User;
+import com.joelapenna.foursquared.R;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * @date February 14, 2010
+ * @author Mark Wyszomierski (mar...@gmail.com), foursquare.
+ */
+public class FriendSearchAddFriendAdapter extends BaseGroupAdapter<User> {
+
+ private LayoutInflater mInflater;
+ private int mLayoutToInflate;
+ private ButtonRowClickHandler mClickListener;
+
+ public FriendSearchAddFriendAdapter(Context context,
ButtonRowClickHandler clickListener) {
+ super(context);
+ mInflater = LayoutInflater.from(context);
+ mLayoutToInflate = R.layout.add_friends_list_item;
+ mClickListener = clickListener;
+ }
+
+ public FriendSearchAddFriendAdapter(Context context, int
layoutResource) {
+ super(context);
+ mInflater = LayoutInflater.from(context);
+ mLayoutToInflate = layoutResource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // A ViewHolder keeps references to children views to avoid
unnecessary
+ // calls to findViewById() on each row.
+ ViewHolder holder;
+
+ // When convertView is not null, we can reuse it directly, there
is no
+ // need to re-inflate it. We only inflate a new View when the
+ // convertView supplied by ListView is null.
+ if (convertView == null) {
+ convertView = mInflater.inflate(mLayoutToInflate, null);
+
+ // Creates a ViewHolder and store references to the two
children
+ // views we want to bind data to.
+ holder = new ViewHolder();
+ holder.main = (LinearLayout)
convertView.findViewById(R.id.addFriendListItemBackground);
+ holder.name = (TextView)
convertView.findViewById(R.id.addFriendListItemName);
+ holder.add = (Button)
convertView.findViewById(R.id.addFriendListItemAddButton);
+ holder.info = (Button)
convertView.findViewById(R.id.addFriendListItemInfoButton);
+
+ convertView.setTag(holder);
+
+ holder.add.setOnClickListener(mOnClickListenerAdd);
+ holder.info.setOnClickListener(mOnClickListenerInfo);
+ } else {
+ // Get the ViewHolder back to get fast access to the TextView
+ // and the ImageView.
+ holder = (ViewHolder) convertView.getTag();
+ }
+
+ User user = (User) getItem(position);
+ holder.name.setText(user.getFirstname() + " "
+ + (user.getLastname() != null ? user.getLastname() : ""));
+ holder.add.setTag(new Integer(position));
+ holder.info.setTag(new Integer(position));
+
+ return convertView;
+ }
+
+ private OnClickListener mOnClickListenerAdd = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Integer position = (Integer) v.getTag();
+ mClickListener.onBtnClickAdd((User) getItem(position));
+ }
+ };
+
+ private OnClickListener mOnClickListenerInfo = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mClickListener != null) {
+ Integer position = (Integer) v.getTag();
+ mClickListener.onBtnClickInfo((User) getItem(position));
+ }
+ }
+ };
+
+ static class ViewHolder {
+ LinearLayout main;
+ TextView name;
+ Button add;
+ Button info;
+ }
+
+ public interface ButtonRowClickHandler {
+ public void onBtnClickAdd(User user);
+
+ public void onBtnClickInfo(User user);
+ }
+}
=======================================
--- /main/AndroidManifest.xml Thu Feb 4 10:07:59 2010
+++ /main/AndroidManifest.xml Thu Feb 18 19:20:08 2010
@@ -14,6 +14,8 @@
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission
+ android:name="android.permission.READ_CONTACTS" />
<uses-sdk
android:minSdkVersion="3"
android:targetSdkVersion="4" />
@@ -264,6 +266,21 @@
<activity
android:name=".VenueTipsActivity">
</activity>
+
+ <activity
+ android:name=".AddFriendsActivity"
+ android:label="@string/add_friends_activity_label">
+ </activity>
+
+ <activity
+ android:name=".AddFriendsByUserInputActivity"
+ android:label="@string/add_friends_activity_label">
+ </activity>
+
+ <activity
+ android:name=".FriendRequestsActivity"
+ android:label="@string/friend_requests_activity_label">
+ </activity>

<receiver
android:name=".appwidget.FriendsAppWidgetProvider"
=======================================
--- /main/res/values/strings.xml Thu Feb 4 10:22:09 2010
+++ /main/res/values/strings.xml Thu Feb 18 19:20:08 2010
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="add_a_tip">Add a Tip</string>
+ <string name="add_friends_activity_label">Foursquare Add Friends</string>
<string name="add_venue_activity_label">Add a New Venue</string>
<string name="add_venue_error_toast_venue_null">Unable to add
venue!</string>
<string name="add_venue_label">Add Venue</string>
@@ -116,4 +117,24 @@
<string name="venues_search_label">Venue Search</string>
<string name="zip_code">Zip Code</string>
<string name="search_description">Venues and friends</string>
+ <string name="add_friends_instructions">Foursquare is more fun when you
connect with your friends. Your friends can see the email address and phone
number you gave us when you signed up, so choose wisely.</string>
+ <string name="add_friends_by_name_btn_label">Find by name</string>
+ <string name="add_friends_by_phonenumber_btn_label">Find using phone
number</string>
+ <string name="add_friends_by_twitter_btn_label">Find Twitter
friends</string>
+ <string name="add_friends_by_name_instructions">Find a friend using
their name</string>
+ <string name="add_friends_by_name_hint">Enter a name (first and/or
last)</string>
+ <string name="add_friends_by_phonenumber_instructions">Find a friend
using a phone number</string>
+ <string name="add_friends_by_phonenumber_hint">Enter a phone
number</string>
+ <string name="add_friends_by_twitter_instructions">Find a friend by
Twitter handle</string>
+ <string name="add_friends_by_twitter_hint">Enter your Twitter
name</string>
+ <string name="add_friends_by_addressbook_instructions">Find friends from
address book</string>
+ <string name="add_friends_by_addressbook_additional_instructions">We\'re
scanning your list of contacts in hopes of finding you some foursquare
friends. This may take a few seconds so thanks for your patience!</string>
+ <string name="add_friends_progress_bar_message_find">Searching for
friends...</string>
+ <string name="add_friends_progress_bar_message_send_request">Sending
friend invitation...</string>
+ <string name="add_friends_by_address_book">Scan my address book</string>
+ <string name="add_friends_by_facebook">Find Facebook friends</string>
+ <string name="add_friends_request_sent_ok">Friend request sent
ok!</string>
+ <string name="add_friends_no_matches">No matches found.</string>
+ <string name="friend_requests_activity_label">Foursquare Friend
Requests</string>
+ <string name="friend_requests_decision_sent_ok">Decision sent
ok!</string>
</resources>
=======================================
--- /main/src/com/joelapenna/foursquare/Foursquare.java Mon Feb 1 23:51:16
2010
+++ /main/src/com/joelapenna/foursquare/Foursquare.java Thu Feb 18 19:20:08
2010
@@ -4,6 +4,13 @@

package com.joelapenna.foursquare;

+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import android.net.Uri;
+import android.text.TextUtils;
+
import com.joelapenna.foursquare.error.FoursquareCredentialsException;
import com.joelapenna.foursquare.error.FoursquareError;
import com.joelapenna.foursquare.error.FoursquareException;
@@ -15,13 +22,6 @@
import com.joelapenna.foursquare.types.User;
import com.joelapenna.foursquare.types.Venue;

-import android.net.Uri;
-import android.text.TextUtils;
-
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
/**
* @author Joe LaPenna (j...@joelapenna.com)
*/
@@ -186,6 +186,24 @@
return mFoursquareV1.venues(location.geolat, location.geolong,
location.geohacc,
location.geovacc, location.geoalt, query, limit);
}
+
+ @V1
+ public Group<User> addFriendsByName(String text)
+ throws FoursquareException, FoursquareError, IOException {
+ return mFoursquareV1.addFriendsByName(text);
+ }
+
+ @V1
+ public Group<User> addFriendsByPhone(String text)
+ throws FoursquareException, FoursquareError, IOException {
+ return mFoursquareV1.addFriendsByPhone(text);
+ }
+
+ @V1
+ public Group<User> addFriendsByTwitter(String text)
+ throws FoursquareException, FoursquareError, IOException {
+ return mFoursquareV1.addFriendsByTwitter(text);
+ }

public static final FoursquareHttpApiV1 createHttpApi(String domain,
String clientVersion,
boolean useOAuth) {
=======================================
--- /main/src/com/joelapenna/foursquare/FoursquareHttpApiV1.java Tue Jan 26
09:54:42 2010
+++ /main/src/com/joelapenna/foursquare/FoursquareHttpApiV1.java Thu Feb 18
19:20:08 2010
@@ -4,6 +4,17 @@

package com.joelapenna.foursquare;

+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
import com.joelapenna.foursquare.error.FoursquareCredentialsException;
import com.joelapenna.foursquare.error.FoursquareError;
import com.joelapenna.foursquare.error.FoursquareException;
@@ -28,17 +39,6 @@
import com.joelapenna.foursquare.types.User;
import com.joelapenna.foursquare.types.Venue;

-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
/**
* @author Joe LaPenna (j...@joelapenna.com)
*/
@@ -63,6 +63,9 @@
private static final String URL_API_FRIEND_DENY = "/friend/deny";
private static final String URL_API_FRIEND_SENDREQUEST
= "/friend/sendrequest";
private static final String URL_API_FRIENDS = "/friends";
+ private static final String URL_API_ADD_FRIENDS_BY_NAME
= "/findfriends/byname";
+ private static final String URL_API_ADD_FRIENDS_BY_PHONE
= "/findfriends/byphone";
+ private static final String URL_API_ADD_FRIENDS_BY_TWITTER
= "/findfriends/bytwitter";

private final DefaultHttpClient mHttpClient =
AbstractHttpApi.createHttpClient();
private HttpApi mHttpApi;
@@ -348,7 +351,7 @@
new BasicNameValuePair("uid", uid));
return (User) mHttpApi.doHttpRequest(httpPost, new UserParser());
}
-
+
/*
* /friend/sendrequest?uid=9937
*/
@@ -358,6 +361,39 @@
new BasicNameValuePair("uid", uid));
return (User) mHttpApi.doHttpRequest(httpPost, new UserParser());
}
+
+ /**
+ * /findfriends/byname?q=john doe, mary smith
+ */
+ @SuppressWarnings("unchecked")
+ public Group<User> addFriendsByName(String text) throws
FoursquareException, FoursquareCredentialsException,
+ FoursquareError, IOException {
+ HttpGet httpGet =
mHttpApi.createHttpGet(fullUrl(URL_API_ADD_FRIENDS_BY_NAME), //
+ new BasicNameValuePair("q", text));
+ return (Group<User>) mHttpApi.doHttpRequest(httpGet, new
GroupParser(new UserParser()));
+ }
+
+ /**
+ * /findfriends/byphone?q=555-5555,555-5556
+ */
+ @SuppressWarnings("unchecked")
+ public Group<User> addFriendsByPhone(String text) throws
FoursquareException, FoursquareCredentialsException,
+ FoursquareError, IOException {
+ HttpPost httpPost =
mHttpApi.createHttpPost(fullUrl(URL_API_ADD_FRIENDS_BY_PHONE), //
+ new BasicNameValuePair("q", text));
+ return (Group<User>) mHttpApi.doHttpRequest(httpPost, new
GroupParser(new UserParser()));
+ }
+
+ /**
+ * /findfriends/bytwitter?q=yourtwittername
+ */
+ @SuppressWarnings("unchecked")
+ public Group<User> addFriendsByTwitter(String text) throws
FoursquareException, FoursquareCredentialsException,
+ FoursquareError, IOException {
+ HttpGet httpGet =
mHttpApi.createHttpGet(fullUrl(URL_API_ADD_FRIENDS_BY_TWITTER), //
+ new BasicNameValuePair("q", text));
+ return (Group<User>) mHttpApi.doHttpRequest(httpGet, new
GroupParser(new UserParser()));
+ }

private String fullUrl(String url) {
return mApiBaseUrl + url;
=======================================
--- /main/src/com/joelapenna/foursquared/PreferenceActivity.java Tue Feb 2
00:10:24 2010
+++ /main/src/com/joelapenna/foursquared/PreferenceActivity.java Thu Feb 18
19:20:08 2010
@@ -105,13 +105,10 @@
FeedbackUtils.SendFeedBack(this, (Foursquared)
getApplication());

} else if (Preferences.PREFERENCE_FRIEND_ADD.equals(key)) {
- startActivity(new Intent( //
- Intent.ACTION_VIEW,
Uri.parse(Foursquare.FOURSQUARE_MOBILE_ADDFRIENDS)));
+ startActivity(new Intent(this, AddFriendsActivity.class));

} else if (Preferences.PREFERENCE_FRIEND_REQUESTS.equals(key)) {
- startActivity(new Intent( //
- Intent.ACTION_VIEW,
Uri.parse(Foursquare.FOURSQUARE_MOBILE_FRIENDS)));
-
+ startActivity(new Intent(this, FriendRequestsActivity.class));
}
return true;
}
=======================================
--- /main/src/com/joelapenna/foursquared/widget/BaseGroupAdapter.java Thu
Oct 8 00:06:43 2009
+++ /main/src/com/joelapenna/foursquared/widget/BaseGroupAdapter.java Thu
Feb 18 19:20:08 2010
@@ -49,4 +49,9 @@
group = g;
notifyDataSetInvalidated();
}
-}
+
+ public void removeItem(int position) throws IndexOutOfBoundsException {
+ group.remove(position);
+ notifyDataSetInvalidated();
+ }
+}

Alexey Volovoy

unread,
Feb 18, 2010, 8:01:46 PM2/18/10
to markww-fo...@googlecode.com, foursqu...@googlegroups.com
Also Preferences :
Description strings are wrong for all Friends preferences ( not
updated with new once )
Friend Requests - i would argue that there is no need to display the
activity with You Have no new friends request - toast will do. If i
would have friends requests - than let's display the activity.

------------------------------------------------------------
Alex Volovoy

Android development
twitter/avolovoy
bytesharp.com
gvoice:+1 816 VOLOVOY

Mark

unread,
Feb 18, 2010, 8:23:12 PM2/18/10
to foursquared-dev
>> Also Preferences : Description strings are wrong for all Friends preferences
Alexy, can you explain the Friends prefs description strings issue
further, I'm not sure what part of the change set that is?

>> Friend Requests - i would argue that there is no need to display the activity

I like that idea, only thing is that we'd have to move the async task
into the prefs activity, and pop up a spinner there when the user
clicks the friends request item - so when they click 'friend
requests', we'll lock the screen for a moment before checking, might
it be awkward for the user?

naveen

unread,
Feb 23, 2010, 12:00:18 PM2/23/10
to foursquared-dev

On Feb 18, 7:25 pm, markww-foursqua...@googlecode.com wrote:
> Revision: ab3e9aca49
> Author: mar...@gmail.com
> Date: Thu Feb 18 19:20:08 2010
> Log: Adding support for adding friends, responding to friend requests.http://code.google.com/r/markww-foursquared/source/detail?r=ab3e9aca49

hi hi guys (joe, really :)

curious if you got a chance to test this more over the weekend. it's
looking good so far from my side

eager to merge and get these smaller changes out into market soon. i
don't think we've done a push in a while

naveen

Alex Volovoy

unread,
Feb 23, 2010, 12:36:43 PM2/23/10
to foursquared-dev
I'm testing latest build - so far seems to be error free. We can
polish UI little bit more later.

Joe LaPenna

unread,
Feb 23, 2010, 12:47:14 PM2/23/10
to naveen, foursquared-dev
Hey Naveen,

This weekend I was distracted with another project that at some point
I'd like to talk to you about: http://foursquare-proxy.googlecode.com/

But, that aside, sorry for not getting to this (monster) review; I was
really excited about working on said other project. I'll get working
on the review for Mark's code and hopefully we can push out another
beta this week, then release next week?

I'll probably have Mark or Alexey run the beta test and let you push
the apk to the market so you guys can see what all the admin stuff is
like.

PS.
Mark, I've started on your code review and wanted to finish it this
morning but I'm about to run out of battery on the shuttle.

On Feb 23, 2010 9:02 AM, "naveen" <nave...@gmail.com> wrote:


On Feb 18, 7:25 pm, markww-foursqua...@googlecode.com wrote:
> Revision: ab3e9aca49
> Author: mar...@gmail.com

> Date: Thu Feb 18 19:20:08 2010

> Log: Adding support for adding friends, responding to friend requ...

hi hi guys (joe, really :)

curious if you got a chance to test this more over the weekend. it's
looking good so far from my side

eager to merge and get these smaller changes out into market soon. i
don't think we've done a push in a while

naveen

--

You received this message because you are subscribed to the Google
Groups "foursquared-dev" group.
T...

naveen

unread,
Feb 23, 2010, 1:43:55 PM2/23/10
to Alex Volovoy, foursquared-dev

On Feb 23, 2010, at 12:36 PM, Alex Volovoy wrote:

> I'm testing latest build - so far seems to be error free. We can
> polish UI little bit more later.

yup. hoping to share mari's stuff sometime in the next couple of days so that we can put that in and iterate

Reply all
Reply to author
Forward
0 new messages