/** * Copyright 2009 Joe LaPenna */ package com.joelapenna.foursquared; import com.joelapenna.foursquare.types.Tip; import com.joelapenna.foursquare.types.Venue; import com.joelapenna.foursquare.util.VenueUtils; import com.joelapenna.foursquared.location.LocationUtils; import com.joelapenna.foursquared.preferences.Preferences; import com.joelapenna.foursquared.util.MenuUtils; import com.joelapenna.foursquared.util.NotificationsUtil; import com.joelapenna.foursquared.util.TabsUtil; import com.joelapenna.foursquared.util.UserUtils; import com.joelapenna.foursquared.widget.VenueView; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.TabActivity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.Spinner; import android.widget.TabHost; import android.widget.Toast; import java.util.HashSet; import java.util.Observable; /** * @author Joe LaPenna (joe@joelapenna.com) * @author Mark Wyszomierski (markww@gmail.com) * -Replaced shout activity with CheckinGatherInfoActivity (3/10/2010). */ public class VenueActivity extends TabActivity { private static final String TAG = "VenueActivity"; private static final boolean DEBUG = FoursquaredSettings.DEBUG; private static final int DIALOG_TIPADD = 1; private static final int MENU_CHECKIN = 1; private static final int MENU_TIPADD = 2; private static final int MENU_CALL = 3; private static final int MENU_EDIT_VENUE = 4; private static final int MENU_MYINFO = 5; private static final int RESULT_CODE_ACTIVITY_CHECKIN_EXECUTE = 1; final VenueObservable venueObservable = new VenueObservable(); private final StateHolder mStateHolder = new StateHolder(); private final HashSet<Object> mProgressBarTasks = new HashSet<Object>(); private VenueView mVenueView; private boolean mCheckedInSuccessfully = false; 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); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.venue_activity); registerReceiver(mLoggedOutReceiver, new IntentFilter(Foursquared.INTENT_ACTION_LOGGED_OUT)); initTabHost(); StateHolder holder = (StateHolder) getLastNonConfigurationInstance(); mVenueView = (VenueView) findViewById(R.id.venue); mVenueView.setCheckinButtonOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // This is a quick checkin, so we can just execute the checkin directly. // There's a setting in preferences which can block this behavior though. SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences( VenueActivity.this); if (settings.getBoolean(Preferences.PREFERENCE_IMMEDIATE_CHECKIN, false)) { startCheckinQuick(); } else { startCheckin(); } } }); mVenueView.setSpecialOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showWebViewForSpecial(); } }); if (holder != null && VenueUtils.isValid(holder.venue)) { if (DEBUG) Log.d(TAG, "Restoring Venue: " + holder.venue); setVenue(holder.venue); } else { new VenueTask().execute(getIntent().getExtras().getString(Foursquared.EXTRA_VENUE_ID)); } } @Override public void onDestroy() { super.onDestroy(); unregisterReceiver(mLoggedOutReceiver); } @Override public void onResume() { super.onResume(); mVenueView.updateCheckinButtonText(); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(Menu.NONE, MENU_CHECKIN, 1, R.string.checkin_action_label) // .setIcon(R.drawable.ic_menu_checkin); menu.add(Menu.NONE, MENU_TIPADD, 2, R.string.add_a_tip).setIcon( android.R.drawable.ic_menu_set_as); menu.add(Menu.NONE, MENU_CALL, 3, R.string.call).setIcon(android.R.drawable.ic_menu_call); menu.add(Menu.NONE, MENU_EDIT_VENUE, 4, R.string.edit_venue).setIcon( android.R.drawable.ic_menu_edit); int sdk = new Integer(Build.VERSION.SDK).intValue(); if (sdk < 4) { int menuIcon = UserUtils.getDrawableForMeMenuItemByGender( ((Foursquared) getApplication()).getUserGender()); menu.add(Menu.NONE, MENU_MYINFO, Menu.NONE, R.string.myinfo_label) // .setIcon(menuIcon); } MenuUtils.addPreferencesToMenu(this, menu); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { boolean checkinEnabled = (mStateHolder.venueId != null) && !mCheckedInSuccessfully; menu.findItem(MENU_CHECKIN).setEnabled(checkinEnabled); boolean callEnabled = mStateHolder.venue != null && !TextUtils.isEmpty(mStateHolder.venue.getPhone()); menu.findItem(MENU_CALL).setEnabled(callEnabled); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case MENU_CHECKIN: startCheckin(); return true; case MENU_TIPADD: showDialog(DIALOG_TIPADD); return true; case MENU_CALL: try { Intent dial = new Intent(); dial.setAction(Intent.ACTION_DIAL); dial.setData(Uri.parse("tel:" + mStateHolder.venue.getPhone())); startActivity(dial); } catch (Exception ex) { Log.e(TAG, "Error starting phone dialer intent.", ex); Toast.makeText(this, "Sorry, we couldn't find any app to place a phone call!", Toast.LENGTH_SHORT).show(); } return true; case MENU_EDIT_VENUE: Intent intentEditVenue = new Intent(this, EditVenueOptionsActivity.class); intentEditVenue.putExtra( EditVenueOptionsActivity.EXTRA_VENUE_PARCELABLE, mStateHolder.venue); startActivity(intentEditVenue); return true; case MENU_MYINFO: Intent intentUser = new Intent(VenueActivity.this, UserDetailsActivity.class); intentUser.putExtra(UserDetailsActivity.EXTRA_USER_ID, ((Foursquared) getApplication()).getUserId()); startActivity(intentUser); return true; } return super.onOptionsItemSelected(item); } @Override public Dialog onCreateDialog(int id) { LayoutInflater inflater = (LayoutInflater) getSystemService(Activity.LAYOUT_INFLATER_SERVICE); View layout; switch (id) { case DIALOG_TIPADD: layout = inflater.inflate(R.layout.tip_add_dialog, (ViewGroup) findViewById(R.id.layout_root)); final EditText editText = (EditText) layout.findViewById(R.id.editText); final Spinner spinner = (Spinner) layout.findViewById(R.id.spinner); return new AlertDialog.Builder(this) // .setView(layout) // .setIcon(android.R.drawable.ic_dialog_alert) // icon .setTitle("Add a Tip") // title .setPositiveButton("Add", new Dialog.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String tip = editText.getText().toString(); String type = ((String) spinner.getSelectedItem()).toLowerCase(); editText.setText(""); spinner.setSelection(0); new TipAddTask().execute(tip, type); } }) // .setNegativeButton("Cancel", new Dialog.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { editText.setText(""); spinner.setSelection(0); dismissDialog(DIALOG_TIPADD); } }).create(); } return null; } @Override public void onPrepareDialog(int id, Dialog dialog) { // If the tip add was a success we must have set mStateHolder.tip. If // that is the case, then // we clear the dialog because clearly they're looking to add a new tip // and not post the // same one again. if (id == DIALOG_TIPADD && mStateHolder.tip != null) { ((EditText) dialog.findViewById(R.id.editText)).setText(""); mStateHolder.tip = null; } } @Override public Object onRetainNonConfigurationInstance() { return mStateHolder; } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case RESULT_CODE_ACTIVITY_CHECKIN_EXECUTE: if (resultCode == Activity.RESULT_OK) { mCheckedInSuccessfully = true; mVenueView.setCheckinButtonEnabled(false); } break; } } public void startProgressBar(String taskId) { boolean added = mProgressBarTasks.add(taskId); if (!added) { if (DEBUG) Log.d(TAG, "Received start for already tracked task. Ignoring"); } setProgressBarIndeterminateVisibility(true); } public void stopProgressBar(String taskId) { boolean removed = mProgressBarTasks.remove(taskId); if (!removed) { if (DEBUG) Log.d(TAG, "Received stop for untracked task. Ignoring"); } else if (mProgressBarTasks.isEmpty()) { setProgressBarIndeterminateVisibility(false); } } private void initTabHost() { final TabHost tabHost = this.getTabHost(); String tag; Intent intent; tag = (String) this.getText(R.string.venue_checkins_tab); intent = new Intent(this, VenueCheckinsActivity.class); TabsUtil.addNativeLookingTab(this, tabHost, "t1", tag, R.drawable.friends_tab, intent); tag = (String) this.getText(R.string.map_label); intent = new Intent(this, VenueMapActivity.class); TabsUtil.addNativeLookingTab(this, tabHost, "t2", tag, R.drawable.map_tab, intent); tag = (String) this.getText(R.string.venue_info_tab); intent = new Intent(this, VenueTipsActivity.class); TabsUtil.addNativeLookingTab(this, tabHost, "t3", tag, R.drawable.tips_tab, intent); } private void onVenueSet() { Venue venue = mStateHolder.venue; if (DEBUG) Log.d(TAG, "onVenueSet:" + venue.getName()); setTitle(venue.getName() + " - Foursquare"); mVenueView.setVenue(venue); mVenueView.setCheckinButtonEnabled(mStateHolder.venueId != null); } private void setVenue(Venue venue) { mStateHolder.venue = venue; mStateHolder.venueId = venue.getId(); venueObservable.notifyObservers(venue); onVenueSet(); } private void startCheckin() { Intent intent = new Intent(this, CheckinOrShoutGatherInfoActivity.class); intent.putExtra(CheckinOrShoutGatherInfoActivity.INTENT_EXTRA_IS_CHECKIN, true); intent.putExtra(CheckinOrShoutGatherInfoActivity.INTENT_EXTRA_VENUE_ID, mStateHolder.venue.getId()); intent.putExtra(CheckinOrShoutGatherInfoActivity.INTENT_EXTRA_VENUE_NAME, mStateHolder.venue.getName()); startActivityForResult(intent, RESULT_CODE_ACTIVITY_CHECKIN_EXECUTE); } private void startCheckinQuick() { SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); boolean tellFriends = settings.getBoolean(Preferences.PREFERENCE_SHARE_CHECKIN, true); boolean tellTwitter = settings.getBoolean(Preferences.PREFERENCE_TWITTER_CHECKIN, false); boolean tellFacebook = settings.getBoolean(Preferences.PREFERENCE_FACEBOOK_CHECKIN, false); Intent intent = new Intent(VenueActivity.this, CheckinExecuteActivity.class); intent.putExtra(CheckinExecuteActivity.INTENT_EXTRA_VENUE_ID, mStateHolder.venue.getId()); intent.putExtra(CheckinExecuteActivity.INTENT_EXTRA_SHOUT, ""); intent.putExtra(CheckinExecuteActivity.INTENT_EXTRA_TELL_FRIENDS, tellFriends); intent.putExtra(CheckinExecuteActivity.INTENT_EXTRA_TELL_TWITTER, tellTwitter); intent.putExtra(CheckinExecuteActivity.INTENT_EXTRA_TELL_FACEBOOK, tellFacebook); startActivityForResult(intent, RESULT_CODE_ACTIVITY_CHECKIN_EXECUTE); } private void showWebViewForSpecial() { Intent intent = new Intent(this, SpecialWebViewActivity.class); intent.putExtra(SpecialWebViewActivity.EXTRA_CREDENTIALS_USERNAME, PreferenceManager.getDefaultSharedPreferences(this).getString(Preferences.PREFERENCE_LOGIN, "")); intent.putExtra(SpecialWebViewActivity.EXTRA_CREDENTIALS_PASSWORD, PreferenceManager.getDefaultSharedPreferences(this).getString(Preferences.PREFERENCE_PASSWORD, "")); intent.putExtra(SpecialWebViewActivity.EXTRA_SPECIAL_ID, mStateHolder.venue.getSpecials().get(0).getId()); startActivity(intent); } class VenueObservable extends Observable { @Override public void notifyObservers(Object data) { setChanged(); super.notifyObservers(data); } public Venue getVenue() { return mStateHolder.venue; } } private class VenueTask extends AsyncTask<String, Void, Venue> { private static final String PROGRESS_BAR_TASK_ID = TAG + "VenueTask"; private Exception mReason; @Override protected void onPreExecute() { startProgressBar(PROGRESS_BAR_TASK_ID); } @Override protected Venue doInBackground(String... params) { try { return ((Foursquared) getApplication()).getFoursquare().venue( params[0], LocationUtils.createFoursquareLocation(((Foursquared) getApplication()) .getLastKnownLocation())); } catch (Exception e) { mReason = e; } return null; } @Override protected void onPostExecute(Venue venue) { try { if (VenueUtils.isValid(venue)) { setVenue(venue); } else { NotificationsUtil.ToastReasonForFailure(VenueActivity.this, mReason); finish(); } } finally { stopProgressBar(PROGRESS_BAR_TASK_ID); } } @Override protected void onCancelled() { stopProgressBar(PROGRESS_BAR_TASK_ID); } } private class TipAddTask extends AsyncTask<String, Void, Tip> { private static final String PROGRESS_BAR_TASK_ID = TAG + "TipAddTask"; private Exception mReason; @Override public void onPreExecute() { if (DEBUG) Log.d(TAG, "TipAddTask: onPreExecute()"); startProgressBar(PROGRESS_BAR_TASK_ID); } @Override public Tip doInBackground(String... params) { if (DEBUG) Log.d(TAG, "CheckinsTask: doInBackground()"); try { assert params.length == 2; String tip = params[0]; String type = params[1]; return ((Foursquared) getApplication()).getFoursquare().addTip( mStateHolder.venueId, tip, type, LocationUtils.createFoursquareLocation(((Foursquared) getApplication()) .getLastKnownLocation())); } catch (Exception e) { mReason = e; } return null; } @Override public void onPostExecute(Tip tip) { if (DEBUG) Log.d(TAG, "TipAddTask: onPostExecute()"); try { if (tip == null) { NotificationsUtil.ToastReasonForFailure(VenueActivity.this, mReason); } else { // Refresh the tips list. Toast.makeText(VenueActivity.this, VenueActivity.this.getResources().getString( R.string.venue_activity_tip_add_result, tip.getId(), tip.getText()), Toast.LENGTH_LONG).show(); new VenueTask().execute(mStateHolder.venueId); } } finally { stopProgressBar(PROGRESS_BAR_TASK_ID); mStateHolder.tip = null; } } @Override public void onCancelled() { stopProgressBar(PROGRESS_BAR_TASK_ID); } } private static final class StateHolder { Venue venue = null; String venueId = null; Tip tip = null; } }