From 8a85ec379a395301e75d2329da6a3b1be7834b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20P=C3=B3=C5=82grabia?= Date: Thu, 29 Sep 2016 23:06:43 +0200 Subject: [PATCH] Working fetching basic google places data. --- .../urbanexplorer/AppConstants.java | 1 + .../urbanexplorer/MainActivity.java | 5 +- .../urbanexplorer/PlacesFragment.java | 33 ----- .../urbanexplorer/adapters/PlacesAdapter.java | 50 +++++++ .../fragments/PlacesFragment.java | 137 ++++++++++++++++++ .../handlers/GooglePlacesSwitchHandler.java | 2 +- app/src/main/res/layout/fragment_places.xml | 14 +- app/src/main/res/layout/google_place_item.xml | 17 +++ build.gradle | 4 + .../googleutils/callback/PlacesCallback.java | 12 ++ .../converter/GooglePlaceConverter.java | 67 ++++++++- .../googleutils/utils/PlacesUtils.java | 22 ++- gradle/wrapper/gradle-wrapper.properties | 4 +- 13 files changed, 317 insertions(+), 51 deletions(-) delete mode 100644 app/src/main/java/pl/tpolgrabia/urbanexplorer/PlacesFragment.java create mode 100644 app/src/main/java/pl/tpolgrabia/urbanexplorer/adapters/PlacesAdapter.java create mode 100644 app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/PlacesFragment.java create mode 100644 app/src/main/res/layout/google_place_item.xml create mode 100644 googleutils/src/main/java/pl/tpolgrabia/googleutils/callback/PlacesCallback.java diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java index 9d87f49..204d295 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java @@ -22,4 +22,5 @@ public class AppConstants { static final String SAVED_CONFIG_KEY = "SAVED_CONFIG_KEY"; public static final String GOOGLE_API_KEY = "AIzaSyBAJoK-pu_qnQ0U8EGjM1Zkz_g8oJV4w2g"; public static final String DEF_WIKI_COUNTRY_CODE = "en"; + public static final Double DEF_PLACES_RADIUS = 10000.0; } diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/MainActivity.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/MainActivity.java index 2d34c4b..5bf9dc0 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/MainActivity.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/MainActivity.java @@ -19,13 +19,10 @@ import pl.tpolgrabia.urbanexplorer.activities.SettingsActivity; import pl.tpolgrabia.urbanexplorer.callbacks.StandardLocationListener; import pl.tpolgrabia.urbanexplorer.dto.MainActivityState; import pl.tpolgrabia.panoramiobindings.dto.PanoramioImageInfo; +import pl.tpolgrabia.urbanexplorer.fragments.*; import pl.tpolgrabia.urbanexplorer.handlers.*; import pl.tpolgrabia.urbanexplorerutils.events.DataLoadingFinishEvent; import pl.tpolgrabia.urbanexplorerutils.events.DataLoadingStartEvent; -import pl.tpolgrabia.urbanexplorer.fragments.HomeFragment; -import pl.tpolgrabia.urbanexplorer.fragments.PanoramioShowerFragment; -import pl.tpolgrabia.urbanexplorer.fragments.Refreshable; -import pl.tpolgrabia.urbanexplorer.fragments.WikiLocationsFragment; import pl.tpolgrabia.urbanexplorer.utils.HelperUtils; import pl.tpolgrabia.urbanexplorer.views.CustomInterceptor; import pl.tpolgrabia.urbanexplorer.views.SwipeFrameLayout; diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/PlacesFragment.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/PlacesFragment.java deleted file mode 100644 index 42dfe98..0000000 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/PlacesFragment.java +++ /dev/null @@ -1,33 +0,0 @@ -package pl.tpolgrabia.urbanexplorer; - - -import android.os.Bundle; -import android.support.v4.app.Fragment; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - - -/** - * A simple {@link Fragment} subclass. - */ -public class PlacesFragment extends Fragment { - - - public static final String TAG = PlacesFragment.class.getSimpleName(); - - public PlacesFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - final View inflatedView = inflater.inflate(R.layout.fragment_places, container, false); - - return inflatedView; - } - -} diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/adapters/PlacesAdapter.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/adapters/PlacesAdapter.java new file mode 100644 index 0000000..d972a47 --- /dev/null +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/adapters/PlacesAdapter.java @@ -0,0 +1,50 @@ +package pl.tpolgrabia.urbanexplorer.adapters; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.TextView; +import com.nostra13.universalimageloader.core.ImageLoader; +import pl.tpolgrabia.googleutils.dto.GooglePlaceResult; +import pl.tpolgrabia.urbanexplorer.MainActivity; +import pl.tpolgrabia.urbanexplorer.R; + +import java.util.List; + +/** + * Created by tpolgrabia on 29.09.16. + */ +public class PlacesAdapter extends ArrayAdapter { + + public PlacesAdapter(Context context, @NonNull List objects) { + super(context, R.layout.google_place_item, objects); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View resultView; + if (convertView == null) { + final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + resultView = inflater.inflate(R.layout.google_place_item, parent, false); + } else { + resultView = convertView; + } + + GooglePlaceResult item = getItem(position); + TextView placeDescriptionWidget = (TextView) resultView.findViewById(R.id.place_description); + placeDescriptionWidget.setText(item.getName()); + + ImageView placePreviewWidget = (ImageView)resultView.findViewById(R.id.place_img_preview); + + ImageLoader.getInstance().displayImage( + item.getIcon(), + placePreviewWidget, + MainActivity.options); + + return resultView; + } +} diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/PlacesFragment.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/PlacesFragment.java new file mode 100644 index 0000000..3e80982 --- /dev/null +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/PlacesFragment.java @@ -0,0 +1,137 @@ +package pl.tpolgrabia.urbanexplorer.fragments; + + +import android.location.Location; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ListView; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import pl.tpolgrabia.googleutils.callback.PlacesCallback; +import pl.tpolgrabia.googleutils.dto.GooglePlaceResult; +import pl.tpolgrabia.googleutils.utils.PlacesUtils; +import pl.tpolgrabia.panoramiobindings.callback.ProviderStatusCallback; +import pl.tpolgrabia.urbanexplorer.AppConstants; +import pl.tpolgrabia.urbanexplorer.MainActivity; +import pl.tpolgrabia.urbanexplorer.R; +import pl.tpolgrabia.urbanexplorer.adapters.PlacesAdapter; +import pl.tpolgrabia.urbanexplorerutils.callbacks.StandardLocationListenerCallback; +import pl.tpolgrabia.urbanexplorerutils.utils.LocationUtils; + +import java.util.List; + + +/** + * A simple {@link Fragment} subclass. + */ +public class PlacesFragment extends Fragment { + + private static final Logger lg = LoggerFactory.getLogger(PlacesFragment.class); + public static final String TAG = PlacesFragment.class.getSimpleName(); + private PlacesUtils placesUtils; + + public PlacesFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + final View inflatedView = inflater.inflate(R.layout.fragment_places, container, false); + + return inflatedView; + } + + @Override + public void onActivityCreated(@Nullable Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + placesUtils = new PlacesUtils(getActivity(), AppConstants.GOOGLE_API_KEY); + + MainActivity mainActivity = (MainActivity) getActivity(); + mainActivity.getLocationCallback() + .addCallback(new StandardLocationListenerCallback() { + @Override + public void callback(Location location) { + lg.debug("Location changed: {}", location); + + if (location == null) { + return; + } + + fetchNearbyPlacesAndPresemt(location); + + } + }); + + mainActivity.getLocationCallback() + .addProviderCallback(new ProviderStatusCallback() { + @Override + public void callback(String provider, boolean enabled) { + + lg.debug("Provider {} has changed the status to {}", provider, enabled); + + if (!enabled) { + return; + } + + if (getActivity() == null) { + return; + } + + Location location = LocationUtils.getLastKnownLocation(getActivity()); + if (location == null) { + return; + } + + fetchNearbyPlacesAndPresemt(location); + + } + }); + + } + + @Override + public void onResume() { + super.onResume(); + + if (getActivity() == null) { + return; + } + + Location location = LocationUtils.getLastKnownLocation(getActivity()); + if (location == null) { + return; + } + + fetchNearbyPlacesAndPresemt(location); + + } + + private void fetchNearbyPlacesAndPresemt(Location location) { + placesUtils.fetchNearbyPlaces( + location.getLatitude(), + location.getLongitude(), + AppConstants.DEF_PLACES_RADIUS, + "museum", + null, + new PlacesCallback() { + @Override + public void callback(Long statusCode, String statusMsg, List googlePlaceResult) { + lg.debug("Fetch nearby statusCode: {}, status message: {}, google result: {}", + statusCode, + statusMsg, + googlePlaceResult); + + ListView googlePlacesWidget = (ListView) getView().findViewById(R.id.google_places); + PlacesAdapter adapter = new PlacesAdapter(getActivity(), googlePlaceResult); + googlePlacesWidget.setAdapter(adapter); + } + }); + } +} diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/handlers/GooglePlacesSwitchHandler.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/handlers/GooglePlacesSwitchHandler.java index 5807967..efcbe64 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/handlers/GooglePlacesSwitchHandler.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/handlers/GooglePlacesSwitchHandler.java @@ -3,7 +3,7 @@ package pl.tpolgrabia.urbanexplorer.handlers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import pl.tpolgrabia.urbanexplorer.MainActivity; -import pl.tpolgrabia.urbanexplorer.PlacesFragment; +import pl.tpolgrabia.urbanexplorer.fragments.PlacesFragment; /** * Created by tpolgrabia on 28.09.16. diff --git a/app/src/main/res/layout/fragment_places.xml b/app/src/main/res/layout/fragment_places.xml index 6bac01d..a8f880a 100644 --- a/app/src/main/res/layout/fragment_places.xml +++ b/app/src/main/res/layout/fragment_places.xml @@ -1,18 +1,20 @@ + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".fragments.PlacesFragment" + android:orientation="vertical"> + android:layout_weight="1" + android:layout_height="0dp"> diff --git a/app/src/main/res/layout/google_place_item.xml b/app/src/main/res/layout/google_place_item.xml new file mode 100644 index 0000000..8eb343a --- /dev/null +++ b/app/src/main/res/layout/google_place_item.xml @@ -0,0 +1,17 @@ + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 168f129..8cba23d 100644 --- a/build.gradle +++ b/build.gradle @@ -21,3 +21,7 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir } + +task wrapper(type: Wrapper) { + gradleVersion = '2.10' +} diff --git a/googleutils/src/main/java/pl/tpolgrabia/googleutils/callback/PlacesCallback.java b/googleutils/src/main/java/pl/tpolgrabia/googleutils/callback/PlacesCallback.java new file mode 100644 index 0000000..e96c865 --- /dev/null +++ b/googleutils/src/main/java/pl/tpolgrabia/googleutils/callback/PlacesCallback.java @@ -0,0 +1,12 @@ +package pl.tpolgrabia.googleutils.callback; + +import pl.tpolgrabia.googleutils.dto.GooglePlaceResult; + +import java.util.List; + +/** + * Created by tpolgrabia on 29.09.16. + */ +public interface PlacesCallback { + void callback(Long statusCode, String statusMsg, List googlePlaceResults); +} diff --git a/googleutils/src/main/java/pl/tpolgrabia/googleutils/converter/GooglePlaceConverter.java b/googleutils/src/main/java/pl/tpolgrabia/googleutils/converter/GooglePlaceConverter.java index 33e2af8..3b58fa3 100644 --- a/googleutils/src/main/java/pl/tpolgrabia/googleutils/converter/GooglePlaceConverter.java +++ b/googleutils/src/main/java/pl/tpolgrabia/googleutils/converter/GooglePlaceConverter.java @@ -2,6 +2,8 @@ package pl.tpolgrabia.googleutils.converter; import org.json.JSONArray; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import pl.tpolgrabia.googleutils.dto.*; import java.util.ArrayList; @@ -11,7 +13,16 @@ import java.util.List; * Created by tpolgrabia on 28.09.16. */ public class GooglePlaceConverter { + + private static final Logger lg = LoggerFactory.getLogger(GooglePlaceConverter.class); public static GooglePlaceResult convertToPlaceResult(JSONObject object) { + + lg.trace("Place result object: {}", object); + + if (object == null) { + return null; + } + GooglePlaceResult dto = new GooglePlaceResult(); dto.setGeometry(convertToPlaceGeometry(object.optJSONObject("geometry"))); dto.setIcon(object.optString("icon")); @@ -27,17 +38,29 @@ public class GooglePlaceConverter { return dto; } - private static List convertToStringList(JSONArray types) { - int n = types.length(); + private static List convertToStringList(JSONArray stringArray) { + lg.trace("String array: {}", stringArray); + + if (stringArray == null) { + return null; + } + + int n = stringArray.length(); List ret = new ArrayList<>(n); for (int i = 0; i < n; i++) { - ret.add(types.optString(i)); + ret.add(stringArray.optString(i)); } return ret; } private static List convertToPlacePhotos(JSONArray jphotos) { + lg.trace("Place photos: {}", jphotos); + + if (jphotos == null) { + return null; + } + int n = jphotos.length(); List photos = new ArrayList<>(n); @@ -49,6 +72,12 @@ public class GooglePlaceConverter { } private static GooglePlacePhoto convertToPlacePhoto(JSONObject jphoto) { + lg.trace("Place photo: {}", jphoto); + + if (jphoto == null) { + return null; + } + GooglePlacePhoto photo = new GooglePlacePhoto(); photo.setHeight(jphoto.optLong("height")); photo.setWidth(jphoto.optLong("width")); @@ -58,6 +87,12 @@ public class GooglePlaceConverter { } private static GooglePlaceGeometry convertToPlaceGeometry(JSONObject jgeometry) { + lg.trace("Place geometry: {}", jgeometry); + + if (jgeometry == null) { + return null; + } + GooglePlaceGeometry geometry = new GooglePlaceGeometry(); geometry.setLocation(convertToPlaceLocation(jgeometry.optJSONObject("location"))); geometry.setViewport(convertToPlaceViewport(jgeometry.optJSONObject("viewport"))); @@ -65,6 +100,12 @@ public class GooglePlaceConverter { } private static GooglePlaceViewport convertToPlaceViewport(JSONObject jviewport) { + lg.trace("Place viewport: {}", jviewport); + + if (jviewport == null) { + return null; + } + GooglePlaceViewport viewport = new GooglePlaceViewport(); viewport.setNorthEast(convertToPlaceLocation(jviewport.optJSONObject("northeast"))); viewport.setSouthWest(convertToPlaceLocation(jviewport.optJSONObject("southwest"))); @@ -72,9 +113,29 @@ public class GooglePlaceConverter { } private static GooglePlaceLocation convertToPlaceLocation(JSONObject jlocation) { + lg.trace("Place location: {}", jlocation); + if (jlocation == null) { + return null; + } + GooglePlaceLocation location = new GooglePlaceLocation(); location.setLatitude(jlocation.optDouble("lat")); location.setLongitude(jlocation.optDouble("lng")); return location; } + + public static List convertToPlaceResults(JSONArray jresults) { + lg.trace("Place results: {}", jresults); + + if (jresults == null) { + return null; + } + + List results = new ArrayList<>(); + int n = jresults.length(); + for (int i = 0; i < n; i++) { + results.add(convertToPlaceResult(jresults.optJSONObject(i))); + } + return results; + } } diff --git a/googleutils/src/main/java/pl/tpolgrabia/googleutils/utils/PlacesUtils.java b/googleutils/src/main/java/pl/tpolgrabia/googleutils/utils/PlacesUtils.java index f24921a..a22f14e 100644 --- a/googleutils/src/main/java/pl/tpolgrabia/googleutils/utils/PlacesUtils.java +++ b/googleutils/src/main/java/pl/tpolgrabia/googleutils/utils/PlacesUtils.java @@ -8,6 +8,11 @@ import com.google.gson.JsonObject; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pl.tpolgrabia.googleutils.callback.PlacesCallback; +import pl.tpolgrabia.googleutils.converter.GooglePlaceConverter; +import pl.tpolgrabia.googleutils.dto.GooglePlaceResult; + +import java.util.List; /** * Created by tpolgrabia on 27.09.16. @@ -26,7 +31,12 @@ public class PlacesUtils { this.aq = new AQuery(ctx); } - public void fetchNearbyPlaces(Double latitude, Double longitude, Double searchRadius, String searchItemType, String pageToken) { + public void fetchNearbyPlaces(Double latitude, + Double longitude, + Double searchRadius, + String searchItemType, + String pageToken, + final PlacesCallback clbk) { if (latitude == null) { throw new IllegalArgumentException("Latitude cannot be null"); @@ -65,16 +75,24 @@ public class PlacesUtils { statusCode, statusMessage, statusError); + clbk.callback((long)statusCode, statusMessage, null); return; } String googleStatus = object.optString("status"); if (!"OK".equals(googleStatus)) { lg.error("Invalid google status: {}", googleStatus); + clbk.callback((long)statusCode, googleStatus, null); return; } - + try { + List googleResults = GooglePlaceConverter.convertToPlaceResults(object.getJSONArray("results")); + clbk.callback((long) statusCode, googleStatus, googleResults); + } catch (Throwable t) { + lg.error("General error", t); + clbk.callback(-1L, "General error", null); + } } }); diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f23df6e..96b9d66 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Oct 21 11:34:03 PDT 2015 +#Thu Sep 29 21:09:40 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip