diff --git a/geocoding_android/CHANGELOG.md b/geocoding_android/CHANGELOG.md index aab699a..0591170 100644 --- a/geocoding_android/CHANGELOG.md +++ b/geocoding_android/CHANGELOG.md @@ -1,3 +1,11 @@ +## 3.0.0 + +* **BREAKING CHANGES**: + * Updates `geocoding_platform_interface` to version 3.1.0. + * Adds method `setLocaleIdentifier` to set the locale for all calls to the geocoding platform. + * Removes the `localeIdentifier` argument from all methods. Use method `setLocaleIdentifier` to configure the locale. +* Implements `placemarkFromAddress`. + ## 2.1.2 * Downgrades Android Gradle plugin to version 7.3.1 so the project is inline with current Flutter stable (version 3.10.5). diff --git a/geocoding_android/android/src/main/java/com/baseflow/geocoding/Geocoding.java b/geocoding_android/android/src/main/java/com/baseflow/geocoding/Geocoding.java index 16ffd1b..cf3d0a9 100644 --- a/geocoding_android/android/src/main/java/com/baseflow/geocoding/Geocoding.java +++ b/geocoding_android/android/src/main/java/com/baseflow/geocoding/Geocoding.java @@ -12,6 +12,7 @@ /** Geocoding components to lookup address or coordinates. */ class Geocoding { private final Context androidContext; + @Nullable private Locale locale; /** * Uses the given {@code androidContext} to execute geocoding features @@ -22,15 +23,18 @@ class Geocoding { this.androidContext = androidContext; } + void setLocaleIdentifier(@Nullable Locale locale) { + this.locale = locale; + } + /** * Returns a list of Address objects matching the supplied address string. * * @param address the address string for the search - * @param locale the desired Locale for the query results * @return a list of Address objects. Returns null or empty list if no matches were found or there is no backend service available. * @throws java.io.IOException if the network is unavailable or any other I/O problem occurs. */ - List
placemarkFromAddress(String address, Locale locale) throws IOException { + List
placemarkFromAddress(String address) throws IOException { final Geocoder geocoder = createGeocoder(androidContext, locale); return geocoder.getFromLocationName(address, 5); @@ -41,15 +45,13 @@ List
placemarkFromAddress(String address, Locale locale) throws IOExcep * * @param latitude the latitude point for the search * @param longitude the longitude point for the search - * @param locale the desired Locale for the query results * @return a list of Address objects. Returns null or empty list if no matches were found or there is no backend service available. * @throws IOException if the network is unavailable or any other I/O problem occurs. */ List
placemarkFromCoordinates( double latitude, - double longitude, - Locale locale) throws IOException { - + double longitude + ) throws IOException { final Geocoder geocoder = createGeocoder(androidContext, locale); return geocoder.getFromLocation(latitude, longitude, 5); } diff --git a/geocoding_android/android/src/main/java/com/baseflow/geocoding/MethodCallHandlerImpl.java b/geocoding_android/android/src/main/java/com/baseflow/geocoding/MethodCallHandlerImpl.java index 5d55185..7a48ad9 100644 --- a/geocoding_android/android/src/main/java/com/baseflow/geocoding/MethodCallHandlerImpl.java +++ b/geocoding_android/android/src/main/java/com/baseflow/geocoding/MethodCallHandlerImpl.java @@ -3,6 +3,7 @@ import android.location.Address; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.baseflow.geocoding.utils.AddressMapper; @@ -10,6 +11,7 @@ import java.io.IOException; import java.util.List; +import java.util.Locale; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.MethodCall; @@ -36,11 +38,20 @@ final class MethodCallHandlerImpl implements MethodCallHandler { } @Override - public void onMethodCall(final MethodCall call, final Result result) { + public void onMethodCall( + final MethodCall call, + @NonNull final Result result + ) { switch (call.method) { + case "setLocaleIdentifier": + setLocaleIdentifier(call, result); + break; case "locationFromAddress": onLocationFromAddress(call, result); break; + case "placemarkFromAddress": + onPlacemarkFromAddress(call, result); + break; case "placemarkFromCoordinates": onPlacemarkFromCoordinates(call, result); break; @@ -82,9 +93,16 @@ void stopListening() { channel = null; } + private void setLocaleIdentifier(MethodCall call, Result result) { + final String languageTag = call.argument("localeIdentifier"); + + geocoding.setLocaleIdentifier(LocaleConverter.fromLanguageTag(languageTag)); + + result.success(true); + } + private void onLocationFromAddress(MethodCall call, Result result) { final String address = call.argument("address"); - final String languageTag = call.argument("localeIdentifier"); if (address == null || address.isEmpty()) { result.error( @@ -94,9 +112,7 @@ private void onLocationFromAddress(MethodCall call, Result result) { } try { - final List
addresses = geocoding.placemarkFromAddress( - address, - LocaleConverter.fromLanguageTag(languageTag)); + final List
addresses = geocoding.placemarkFromAddress(address); if (addresses == null || addresses.isEmpty()) { result.error( @@ -110,26 +126,61 @@ private void onLocationFromAddress(MethodCall call, Result result) { } catch (IOException ex) { result.error( "IO_ERROR", - String.format("A network error occurred trying to lookup the address ''.", address), + String.format("A network error occurred trying to lookup the address '%s'.", address), null ); } } + private void onPlacemarkFromAddress(final MethodCall call, final Result result) { + final String address = call.argument("address"); + + if (address == null || address.isEmpty()) { + result.error( + "ARGUMENT_ERROR", + "Supply a valid value for the 'address' parameter.", + null); + } + + try { + final List
addresses = geocoding.placemarkFromAddress(address); + + if (addresses == null || addresses.isEmpty()) { + result.error( + "NOT_FOUND", + String.format("No coordinates found for '%s'", address), + null); + return; + } + + result.success(AddressMapper.toAddressHashMapList(addresses)); + } catch (IOException e) { + result.error( + "IO_ERROR", + String.format("A network error occurred trying to lookup the address '%s'.", address), + null + ); + } + } + private void onPlacemarkFromCoordinates(final MethodCall call, final Result result) { final double latitude = call.argument("latitude"); final double longitude = call.argument("longitude"); - final String languageTag = call.argument("localeIdentifier"); try { final List
addresses = geocoding.placemarkFromCoordinates( latitude, - longitude, - LocaleConverter.fromLanguageTag(languageTag)); + longitude); + if (addresses == null || addresses.isEmpty()) { result.error( "NOT_FOUND", - String.format("No address information found for supplied coordinates (latitude: %f, longitude: %f).", latitude, longitude), + String.format( + Locale.ENGLISH, + "No address information found for supplied coordinates (latitude: %f, longitude: %f).", + latitude, + longitude + ), null); return; } @@ -137,7 +188,12 @@ private void onPlacemarkFromCoordinates(final MethodCall call, final Result resu } catch (IOException ex) { result.error( "IO_ERROR", - String.format("A network error occurred trying to lookup the supplied coordinates (latitude: %f, longitude: %f).", latitude, longitude), + String.format( + Locale.ENGLISH, + "A network error occurred trying to lookup the supplied coordinates (latitude: %f, longitude: %f).", + latitude, + longitude + ), null ); } diff --git a/geocoding_android/example/lib/plugin_example/geocode_page.dart b/geocoding_android/example/lib/plugin_example/geocode_page.dart index 461cd1a..504bc0a 100644 --- a/geocoding_android/example/lib/plugin_example/geocode_page.dart +++ b/geocoding_android/example/lib/plugin_example/geocode_page.dart @@ -103,6 +103,39 @@ class _GeocodeWidgetState extends State { const Padding( padding: EdgeInsets.only(top: 8), ), + Center( + child: ElevatedButton( + child: Text('Look up address'), + onPressed: () { + GeocodingAndroid() + .placemarkFromAddress(_addressController.text) + .then((locations) { + var output = 'No results found.'; + if (locations.isNotEmpty) { + output = locations[0].toString(); + } + + setState(() { + _output = output; + }); + }); + }), + ), + const Padding( + padding: EdgeInsets.only(top: 32), + ), + TextField( + autocorrect: false, + controller: _addressController, + style: Theme.of(context).textTheme.bodyMedium, + decoration: InputDecoration( + hintText: 'Address', + ), + keyboardType: TextInputType.text, + ), + const Padding( + padding: EdgeInsets.only(top: 8), + ), Center( child: ElevatedButton( child: Text('Look up location'), diff --git a/geocoding_android/example/pubspec.yaml b/geocoding_android/example/pubspec.yaml index b673e62..ad110b8 100644 --- a/geocoding_android/example/pubspec.yaml +++ b/geocoding_android/example/pubspec.yaml @@ -19,7 +19,7 @@ dependencies: # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ - geocoding_platform_interface: ^2.0.0 + geocoding_platform_interface: ^3.1.0 # The following adds the Cupertino Icons font to your application. diff --git a/geocoding_android/lib/geocoding_android.dart b/geocoding_android/lib/geocoding_android.dart index e61a911..45797ce 100644 --- a/geocoding_android/lib/geocoding_android.dart +++ b/geocoding_android/lib/geocoding_android.dart @@ -12,18 +12,25 @@ class GeocodingAndroid extends GeocodingPlatform { GeocodingPlatform.instance = GeocodingAndroid(); } + @override + Future setLocaleIdentifier( + String localeIdentifier, + ) { + final parameters = { + 'localeIdentifier': localeIdentifier, + }; + + return _channel.invokeMethod('setLocaleIdentifier', parameters); + } + @override Future> locationFromAddress( - String address, { - String? localeIdentifier, - }) async { + String address, + ) async { final parameters = { 'address': address, }; - if (localeIdentifier != null) { - parameters['localeIdentifier'] = localeIdentifier; - } try { final placemarks = await _channel.invokeMethod( 'locationFromAddress', @@ -40,23 +47,39 @@ class GeocodingAndroid extends GeocodingPlatform { @override Future> placemarkFromCoordinates( double latitude, - double longitude, { - String? localeIdentifier, - }) async { + double longitude, + ) async { final parameters = { 'latitude': latitude, 'longitude': longitude, }; - if (localeIdentifier != null) { - parameters['localeIdentifier'] = localeIdentifier; - } - final placemarks = await _channel.invokeMethod('placemarkFromCoordinates', parameters); return Placemark.fromMaps(placemarks); } + @override + Future> placemarkFromAddress( + String address, + ) async { + final parameters = { + 'address': address, + }; + + try { + final placemarks = await _channel.invokeMethod( + 'placemarkFromAddress', + parameters, + ); + + return Placemark.fromMaps(placemarks); + } on PlatformException catch (e) { + _handlePlatformException(e); + rethrow; + } + } + void _handlePlatformException(PlatformException platformException) { switch (platformException.code) { case 'NOT_FOUND': diff --git a/geocoding_android/pubspec.yaml b/geocoding_android/pubspec.yaml index cc84a4c..f92114a 100644 --- a/geocoding_android/pubspec.yaml +++ b/geocoding_android/pubspec.yaml @@ -1,6 +1,6 @@ name: geocoding_android description: A Flutter Geocoding plugin which provides easy geocoding and reverse-geocoding features. -version: 2.1.2 +version: 3.0.0 repository: https://github.com/baseflow/flutter-geocoding/tree/main/geocoding_android issue_tracker: https://github.com/Baseflow/flutter-geocoding/issues @@ -12,7 +12,7 @@ dependencies: flutter: sdk: flutter - geocoding_platform_interface: ^2.0.0 + geocoding_platform_interface: ^3.1.0 dev_dependencies: flutter_test: diff --git a/geocoding_android/test/geocoding_test.dart b/geocoding_android/test/geocoding_test.dart index 07cc1e3..c4e16db 100644 --- a/geocoding_android/test/geocoding_test.dart +++ b/geocoding_android/test/geocoding_test.dart @@ -9,7 +9,7 @@ final mockLocation = Location( timestamp: DateTime.fromMillisecondsSinceEpoch(0).toUtc(), ); -final mockPlacemark = Placemark( +const mockPlacemark = Placemark( administrativeArea: 'Overijssel', country: 'Netherlands', isoCountryCode: 'NL',