From b4a9d54a276ea5cbeb68320d19b5564ba2591bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20P=C3=B3=C5=82grabia?= Date: Tue, 20 Sep 2016 13:04:52 +0200 Subject: [PATCH] Added fetching geocoded location (natural street address). --- .../urbanexplorer/AppConstants.java | 4 +- .../callbacks/LocationGeoCoderCallback.java | 8 ++ .../urbanexplorer/fragments/HomeFragment.java | 50 +++++++---- .../fragments/WikiLocationsFragment.java | 38 ++++++--- .../urbanexplorer/utils/LocationUtils.java | 83 +++++++++++++++++++ 5 files changed, 155 insertions(+), 28 deletions(-) create mode 100644 app/src/main/java/pl/tpolgrabia/urbanexplorer/callbacks/LocationGeoCoderCallback.java diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java index 1a0a1b2..f0a2815 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/AppConstants.java @@ -4,9 +4,9 @@ package pl.tpolgrabia.urbanexplorer; * Created by tpolgrabia on 27.08.16. */ public class AppConstants { - public static final String GOOGLE_API_KEY = "AIzaSyDAnmEK6cgovRrefUuYojL1pxPEbIBLZUw"; + public static final String GOOGLE_API_KEY = "AIzaSyBAJoK-pu_qnQ0U8EGjM1Zkz_g8oJV4w2g"; public static final long MIN_TIME = 60000; - public static final AppStage RELEASE = AppStage.FINAL; + public static final AppStage RELEASE = AppStage.DEVELOPMENT; public static final float MIN_DISTANCE = 100; public static final float PAMNORAMIO_DEF_RADIUSX = 0.05f; public static final float PAMNORAMIO_DEF_RADIUSY = 0.05f; diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/callbacks/LocationGeoCoderCallback.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/callbacks/LocationGeoCoderCallback.java new file mode 100644 index 0000000..b2d2e1a --- /dev/null +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/callbacks/LocationGeoCoderCallback.java @@ -0,0 +1,8 @@ +package pl.tpolgrabia.urbanexplorer.callbacks; + +/** + * Created by Tomasz Półgrabia (c310702) on 20.09.2016. + */ +public interface LocationGeoCoderCallback { + void callback(int code, String message, String googleStatus, String geocodedLocation); +} diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/HomeFragment.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/HomeFragment.java index 20738ff..1e6238c 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/HomeFragment.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/HomeFragment.java @@ -20,12 +20,10 @@ import org.slf4j.LoggerFactory; import pl.tpolgrabia.urbanexplorer.AppConstants; import pl.tpolgrabia.urbanexplorer.MainActivity; import pl.tpolgrabia.urbanexplorer.R; -import pl.tpolgrabia.urbanexplorer.callbacks.PanoramioResponseCallback; -import pl.tpolgrabia.urbanexplorer.callbacks.PanoramioResponseStatus; -import pl.tpolgrabia.urbanexplorer.callbacks.ProviderStatusCallback; -import pl.tpolgrabia.urbanexplorer.callbacks.StandardLocationListenerCallback; +import pl.tpolgrabia.urbanexplorer.callbacks.*; import pl.tpolgrabia.urbanexplorer.dto.panoramio.PanoramioCacheDto; import pl.tpolgrabia.urbanexplorer.dto.panoramio.PanoramioImageInfo; +import pl.tpolgrabia.urbanexplorer.utils.LocationUtils; import pl.tpolgrabia.urbanexplorer.utils.NetUtils; import pl.tpolgrabia.urbanexplorer.utils.PanoramioUtils; @@ -51,6 +49,7 @@ public class HomeFragment extends Fragment implements Refreshable { private Semaphore loading; private ArrayList photos; private boolean noMorePhotos; + private String currentGeocodedLocation; public int getPanoramioBulkDataSize() { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); @@ -93,7 +92,8 @@ public class HomeFragment extends Fragment implements Refreshable { public void callback(Location location) { noMorePhotos = false; photos = new ArrayList<>(); - updateLocationInfo(); + currentGeocodedLocation = null; + updateGeocodedLocation(); try { fetchAdditionalPhotos(); } catch (InterruptedException e) { @@ -113,6 +113,26 @@ public class HomeFragment extends Fragment implements Refreshable { }); } + private void updateGeocodedLocation() { + if (getActivity() == null) { + lg.debug("Activity still not attached"); + return; + } + + Location currLocation = NetUtils.getLastKnownLocation(getActivity()); + LocationUtils.getGeoCodedLocation(getActivity(), currLocation.getLatitude(), currLocation.getLongitude(), new LocationGeoCoderCallback() { + @Override + public void callback(int code, String message, String googleStatus, String geocodedLocation) { + lg.debug("Geocoded result code {}, message {}, status: {}, value {}", + code, message, googleStatus, geocodedLocation); + + currentGeocodedLocation = geocodedLocation; + updateLocationInfo(); + } + }); + + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -415,7 +435,12 @@ public class HomeFragment extends Fragment implements Refreshable { super.onResume(); getActivity().setTitle("Panoramio search"); lg.trace("onResume"); - updateLocationInfo(); + if (currentGeocodedLocation != null) { + updateLocationInfo(); + } + else { + updateGeocodedLocation(); + } } public void updateLocationInfo() { @@ -425,21 +450,16 @@ public class HomeFragment extends Fragment implements Refreshable { lg.warn("Fragment has no view"); return; } - TextView locationInfo = (TextView) view.findViewById(R.id.locationInfo); + final TextView locationInfo = (TextView) view.findViewById(R.id.locationInfo); final FragmentActivity activity = getActivity(); if (activity == null) { lg.warn("Activity should'nt be null. No headless fragment"); return; } - Location currLocation = NetUtils.getLastKnownLocation(activity); + final Location currLocation = NetUtils.getLastKnownLocation(activity); lg.trace("Current location: {}, locationInfo: {}", currLocation, locationInfo); - if (currLocation != null && locationInfo != null) { - // update home fragment's location info - locationInfo.setText("Your current location: (" - + currLocation.getLatitude() - + "," + - currLocation.getLongitude() + ")"); - } + locationInfo.setText(currentGeocodedLocation); + } @Override diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/WikiLocationsFragment.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/WikiLocationsFragment.java index 7208f92..4ee9292 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/WikiLocationsFragment.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/fragments/WikiLocationsFragment.java @@ -21,10 +21,7 @@ import pl.tpolgrabia.urbanexplorer.AppConstants; import pl.tpolgrabia.urbanexplorer.MainActivity; import pl.tpolgrabia.urbanexplorer.R; import pl.tpolgrabia.urbanexplorer.adapters.WikiLocationsAdapter; -import pl.tpolgrabia.urbanexplorer.callbacks.FetchWikiLocationsCallback; -import pl.tpolgrabia.urbanexplorer.callbacks.ProviderStatusCallback; -import pl.tpolgrabia.urbanexplorer.callbacks.StandardLocationListenerCallback; -import pl.tpolgrabia.urbanexplorer.callbacks.WikiStatus; +import pl.tpolgrabia.urbanexplorer.callbacks.*; import pl.tpolgrabia.urbanexplorer.dto.wiki.WikiCacheDto; import pl.tpolgrabia.urbanexplorer.dto.wiki.app.WikiAppObject; import pl.tpolgrabia.urbanexplorer.utils.*; @@ -51,6 +48,7 @@ public class WikiLocationsFragment extends Fragment implements Refreshable { private TextView currentLocation; private ArrayList appObjects = new ArrayList<>(); private int lastFetchSize = -1; + private String currentGeocodedLocation; public WikiLocationsFragment() { // Required empty public constructor @@ -223,11 +221,34 @@ public class WikiLocationsFragment extends Fragment implements Refreshable { public void onResume() { super.onResume(); getActivity().setTitle("Wiki search"); - updateLocationInfo(); + if (currentGeocodedLocation != null) { + updateLocationInfo(); + } else { + updateGeocodedLocation(); + } fetchWikiLocations(); lg.trace("onResume {}", System.identityHashCode(this)); } + private void updateGeocodedLocation() { + if (getActivity() == null) { + lg.debug("Activity is not attached"); + return; + } + + Location location = NetUtils.getLastKnownLocation(getActivity()); + LocationUtils.getGeoCodedLocation(getActivity(), location.getLatitude(), location.getLongitude(), new LocationGeoCoderCallback() { + @Override + public void callback(int code, String message, String googleStatus, String geocodedLocation) { + lg.debug("Geocoded result code {}, message {}, status: {}, value {}", + code, message, googleStatus, geocodedLocation); + + currentGeocodedLocation = geocodedLocation; + updateLocationInfo(); + } + }); + } + public void updateLocationInfo() { final FragmentActivity activity = getActivity(); if (activity == null) { @@ -235,12 +256,7 @@ public class WikiLocationsFragment extends Fragment implements Refreshable { return; } final Location location = NetUtils.getLastKnownLocation(activity); - if (location != null) { - currentLocation.setText("Your current location: (" - + location.getLatitude() - + "," - + location.getLongitude() + ")"); - } + currentLocation.setText(currentGeocodedLocation); } @Override diff --git a/app/src/main/java/pl/tpolgrabia/urbanexplorer/utils/LocationUtils.java b/app/src/main/java/pl/tpolgrabia/urbanexplorer/utils/LocationUtils.java index 243b9f4..0186afa 100644 --- a/app/src/main/java/pl/tpolgrabia/urbanexplorer/utils/LocationUtils.java +++ b/app/src/main/java/pl/tpolgrabia/urbanexplorer/utils/LocationUtils.java @@ -2,8 +2,15 @@ package pl.tpolgrabia.urbanexplorer.utils; import android.content.Context; import android.location.LocationManager; +import com.androidquery.AQuery; +import com.androidquery.callback.AjaxCallback; +import com.androidquery.callback.AjaxStatus; +import org.json.JSONArray; +import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import pl.tpolgrabia.urbanexplorer.AppConstants; +import pl.tpolgrabia.urbanexplorer.callbacks.LocationGeoCoderCallback; /** * Created by tpolgrabia on 28.08.16. @@ -34,4 +41,80 @@ public class LocationUtils { return null; } + + public static void getGeoCodedLocation(Context ctx, Double latitude, Double longitude, + final LocationGeoCoderCallback clbk) { + if (ctx == null) { + throw new IllegalArgumentException("Context cannot be null"); + } + + if (latitude == null) { + throw new IllegalArgumentException("Latitude cannot be null"); + } + + if (longitude == null) { + throw new IllegalArgumentException("Longitude cannot be null"); + } + + AQuery aq = new AQuery(ctx); + + aq.ajax("https://maps.googleapis.com/maps/api/geocode/json" + + "?latlng=" + latitude + "," + longitude + + "&key=" + AppConstants.GOOGLE_API_KEY, JSONObject.class, new AjaxCallback(){ + @Override + public void callback(String url, JSONObject object, AjaxStatus status) { + lg.debug("Got response from url {} with status {} - {}", + url, + status, + object); + + String googleStatus = object != null ? object.optString("status") : "(null)"; + lg.trace("Google status {}", googleStatus); + + if (status.getCode() != 200) { + lg.info("Got invalid response with error code {} and message {} and error {}", + status.getCode(), status.getMessage(), status.getError()); + clbk.callback(status.getCode(), status.getMessage(), googleStatus, null); + return; + } + + if (!"OK".equals(googleStatus)) { + lg.info("Got invalid google status {}", googleStatus); + clbk.callback(status.getCode(), status.getMessage(), googleStatus, null); + return; + } + + JSONArray results = object.optJSONArray("results"); + int n = results.length(); + for (int i = 0; i < n; i++) { + result = results.optJSONObject(i); + if (result == null) { + continue; + } + + JSONArray types = result.optJSONArray("types"); + if (types == null) { + continue; + } + + if (types.length() != 1){ + continue; + } + + String singleType = types.optString(0); + if (!"street_address".equals(singleType)) { + continue; + } + clbk.callback(status.getCode(), + status.getMessage(), + googleStatus, + result.optString("formatted_address")); + return; + } + + clbk.callback(status.getCode(), status.getMessage(), googleStatus, "(not found)"); + + } + }); + } }