package com.mobmonkey.mobmonkeyandroid.fragments; import java.util.ArrayList; import java.util.HashMap; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.location.Address; import android.location.Location; import android.os.Bundle; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter; import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener; import com.google.android.gms.maps.GoogleMap.OnMapClickListener; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.mobmonkey.mobmonkeyandroid.R; import com.mobmonkey.mobmonkeyandroid.AddLocationScreen; import com.mobmonkey.mobmonkeyandroid.arrayadapters.MMSearchResultsArrayAdapter; import com.mobmonkey.mobmonkeyandroid.arrayadaptersitems.MMSearchResultsItem; import com.mobmonkey.mobmonkeyandroid.listeners.*; import com.mobmonkey.mobmonkeyandroid.utils.MMExpandedListView; import com.mobmonkey.mobmonkeyandroid.utils.MMFragment; import com.mobmonkey.mobmonkeyandroid.utils.MMSupportMapFragment; import com.mobmonkey.mobmonkeyandroid.utils.MMUtility; import com.mobmonkey.mobmonkeysdk.adapters.MMGeocoderAdapter; import com.mobmonkey.mobmonkeysdk.utils.MMCallback; import com.mobmonkey.mobmonkeysdk.utils.MMProgressDialog; import com.mobmonkey.mobmonkeysdk.utils.MMSDKConstants; import com.mobmonkey.mobmonkeysdk.utils.MMLocationListener; import com.mobmonkey.mobmonkeysdk.utils.MMLocationManager; /** * @author Dezapp, LLC * */ public class SearchResultsFragment extends MMFragment implements OnClickListener, OnItemClickListener, OnInfoWindowClickListener, OnMapClickListener { private static final String TAG = "SearchResultsScreen: "; private SharedPreferences userPrefs; private SharedPreferences.Editor userPrefsEditor; private String user; private FragmentManager fragmentManager; private JSONArray searchResults; private Location location; private MMSearchResultsItem[] resultLocations; private JSONArray locationHistory; private TextView tvNavBarTitle; private ImageButton ibMap; private Button btnAddLoc; private Button btnCancel; private MMExpandedListView elvSearchResults; private MMSupportMapFragment smfResultLocations; private GoogleMap googleMap; private boolean displayMap = false; private boolean addLocClicked; private Marker currMarker; private float currZoomLevel = 16; private HashMap<Marker, JSONObject> markerHashMap; private MMOnSearchResultsFragmentItemClickListener searchResultsLocationSelectListener; /* * (non-Javadoc) * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Log.d(TAG, TAG + "onCreateView"); userPrefs = getActivity().getSharedPreferences(MMSDKConstants.USER_PREFS, Context.MODE_PRIVATE); userPrefsEditor = userPrefs.edit(); user = userPrefs.getString(MMSDKConstants.KEY_USER, MMSDKConstants.DEFAULT_STRING_EMPTY); fragmentManager = getFragmentManager(); location = MMLocationManager.getGPSLocation(); View view = inflater.inflate(R.layout.fragment_searchresults_screen, container, false); tvNavBarTitle = (TextView) view.findViewById(R.id.tvnavbartitle); ibMap = (ImageButton) view.findViewById(R.id.ibmap); btnAddLoc = (Button) view.findViewById(R.id.btnaddloc); btnCancel = (Button) view.findViewById(R.id.btncancel); elvSearchResults = (MMExpandedListView) view.findViewById(R.id.elvsearchresults); tvNavBarTitle.setText(getArguments().getString(MMSDKConstants.KEY_INTENT_EXTRA_SEARCH_RESULT_TITLE)); try { if(!getArguments().getString(MMSDKConstants.KEY_INTENT_EXTRA_SEARCH_RESULTS).equals(MMSDKConstants.DEFAULT_STRING_EMPTY)) { searchResults = new JSONArray(getArguments().getString(MMSDKConstants.KEY_INTENT_EXTRA_SEARCH_RESULTS)); } else { searchResults = new JSONArray(); } getLocations(); } catch (JSONException e) { e.printStackTrace(); } ibMap.setOnClickListener(SearchResultsFragment.this); btnAddLoc.setOnClickListener(SearchResultsFragment.this); btnCancel.setOnClickListener(SearchResultsFragment.this); elvSearchResults.setOnItemClickListener(SearchResultsFragment.this); ArrayAdapter<MMSearchResultsItem> arrayAdapter = new MMSearchResultsArrayAdapter(getActivity(), R.layout.listview_row_searchresults, resultLocations); elvSearchResults.setAdapter(arrayAdapter); addLocClicked = false; return view; } /* * (non-Javadoc) * @see android.support.v4.app.Fragment#onAttach(android.app.Activity) */ @Override public void onAttach(Activity activity) { super.onAttach(activity); if(activity instanceof MMOnSearchResultsFragmentItemClickListener) { searchResultsLocationSelectListener = (MMOnSearchResultsFragmentItemClickListener) activity; } } /* * (non-Javadoc) * @see com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener#onInfoWindowClick(com.google.android.gms.maps.model.Marker) */ @Override public void onInfoWindowClick(Marker marker) { try { addToHistory(markerHashMap.get((Marker) marker)); currMarker = marker; currZoomLevel = googleMap.getCameraPosition().zoom; searchResultsLocationSelectListener.onSearchResultsFragmentItemClick(markerHashMap.get((Marker) marker).toString()); } catch (JSONException e) { e.printStackTrace(); } } /* * (non-Javadoc) * @see com.google.android.gms.maps.GoogleMap.OnMapClickListener#onMapClick(com.google.android.gms.maps.model.LatLng) */ @Override public void onMapClick(LatLng pointClicked) { if(addLocClicked) { MMGeocoderAdapter.getFromLocation(getActivity(), new ReverseGeocodeCallback(), pointClicked.latitude, pointClicked.longitude); MMProgressDialog.displayDialog(getActivity(), MMSDKConstants.DEFAULT_STRING_EMPTY, getString(R.string.pd_retrieving_location_information)); } } /* * (non-Javadoc) * @see android.view.View.OnClickListener#onClick(android.view.View) */ @Override public void onClick(View view) { switch(view.getId()) { case R.id.ibmap: ibMapClick(); break; case R.id.btnaddloc: buttonAddLocClick(); break; case R.id.btncancel: buttonCancelClick(); break; } } /* * (non-Javadoc) * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long) */ @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long arg3) { try { Log.d(TAG, TAG + "onItemClick"); addToHistory(searchResults.getJSONObject(position)); searchResultsLocationSelectListener.onSearchResultsFragmentItemClick(searchResults.getJSONObject(position).toString()); } catch (JSONException e) { e.printStackTrace(); } } /* (non-Javadoc) * @see android.support.v4.app.Fragment#onResume() */ @Override public void onResume() { super.onResume(); getMMSupportMapFragment(); } /* (non-Javadoc) * @see android.support.v4.app.Fragment#onPause() */ @Override public void onPause() { super.onPause(); try { FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.remove(smfResultLocations); transaction.commitAllowingStateLoss(); } catch (Exception e) { e.printStackTrace(); } } /* * (non-Javadoc) * @see android.support.v4.app.Fragment#onDestroyView() */ @Override public void onDestroyView() { super.onDestroyView(); } /* (non-Javadoc) * @see com.mobmonkey.mobmonkey.utils.MMFragment#onFragmentBackPressed() */ @Override public void onFragmentBackPressed() { } /** * * @throws JSONException */ private void getLocations() throws JSONException { resultLocations = new MMSearchResultsItem[searchResults.length()]; for(int i = 0; i < searchResults.length(); i++) { JSONObject jObj = searchResults.getJSONObject(i); resultLocations[i] = new MMSearchResultsItem(); resultLocations[i].setLocName(jObj.getString(MMSDKConstants.JSON_KEY_NAME)); resultLocations[i].setLocDist(MMUtility.calcDist(location, jObj.getDouble(MMSDKConstants.JSON_KEY_LATITUDE), jObj.getDouble(MMSDKConstants.JSON_KEY_LONGITUDE)) + MMSDKConstants.DEFAULT_STRING_SPACE + getString(R.string.miles)); String address = MMSDKConstants.DEFAULT_STRING_EMPTY; address += jObj.isNull(MMSDKConstants.JSON_KEY_ADDRESS) ? MMSDKConstants.DEFAULT_STRING_EMPTY : jObj.getString(MMSDKConstants.JSON_KEY_ADDRESS); address += MMSDKConstants.DEFAULT_STRING_NEWLINE; String localityRegion = MMSDKConstants.DEFAULT_STRING_EMPTY; localityRegion += jObj.isNull(MMSDKConstants.JSON_KEY_LOCALITY) ? MMSDKConstants.DEFAULT_STRING_EMPTY : jObj.getString(MMSDKConstants.JSON_KEY_LOCALITY); localityRegion += jObj.isNull(MMSDKConstants.JSON_KEY_LOCALITY) || jObj.isNull(MMSDKConstants.JSON_KEY_REGION) ? MMSDKConstants.DEFAULT_STRING_EMPTY : MMSDKConstants.DEFAULT_STRING_COMMA_SPACE; localityRegion += jObj.isNull(MMSDKConstants.JSON_KEY_REGION) ? MMSDKConstants.DEFAULT_STRING_EMPTY : jObj.getString(MMSDKConstants.JSON_KEY_REGION); resultLocations[i].setLocAddr(address + localityRegion); Log.d(TAG, i + " stream: " + jObj.getInt(MMSDKConstants.MEDIA_LIVESTREAMING) + " video: " + jObj.getInt(MMSDKConstants.JSON_KEY_VIDEOS) + " images: " + jObj.getInt(MMSDKConstants.JSON_KEY_IMAGES)); } } /** * @throws JSONException * */ private void getMMSupportMapFragment() { smfResultLocations = (MMSupportMapFragment) fragmentManager.findFragmentByTag(MMSDKConstants.MMSUPPORT_MAP_FRAGMENT_TAG); if(smfResultLocations == null) { smfResultLocations = new MMSupportMapFragment() { /* (non-Javadoc) * @see android.support.v4.app.Fragment#onActivityCreated(android.os.Bundle) */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); googleMap = smfResultLocations.getMap(); if(googleMap != null) { try { smfResultLocations.getView().setVisibility(View.INVISIBLE); addToGoogleMap(); getLocationHistory(); } catch (JSONException e) { e.printStackTrace(); } } } }; FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.llsearchresultsmap, smfResultLocations, MMSDKConstants.MMSUPPORT_MAP_FRAGMENT_TAG); fragmentTransaction.commit(); } } /** * * @return * @throws JSONException */ private boolean getLocationHistory() throws JSONException { String history = userPrefs.getString(user + MMSDKConstants.SHARED_PREFS_KEY_HISTORY, MMSDKConstants.DEFAULT_STRING_EMPTY); if(!history.equals(MMSDKConstants.DEFAULT_STRING_EMPTY)) { locationHistory = new JSONArray(history); return true; } else { locationHistory = new JSONArray(); return false; } } /** * * @throws JSONException */ private void addToGoogleMap() throws JSONException { LatLng currentLoc = new LatLng(location.getLatitude(), location.getLongitude()); markerHashMap = new HashMap<Marker, JSONObject>(); googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter()); for(int i = 0; i < searchResults.length(); i++) { JSONObject jObj = searchResults.getJSONObject(i); LatLng resultLocLatLng = new LatLng(jObj.getDouble(MMSDKConstants.JSON_KEY_LATITUDE), jObj.getDouble(MMSDKConstants.JSON_KEY_LONGITUDE)); Marker locationResultMarker = googleMap.addMarker(new MarkerOptions(). position(resultLocLatLng). title(jObj.getString(MMSDKConstants.JSON_KEY_NAME)) .snippet(jObj.getString(MMSDKConstants.JSON_KEY_ADDRESS))); if(currMarker != null && currMarker.getTitle().equals(locationResultMarker.getTitle())) { Log.d(TAG, TAG + "marker equal"); locationResultMarker.showInfoWindow(); currentLoc = currMarker.getPosition(); } markerHashMap.put(locationResultMarker, jObj); } if(currMarker != null) { currentLoc = currMarker.getPosition(); } googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLoc, currZoomLevel)); googleMap.setOnInfoWindowClickListener(SearchResultsFragment.this); googleMap.setOnMapClickListener(SearchResultsFragment.this); googleMap.setMyLocationEnabled(true); Log.d(TAG, TAG + "my location: " + googleMap.getMyLocation()); } /** * * @param position * @throws JSONException */ private void addToHistory(JSONObject loc) throws JSONException { if(!locationExistsInHistory(loc)) { if(locationHistory.length() < MMSDKConstants.HISTORY_SIZE) { ArrayList<JSONObject> temp = new ArrayList<JSONObject>(); //Convert to ArrayList so that you can add last item view to front of array for (int i=0; i<locationHistory.length(); i++) temp.add(locationHistory.getJSONObject(i)); temp.add(0, loc); locationHistory = new JSONArray(temp); } else { ArrayList<JSONObject> temp = new ArrayList<JSONObject>(); //Convert to ArrayList so that you can add last item view to front of array for (int i=0; i<locationHistory.length(); i++) temp.add(locationHistory.getJSONObject(i)); temp.add(0, loc); temp.remove(MMSDKConstants.HISTORY_SIZE); locationHistory = new JSONArray(temp); } } userPrefsEditor.putString(user + MMSDKConstants.SHARED_PREFS_KEY_HISTORY, locationHistory.toString()); userPrefsEditor.commit(); } /** * * @param loc * @return * @throws JSONException */ private boolean locationExistsInHistory(JSONObject loc) throws JSONException { if(locationHistory.length() <= 0) { return false; } for(int i = 0; i < locationHistory.length(); i++) { if(locationHistory.getJSONObject(i).getString(MMSDKConstants.JSON_KEY_NAME).equals(loc.getString(MMSDKConstants.JSON_KEY_NAME)) && locationHistory.getJSONObject(i).getString(MMSDKConstants.JSON_KEY_LATITUDE).equals(loc.getString(MMSDKConstants.JSON_KEY_LATITUDE)) && locationHistory.getJSONObject(i).getString(MMSDKConstants.JSON_KEY_LONGITUDE).equals(loc.getString(MMSDKConstants.JSON_KEY_LONGITUDE))) { ArrayList<JSONObject> temp = new ArrayList<JSONObject>(); //Convert to ArrayList so that you can add last item view to front of array for (int j=0; j<locationHistory.length(); j++) temp.add(locationHistory.getJSONObject(j)); JSONObject tempObj = temp.remove(i); temp.add(0, tempObj); locationHistory = new JSONArray(temp); return true; } } return false; } /** * */ private void ibMapClick() { if(elvSearchResults.getVisibility() == View.VISIBLE) { displayMap = true; elvSearchResults.setVisibility(View.INVISIBLE); smfResultLocations.getView().setVisibility(View.VISIBLE); } else if(elvSearchResults.getVisibility() == View.INVISIBLE) { displayMap = false; elvSearchResults.setVisibility(View.VISIBLE); smfResultLocations.getView().setVisibility(View.INVISIBLE); btnAddLoc.setVisibility(View.VISIBLE); btnCancel.setVisibility(View.GONE); } } /** * */ private void buttonAddLocClick() { if(MMLocationManager.isGPSEnabled() && MMLocationManager.getGPSLocation() != null) { if(smfResultLocations.getView().getVisibility() == View.INVISIBLE) { startActivity(new Intent(getActivity(), AddLocationScreen.class)); } else { Toast.makeText(getActivity(), R.string.toast_tap_location_to_add, Toast.LENGTH_LONG).show(); addLocClicked = true; btnAddLoc.setVisibility(View.GONE); btnCancel.setVisibility(View.VISIBLE); } } } /** * */ private void buttonCancelClick() { addLocClicked = false; btnAddLoc.setVisibility(View.VISIBLE); btnCancel.setVisibility(View.GONE); } /** * * @author Dezapp, LLC * */ private class ReverseGeocodeCallback implements MMCallback { @Override public void processCallback(Object obj) { MMProgressDialog.dismissDialog(); if(obj != null) { if(obj instanceof String) { if(((String) obj).equals(MMSDKConstants.CONNECTION_TIMED_OUT)) { Toast.makeText(getActivity(), getString(R.string.toast_connection_timed_out), Toast.LENGTH_SHORT).show(); } else if(((String) obj).equals(MMSDKConstants.SERVICE_NOT_AVAILABLE)) { Toast.makeText(getActivity(), R.string.toast_service_not_available, Toast.LENGTH_LONG).show(); } } else if(obj instanceof Address) { Address locationClicked = (Address) obj; Intent intent = new Intent(getActivity(), AddLocationScreen.class); intent.putExtra(MMSDKConstants.JSON_KEY_ADDRESS, locationClicked.getAddressLine(MMSDKConstants.DEFAULT_INT_ZERO)); intent.putExtra(MMSDKConstants.JSON_KEY_LOCALITY, locationClicked.getLocality()); intent.putExtra(MMSDKConstants.JSON_KEY_REGION, locationClicked.getAdminArea()); intent.putExtra(MMSDKConstants.JSON_KEY_POSTCODE, locationClicked.getPostalCode()); intent.putExtra(MMSDKConstants.JSON_KEY_COUNTRY_CODE, locationClicked.getCountryCode()); intent.putExtra(MMSDKConstants.JSON_KEY_LATITUDE, locationClicked.getLatitude()); intent.putExtra(MMSDKConstants.JSON_KEY_LONGITUDE, locationClicked.getLongitude()); startActivity(intent); } } } } /** * * @author Dezapp, LLC * */ private class CustomInfoWindowAdapter implements InfoWindowAdapter { private final View mWindow; private final View mContents; public CustomInfoWindowAdapter() { mWindow = getActivity().getLayoutInflater().inflate(R.layout.custom_info_window, null); mContents = getActivity().getLayoutInflater().inflate(R.layout.custom_info_contents, null); } @Override public View getInfoWindow(Marker marker) { render(marker, mWindow); return mWindow; } @Override public View getInfoContents(Marker marker) { render(marker, mContents); return mContents; } private void render(Marker marker, View view) { String title = marker.getTitle(); TextView titleUi = ((TextView) view.findViewById(R.id.title)); if (title != null) { titleUi.setText(title); } else { titleUi.setText(MMSDKConstants.DEFAULT_STRING_EMPTY); } String snippet = marker.getSnippet(); TextView snippetUi = ((TextView) view.findViewById(R.id.snippet)); if (snippet != null) { snippetUi.setText(snippet); } else { snippetUi.setText(MMSDKConstants.DEFAULT_STRING_EMPTY); } } } }