From d668c194df83710d78bc4af631c16b600a123442 Mon Sep 17 00:00:00 2001 From: David Boho Date: Wed, 11 Mar 2020 15:22:44 +0100 Subject: [PATCH 1/5] add GeocodingIntentService --- plugin.xml | 11 +- src/android/GeocodingIntentService.java | 224 +++++++++++++++++++++ src/android/NativeGeocoder.java | 254 ++++++------------------ 3 files changed, 290 insertions(+), 199 deletions(-) create mode 100644 src/android/GeocodingIntentService.java diff --git a/plugin.xml b/plugin.xml index 1635e5e..a7076f1 100644 --- a/plugin.xml +++ b/plugin.xml @@ -22,7 +22,16 @@ - + + + + + + diff --git a/src/android/GeocodingIntentService.java b/src/android/GeocodingIntentService.java new file mode 100644 index 0000000..51fee24 --- /dev/null +++ b/src/android/GeocodingIntentService.java @@ -0,0 +1,224 @@ +package cordova.plugin.nativegeocoder; + +import android.app.IntentService; +import android.content.Context; +import android.content.Intent; +import android.location.Address; +import android.location.Geocoder; +import android.location.Location; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.os.Bundle; +import android.os.ResultReceiver; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + + +class NativeGeocoderOptions { + boolean useLocale = true; + String defaultLocale = null; + int maxResults = 1; +} + +public class GeocodingIntentService extends IntentService { + public static final String OPTIONS_DATA_EXTRA = "NATIVE_GEOCODER_OPTIONS_DATA_EXTRA"; + public static final String LOCATION_DATA_EXTRA = "NATIVE_GEOCODER_LOCATION_DATA_EXTRA"; + public static final String ADDRESS_STRING_DATA_EXTRA = "NATIVE_GEOCODER_ADDRESS_STRING_DATA_EXTRA"; + public static final String RECEIVER = "NATIVE_GEOCODER_RECEIVER"; + public static final int FAILURE_RESULT = 1; + public static final int SUCCESS_RESULT = 0; + public static final String RESULT_DATA_KEY = "NATIVE_GEOCODER_RECEIVER_RESULT_KEY"; + + public GeocodingIntentService() { + super("GeocodingIntentService"); + } + + @Override + protected void onHandleIntent(Intent intent) { + Location location = intent.getParcelableExtra(LOCATION_DATA_EXTRA); + String options = intent.getStringExtra(OPTIONS_DATA_EXTRA); + String addressString = intent.getStringExtra(ADDRESS_STRING_DATA_EXTRA); + ResultReceiver mReceiver = intent.getParcelableExtra(RECEIVER); + + NativeGeocoderOptions geocoderOptions = getNativeGeocoderOptions(options); + + try { + if (location != null) { + backwardGeocode(mReceiver, location, geocoderOptions); + } else { + forwardGeocode(mReceiver, addressString, geocoderOptions); + } + } catch (Exception e) { + String errorMsg = e.getMessage(); + if (e.getMessage().equals("grpc failed") && !isNetworkAvailable()) { + errorMsg = "No Internet Access"; + } + deliverResultToReceiver(mReceiver, FAILURE_RESULT, "Geocoder:getFromLocationName Error: " + errorMsg); + } + } + + private void backwardGeocode(ResultReceiver mReceiver, Location location, NativeGeocoderOptions geocoderOptions) throws IOException { + Geocoder geocoder = createGeocoderWithOptions(geocoderOptions); + List
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), + geocoderOptions.maxResults); + if (addresses.size() > 0) { + JSONArray jsonAddresses = this.addressesToJSONArray(addresses, geocoderOptions.maxResults, false); + deliverResultToReceiver(mReceiver, SUCCESS_RESULT, jsonAddresses.toString()); + } else { + deliverResultToReceiver(mReceiver, FAILURE_RESULT, "Cannot get an address."); + } + } + + private void forwardGeocode(ResultReceiver mReceiver, String addressString, NativeGeocoderOptions geocoderOptions) throws IOException { + Geocoder geocoder = createGeocoderWithOptions(geocoderOptions); + List
addresses = geocoder.getFromLocationName(addressString, geocoderOptions.maxResults); + if (addresses.size() > 0) { + JSONArray jsonAddresses = this.addressesToJSONArray(addresses, geocoderOptions.maxResults, true); + if (jsonAddresses.length() > 0) { + deliverResultToReceiver(mReceiver, SUCCESS_RESULT, jsonAddresses.toString()); + } else { + deliverResultToReceiver(mReceiver, FAILURE_RESULT, "Cannot get latitude and/or longitude."); + } + } else { + deliverResultToReceiver(mReceiver, FAILURE_RESULT, "Cannot find a location."); + } + } + + private void deliverResultToReceiver(ResultReceiver mReceiver, int resultCode, String message) { + Bundle bundle = new Bundle(); + bundle.putString(RESULT_DATA_KEY, message); + mReceiver.send(resultCode, bundle); + } + + private JSONArray addressesToJSONArray(List
addresses, int maxResults, boolean skipEmptyLocationResults) { + JSONArray resultArray = new JSONArray(); + int maxResultObjects = addresses.size() >= maxResults ? maxResults : addresses.size(); + + for (int i = 0; i < maxResultObjects; i++) { + Address address = addresses.get(i); + + try { + String latitude = String.valueOf(address.getLatitude()); + String longitude = String.valueOf(address.getLongitude()); + + boolean hasLocation = !latitude.isEmpty() && !longitude.isEmpty(); + if (hasLocation || !skipEmptyLocationResults) { + // https://developer.android.com/reference/android/location/Address.html + JSONObject placemark = new JSONObject(); + placemark.put("latitude", latitude.isEmpty() ? "" : latitude); + placemark.put("longitude", longitude.isEmpty() ? "" : longitude); + placemark.put("countryCode", address.getCountryCode() != null ? address.getCountryCode() : ""); + placemark.put("countryName", address.getCountryName() != null ? address.getCountryName() : ""); + placemark.put("postalCode", address.getPostalCode() != null ? address.getPostalCode() : ""); + placemark.put("administrativeArea", address.getAdminArea() != null ? address.getAdminArea() : ""); + placemark.put("subAdministrativeArea", address.getSubAdminArea() != null ? address.getSubAdminArea() : ""); + placemark.put("locality", address.getLocality() != null ? address.getLocality() : ""); + placemark.put("subLocality", address.getSubLocality() != null ? address.getSubLocality() : ""); + placemark.put("thoroughfare", address.getThoroughfare() != null ? address.getThoroughfare() : ""); + placemark.put("subThoroughfare", address.getSubThoroughfare() != null ? address.getSubThoroughfare() : ""); + placemark.put("areasOfInterest", address.getFeatureName() != null ? new JSONArray(new String[]{address.getFeatureName()}) : new JSONArray()); + + resultArray.put(placemark); + } + } catch (JSONException e) { + e.printStackTrace(); + } catch (RuntimeException e) { + e.printStackTrace(); + } + } + return resultArray; + } + + /** + * Get a valid NativeGeocoderOptions object + * + * @param stringOptions String + * @return NativeGeocoderOptions + */ + private NativeGeocoderOptions getNativeGeocoderOptions(String stringOptions) { + NativeGeocoderOptions geocoderOptions = new NativeGeocoderOptions(); + + if (stringOptions != null) { + try { + JSONObject options = new JSONObject(stringOptions); + geocoderOptions.useLocale = !options.has("useLocale") || options.getBoolean("useLocale"); + if (options.has("defaultLocale")) { + geocoderOptions.defaultLocale = options.getString("defaultLocale"); + } else { + geocoderOptions.defaultLocale = null; + } + if (options.has("maxResults")) { + geocoderOptions.maxResults = options.getInt("maxResults"); + + if (geocoderOptions.maxResults > 0) { + int MAX_RESULTS_COUNT = 5; + geocoderOptions.maxResults = geocoderOptions.maxResults > MAX_RESULTS_COUNT ? MAX_RESULTS_COUNT : geocoderOptions.maxResults; + } else { + geocoderOptions.maxResults = 1; + } + + } else { + geocoderOptions.maxResults = 1; + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + + return geocoderOptions; + } + + /** + * Create a Geocoder with NativeGeocoderOptions + * + * @param geocoderOptions NativeGeocoderOptions + * @return Geocoder + */ + private Geocoder createGeocoderWithOptions(NativeGeocoderOptions geocoderOptions) { + if (geocoderOptions.defaultLocale != null && !geocoderOptions.defaultLocale.isEmpty()) { + Locale locale; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + locale = Locale.forLanguageTag(geocoderOptions.defaultLocale); + } else { + String[] parts = geocoderOptions.defaultLocale.split("[-_]", -1); + if (parts.length == 1) + locale = new Locale(parts[0]); + else if (parts.length == 2 || (parts.length == 3 && parts[2].startsWith("#"))) + locale = new Locale(parts[0], parts[1]); + else + locale = new Locale(parts[0], parts[1], parts[2]); + } + return new Geocoder(this, locale); + } else { + if (geocoderOptions.useLocale) { + return new Geocoder(this, Locale.getDefault()); + } else { + return new Geocoder(this, Locale.ENGLISH); + } + } + } + + + /** + * Get network connection + * + * @return boolean + */ + private boolean isNetworkAvailable() { + ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo activeNetworkInfo = null; + if (connectivityManager != null) { + activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); + } + return activeNetworkInfo != null && activeNetworkInfo.isConnected(); + } + + +} diff --git a/src/android/NativeGeocoder.java b/src/android/NativeGeocoder.java index 5bb8c53..1ef49b0 100644 --- a/src/android/NativeGeocoder.java +++ b/src/android/NativeGeocoder.java @@ -1,11 +1,12 @@ package cordova.plugin.nativegeocoder; -import android.content.Context; -import android.location.Address; +import android.content.Intent; import android.location.Geocoder; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.os.Build; +import android.location.Location; +import android.os.Bundle; +import android.os.Handler; +import android.os.ResultReceiver; + import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaPlugin; @@ -14,14 +15,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.util.List; -import java.util.Locale; -class NativeGeocoderOptions { - boolean useLocale = true; - String defaultLocale = null; - int maxResults = 1; -} public class NativeGeocoder extends CordovaPlugin { private Geocoder geocoder; @@ -46,6 +40,10 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo } this.reverseGeocode(latitude, longitude, options, callbackContext); + + PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT); + r.setKeepCallback(true); + callbackContext.sendPluginResult(r); return true; } @@ -57,7 +55,12 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo } catch (JSONException e) { e.printStackTrace(); } + this.forwardGeocode(addressString, options, callbackContext); + + PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT); + r.setKeepCallback(true); + callbackContext.sendPluginResult(r); return true; } @@ -66,12 +69,13 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo /** * Reverse geocode a given latitude and longitude to find location address - * @param latitude double - * @param longitude double - * @param options JSONObject + * + * @param latitude double + * @param longitude double + * @param options JSONObject * @param callbackContext CallbackContext */ - private void reverseGeocode(double latitude, double longitude, JSONObject options, CallbackContext callbackContext) throws JSONException{ + private void reverseGeocode(double latitude, double longitude, JSONObject options, CallbackContext callbackContext) { if (latitude == 0 || longitude == 0) { PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Expected two non-empty double arguments."); @@ -84,61 +88,26 @@ private void reverseGeocode(double latitude, double longitude, JSONObject option callbackContext.sendPluginResult(r); return; } - - NativeGeocoderOptions geocoderOptions = getNativeGeocoderOptions(options); - geocoder = createGeocoderWithOptions(geocoderOptions); - - try { - List
geoResults = geocoder.getFromLocation(latitude, longitude, geocoderOptions.maxResults); - if (geoResults.size() > 0) { - int maxResultObjects = geoResults.size() >= geocoderOptions.maxResults ? geoResults.size() : geoResults.size(); - JSONArray resultObj = new JSONArray(); - - for (int i = 0; i < maxResultObjects; i++) { - Address address = geoResults.get(i); - - // https://developer.android.com/reference/android/location/Address.html - JSONObject placemark = new JSONObject(); - placemark.put("latitude", !String.valueOf(address.getLatitude()).isEmpty() ? address.getLatitude() : ""); - placemark.put("longitude", !String.valueOf(address.getLongitude()).isEmpty() ? address.getLongitude() : ""); - placemark.put("countryCode", address.getCountryCode() != null ? address.getCountryCode() : ""); - placemark.put("countryName", address.getCountryName() != null ? address.getCountryName() : ""); - placemark.put("postalCode", address.getPostalCode() != null ? address.getPostalCode() : ""); - placemark.put("administrativeArea", address.getAdminArea() != null ? address.getAdminArea() : ""); - placemark.put("subAdministrativeArea", address.getSubAdminArea() != null ? address.getSubAdminArea() : ""); - placemark.put("locality", address.getLocality() != null ? address.getLocality() : ""); - placemark.put("subLocality", address.getSubLocality() != null ? address.getSubLocality() : ""); - placemark.put("thoroughfare", address.getThoroughfare() != null ? address.getThoroughfare() : ""); - placemark.put("subThoroughfare", address.getSubThoroughfare() != null ? address.getSubThoroughfare() : ""); - placemark.put("areasOfInterest", address.getFeatureName() != null ? new JSONArray(new String[]{ address.getFeatureName()} ) : new JSONArray()); - - resultObj.put(placemark); - } - - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, resultObj)); - } else { - PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot get an address."); - callbackContext.sendPluginResult(r); - } - } - catch (Exception e) { - String errorMsg = e.getMessage(); - if (e.getMessage().equals("grpc failed") && !isNetworkAvailable()) { - errorMsg = "No Internet Access"; - } - PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Geocoder:getFromLocationName Error: " + errorMsg); - callbackContext.sendPluginResult(r); - } + Location location = new Location(""); + location.setLatitude(latitude); + location.setLongitude(longitude); + + Intent intent = new Intent(this.cordova.getActivity(), GeocodingIntentService.class); + intent.putExtra(GeocodingIntentService.RECEIVER, new AddressResultReceiver(callbackContext)); + intent.putExtra(GeocodingIntentService.LOCATION_DATA_EXTRA, location); + intent.putExtra(GeocodingIntentService.OPTIONS_DATA_EXTRA, options.toString()); + this.cordova.getActivity().startService(intent); } /** * Forward geocode a given address to find coordinates - * @param addressString String - * @param options JSONObject + * + * @param addressString String + * @param options JSONObject * @param callbackContext CallbackContext */ - private void forwardGeocode(String addressString, JSONObject options, CallbackContext callbackContext) throws JSONException { + private void forwardGeocode(String addressString, JSONObject options, CallbackContext callbackContext) { if (addressString == null || addressString.length() == 0) { PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Expected a non-empty string argument."); callbackContext.sendPluginResult(r); @@ -151,148 +120,37 @@ private void forwardGeocode(String addressString, JSONObject options, CallbackCo return; } - NativeGeocoderOptions geocoderOptions = getNativeGeocoderOptions(options); - geocoder = createGeocoderWithOptions(geocoderOptions); - - try { - List
geoResults = geocoder.getFromLocationName(addressString, geocoderOptions.maxResults); - - if (geoResults.size() > 0) { - int maxResultObjects = geoResults.size() >= geocoderOptions.maxResults ? geoResults.size() : geoResults.size(); - JSONArray resultObj = new JSONArray(); - - for (int i = 0; i < maxResultObjects; i++) { - Address address = geoResults.get(i); - - try { - String latitude = String.valueOf(address.getLatitude()); - String longitude = String.valueOf(address.getLongitude()); - - if (!latitude.isEmpty() && !longitude.isEmpty()) { - // https://developer.android.com/reference/android/location/Address.html - JSONObject placemark = new JSONObject(); - placemark.put("latitude", latitude); - placemark.put("longitude", longitude); - placemark.put("countryCode", address.getCountryCode() != null ? address.getCountryCode() : ""); - placemark.put("countryName", address.getCountryName() != null ? address.getCountryName() : ""); - placemark.put("postalCode", address.getPostalCode() != null ? address.getPostalCode() : ""); - placemark.put("administrativeArea", address.getAdminArea() != null ? address.getAdminArea() : ""); - placemark.put("subAdministrativeArea", address.getSubAdminArea() != null ? address.getSubAdminArea() : ""); - placemark.put("locality", address.getLocality() != null ? address.getLocality() : ""); - placemark.put("subLocality", address.getSubLocality() != null ? address.getSubLocality() : ""); - placemark.put("thoroughfare", address.getThoroughfare() != null ? address.getThoroughfare() : ""); - placemark.put("subThoroughfare", address.getSubThoroughfare() != null ? address.getSubThoroughfare() : ""); - placemark.put("areasOfInterest", address.getFeatureName() != null ? new JSONArray(new String[]{ address.getFeatureName() }) : new JSONArray()); - - resultObj.put(placemark); - } - } - catch (RuntimeException e) { - e.printStackTrace(); - } - } - - if (resultObj.length() == 0) { - PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot get latitude and/or longitude."); - callbackContext.sendPluginResult(r); - } else { - callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, resultObj)); - } - - } else { - PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Cannot find a location."); - callbackContext.sendPluginResult(r); - } - } - catch (Exception e) { - String errorMsg = e.getMessage(); - if (e.getMessage().equals("grpc failed") && !isNetworkAvailable()) { - errorMsg = "No Internet Access"; - } - PluginResult r = new PluginResult(PluginResult.Status.ERROR, "Geocoder:getFromLocationName Error: " + errorMsg); - callbackContext.sendPluginResult(r); - } + Intent intent = new Intent(this.cordova.getActivity(), GeocodingIntentService.class); + intent.putExtra(GeocodingIntentService.RECEIVER, new AddressResultReceiver(callbackContext)); + intent.putExtra(GeocodingIntentService.ADDRESS_STRING_DATA_EXTRA, addressString); + intent.putExtra(GeocodingIntentService.OPTIONS_DATA_EXTRA, options.toString()); + this.cordova.getActivity().startService(intent); } - /** - * Get network connection - * @return boolean - */ - private boolean isNetworkAvailable() { - ConnectivityManager connectivityManager - = (ConnectivityManager) cordova.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetworkInfo = null; - if (connectivityManager != null) { - activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); - } - return activeNetworkInfo != null && activeNetworkInfo.isConnected(); - } - - /** - * Get a valid NativeGeocoderOptions object - * @param options JSONObject - * @return NativeGeocoderOptions - */ - private NativeGeocoderOptions getNativeGeocoderOptions(JSONObject options) throws JSONException { - NativeGeocoderOptions geocoderOptions = new NativeGeocoderOptions(); - - if (options != null) { - geocoderOptions.useLocale = !options.has("useLocale") || options.getBoolean("useLocale"); - if (options.has("defaultLocale")) { - geocoderOptions.defaultLocale = options.getString("defaultLocale"); - } else { - geocoderOptions.defaultLocale = null; - } - if (options.has("maxResults")) { - geocoderOptions.maxResults = options.getInt("maxResults"); + static class AddressResultReceiver extends ResultReceiver { - if (geocoderOptions.maxResults > 0) { - int MAX_RESULTS_COUNT = 5; - geocoderOptions.maxResults = geocoderOptions.maxResults > MAX_RESULTS_COUNT ? MAX_RESULTS_COUNT : geocoderOptions.maxResults; - } else { - geocoderOptions.maxResults = 1; - } + private final CallbackContext callbackContext; - } else { - geocoderOptions.maxResults = 1; - } - } else { - geocoderOptions.useLocale = true; - geocoderOptions.defaultLocale = null; - geocoderOptions.maxResults = 1; + public AddressResultReceiver(CallbackContext callbackContext) { + super(new Handler()); + this.callbackContext = callbackContext; } - return geocoderOptions; - } - - /** - * Create a Geocoder with NativeGeocoderOptions - * @param geocoderOptions NativeGeocoderOptions - * @return Geocoder - */ - private Geocoder createGeocoderWithOptions(NativeGeocoderOptions geocoderOptions) { - if (geocoderOptions.defaultLocale != null && !geocoderOptions.defaultLocale.isEmpty()) { - Locale locale; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - locale = Locale.forLanguageTag(geocoderOptions.defaultLocale); + @Override + protected void onReceiveResult(int resultCode, Bundle resultData) { + String result = resultData.getString(GeocodingIntentService.RESULT_DATA_KEY); + PluginResult pluginResult; + if (resultCode == GeocodingIntentService.FAILURE_RESULT) { + pluginResult = new PluginResult(PluginResult.Status.ERROR, result); } else { - String parts[] = geocoderOptions.defaultLocale.split("[-_]", -1); - if (parts.length == 1) - locale = new Locale(parts[0]); - else if (parts.length == 2 || (parts.length == 3 && parts[2].startsWith("#"))) - locale = new Locale(parts[0], parts[1]); - else - locale = new Locale(parts[0], parts[1], parts[2]); - } - geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), locale); - } else { - if (geocoderOptions.useLocale) { - geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), Locale.getDefault()); - } else { - geocoder = new Geocoder(cordova.getActivity().getApplicationContext(), Locale.ENGLISH); + try { + JSONArray json = new JSONArray(result); + pluginResult = new PluginResult(PluginResult.Status.OK, json); + } catch (JSONException e) { + pluginResult = new PluginResult(PluginResult.Status.ERROR, "can not parse result"); + } } + this.callbackContext.sendPluginResult(pluginResult); } - return geocoder; } - } From 886b7db3e5feb062c241f3a01bb2857101d2444a Mon Sep 17 00:00:00 2001 From: David Boho Date: Wed, 11 Mar 2020 15:56:47 +0100 Subject: [PATCH 2/5] minor: clean up unused member variable --- src/android/NativeGeocoder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/android/NativeGeocoder.java b/src/android/NativeGeocoder.java index 85717f3..9ec6a4d 100644 --- a/src/android/NativeGeocoder.java +++ b/src/android/NativeGeocoder.java @@ -18,7 +18,6 @@ public class NativeGeocoder extends CordovaPlugin { - private Geocoder geocoder; @Override public void initialize(CordovaInterface cordova, CordovaWebView webView) { From e56c1a5ca47c7bb9524a61f71b62bfdde3e2662b Mon Sep 17 00:00:00 2001 From: David Boho Date: Wed, 11 Mar 2020 16:19:12 +0100 Subject: [PATCH 3/5] minor: add docs --- src/android/GeocodingIntentService.java | 29 +++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/android/GeocodingIntentService.java b/src/android/GeocodingIntentService.java index 51fee24..949729a 100644 --- a/src/android/GeocodingIntentService.java +++ b/src/android/GeocodingIntentService.java @@ -51,7 +51,7 @@ protected void onHandleIntent(Intent intent) { try { if (location != null) { - backwardGeocode(mReceiver, location, geocoderOptions); + reverseGeocode(mReceiver, location, geocoderOptions); } else { forwardGeocode(mReceiver, addressString, geocoderOptions); } @@ -64,7 +64,13 @@ protected void onHandleIntent(Intent intent) { } } - private void backwardGeocode(ResultReceiver mReceiver, Location location, NativeGeocoderOptions geocoderOptions) throws IOException { + /** + * Reverse geocode a given location to find location address + * @param mReceiver ResultReceiver + * @param location Location + * @param geocoderOptions NativeGeocoderOptions + */ + private void reverseGeocode(ResultReceiver mReceiver, Location location, NativeGeocoderOptions geocoderOptions) throws IOException { Geocoder geocoder = createGeocoderWithOptions(geocoderOptions); List
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), geocoderOptions.maxResults); @@ -76,6 +82,12 @@ private void backwardGeocode(ResultReceiver mReceiver, Location location, Native } } + /** + * Forward geocode a given address to find coordinates + * @param mReceiver ResultReceiver + * @param addressString String + * @param geocoderOptions NativeGeocoderOptions + */ private void forwardGeocode(ResultReceiver mReceiver, String addressString, NativeGeocoderOptions geocoderOptions) throws IOException { Geocoder geocoder = createGeocoderWithOptions(geocoderOptions); List
addresses = geocoder.getFromLocationName(addressString, geocoderOptions.maxResults); @@ -91,12 +103,25 @@ private void forwardGeocode(ResultReceiver mReceiver, String addressString, Nati } } + /** + * Send the decoding result back to the receiver + * @param mReceiver ResultReceiver + * @param resultCode int + * @param message String + */ private void deliverResultToReceiver(ResultReceiver mReceiver, int resultCode, String message) { Bundle bundle = new Bundle(); bundle.putString(RESULT_DATA_KEY, message); mReceiver.send(resultCode, bundle); } + /** + * Convert a list of addresses to a JSONArray + * @param addresses List
+ * @param maxResults int + * @param skipEmptyLocationResults boolean + * @return JSONArray + */ private JSONArray addressesToJSONArray(List
addresses, int maxResults, boolean skipEmptyLocationResults) { JSONArray resultArray = new JSONArray(); int maxResultObjects = addresses.size() >= maxResults ? maxResults : addresses.size(); From f91ec48bf179fd5381b2f8545122fe99fa532b4b Mon Sep 17 00:00:00 2001 From: David Boho Date: Fri, 20 Mar 2020 16:09:44 +0100 Subject: [PATCH 4/5] fix service path in plugin.xml --- plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.xml b/plugin.xml index 87ff71e..0bf381d 100644 --- a/plugin.xml +++ b/plugin.xml @@ -24,7 +24,7 @@ From 19ebb5020f63ce4478c2de22efbf1774753e4a18 Mon Sep 17 00:00:00 2001 From: Sebastian Baar Date: Wed, 25 Mar 2020 09:15:36 +0100 Subject: [PATCH 5/5] some fixes, remove dependency & version update --- CHANGELOG.md | 8 ++++++++ README.md | 2 +- package.json | 2 +- plugin.xml | 5 +---- src/android/GeocodingIntentService.java | 10 +++------- src/android/NativeGeocoder.java | 6 +++--- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e44b00a..e987f0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 3.3.0 (2020-03-25) + +- merge PR #54 "move Geocoding in an IntentService to not block the main thread" (closes #47, thank you @DavidWiesner) + +## ** BREAKING CHANGES ** +- remove dependency [Swift support plugin](https://github.com/akofman/cordova-plugin-add-swift-support); min Cordova iOS Version is now >5.0.0 + + # 3.2.2 (2019-04-14) - update cordova-plugin-add-swift-support to 2.0.2 (closes #45, thank you @DavidWiesner) diff --git a/README.md b/README.md index 8aa61fe..b77ee95 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This plugin is also available for **[Ionic Native](https://ionicframework.com/do ``` cordova plugin add cordova-plugin-nativegeocoder ``` -The iOS part is written in Swift and the [Swift support plugin](https://github.com/akofman/cordova-plugin-add-swift-support) is configured as a dependency. +**For iOS Cordova iOS version >5.0.0 is required.** ## Configuration You can also configure the following variable to customize the iOS location plist entry diff --git a/package.json b/package.json index c2e09e4..61c3287 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-nativegeocoder", - "version": "3.2.2", + "version": "3.3.0", "description": "Cordova plugin for native forward and reverse geocoding", "cordova": { "id": "cordova-plugin-nativegeocoder", diff --git a/plugin.xml b/plugin.xml index 0bf381d..3f0b045 100644 --- a/plugin.xml +++ b/plugin.xml @@ -1,5 +1,5 @@ - + NativeGeocoder Cordova plugin for native forward and reverse geocoding MIT @@ -51,8 +51,5 @@ $LOCATION_WHEN_IN_USE_DESCRIPTION - - - diff --git a/src/android/GeocodingIntentService.java b/src/android/GeocodingIntentService.java index 949729a..5e2568f 100644 --- a/src/android/GeocodingIntentService.java +++ b/src/android/GeocodingIntentService.java @@ -124,7 +124,7 @@ private void deliverResultToReceiver(ResultReceiver mReceiver, int resultCode, S */ private JSONArray addressesToJSONArray(List
addresses, int maxResults, boolean skipEmptyLocationResults) { JSONArray resultArray = new JSONArray(); - int maxResultObjects = addresses.size() >= maxResults ? maxResults : addresses.size(); + int maxResultObjects = Math.min(addresses.size(), maxResults); for (int i = 0; i < maxResultObjects; i++) { Address address = addresses.get(i); @@ -152,9 +152,7 @@ private JSONArray addressesToJSONArray(List
addresses, int maxResults, resultArray.put(placemark); } - } catch (JSONException e) { - e.printStackTrace(); - } catch (RuntimeException e) { + } catch (JSONException | RuntimeException e) { e.printStackTrace(); } } @@ -184,7 +182,7 @@ private NativeGeocoderOptions getNativeGeocoderOptions(String stringOptions) { if (geocoderOptions.maxResults > 0) { int MAX_RESULTS_COUNT = 5; - geocoderOptions.maxResults = geocoderOptions.maxResults > MAX_RESULTS_COUNT ? MAX_RESULTS_COUNT : geocoderOptions.maxResults; + geocoderOptions.maxResults = Math.min(geocoderOptions.maxResults, MAX_RESULTS_COUNT); } else { geocoderOptions.maxResults = 1; } @@ -230,7 +228,6 @@ else if (parts.length == 2 || (parts.length == 3 && parts[2].startsWith("#"))) } } - /** * Get network connection * @@ -245,5 +242,4 @@ private boolean isNetworkAvailable() { return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } - } diff --git a/src/android/NativeGeocoder.java b/src/android/NativeGeocoder.java index 9ec6a4d..53958b0 100644 --- a/src/android/NativeGeocoder.java +++ b/src/android/NativeGeocoder.java @@ -34,7 +34,7 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo JSONObject options = null; try { options = args.getJSONObject(2); - } catch (JSONException e) { } + } catch (JSONException ignored) { } this.reverseGeocode(latitude, longitude, options, callbackContext); @@ -49,7 +49,7 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo JSONObject options = null; try { options = args.getJSONObject(1); - } catch (JSONException e) { } + } catch (JSONException ignored) { } this.forwardGeocode(addressString, options, callbackContext); PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT); @@ -123,7 +123,7 @@ static class AddressResultReceiver extends ResultReceiver { private final CallbackContext callbackContext; - public AddressResultReceiver(CallbackContext callbackContext) { + AddressResultReceiver(CallbackContext callbackContext) { super(new Handler()); this.callbackContext = callbackContext; }