[google_maps_flutter] Add support to request map renderer for Android (#6619)
* [google_maps_flutter] support to request a specific map renderer for android
* [google_maps_flutter] Minor fixes to comments and error messages
* [google_maps_flutter] fix linting issues
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md
index 012a508..ac94475 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md
+++ b/packages/google_maps_flutter/google_maps_flutter_android/CHANGELOG.md
@@ -1,5 +1,6 @@
-## NEXT
+## 2.4.0
+* Adds the ability to request a specific map renderer.
* Updates code for new analysis options.
## 2.3.3
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/README.md b/packages/google_maps_flutter/google_maps_flutter_android/README.md
index 877b9bb..e07b0bc 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/README.md
+++ b/packages/google_maps_flutter/google_maps_flutter_android/README.md
@@ -48,7 +48,30 @@
This mode will likely become the default in future versions if/when the
missed updates issue can be resolved.
+## Map renderer
+
+This plugin supports the option to request a specific [map renderer][5].
+
+The renderer must be requested before creating GoogleMap instances, as the renderer can be initialized only once per application context.
+
+<?code-excerpt "readme_excerpts.dart (MapRenderer)"?>
+```dart
+AndroidMapRenderer mapRenderer = AndroidMapRenderer.platformDefault;
+// ···
+ final GoogleMapsFlutterPlatform mapsImplementation =
+ GoogleMapsFlutterPlatform.instance;
+ if (mapsImplementation is GoogleMapsFlutterAndroid) {
+ WidgetsFlutterBinding.ensureInitialized();
+ mapRenderer = await mapsImplementation
+ .initializeWithRenderer(AndroidMapRenderer.latest);
+ }
+```
+
+Available values are `AndroidMapRenderer.latest`, `AndroidMapRenderer.legacy`, `AndroidMapRenderer.platformDefault`.
+Note that getting the requested renderer as a response is not guaranteed.
+
[1]: https://pub.dev/packages/google_maps_flutter
[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
[3]: https://docs.flutter.dev/development/platform-integration/android/platform-views
[4]: https://github.com/flutter/flutter/issues/103686
+[5]: https://developers.google.com/maps/documentation/android-sdk/renderer
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java
index ca9ac18..ffa2412 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapFactory.java
@@ -17,11 +17,15 @@
private final BinaryMessenger binaryMessenger;
private final LifecycleProvider lifecycleProvider;
+ private final GoogleMapInitializer googleMapInitializer;
- GoogleMapFactory(BinaryMessenger binaryMessenger, LifecycleProvider lifecycleProvider) {
+ GoogleMapFactory(
+ BinaryMessenger binaryMessenger, Context context, LifecycleProvider lifecycleProvider) {
super(StandardMessageCodec.INSTANCE);
+
this.binaryMessenger = binaryMessenger;
this.lifecycleProvider = lifecycleProvider;
+ this.googleMapInitializer = new GoogleMapInitializer(context, binaryMessenger);
}
@SuppressWarnings("unchecked")
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java
new file mode 100644
index 0000000..a113c0a
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapInitializer.java
@@ -0,0 +1,109 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.googlemaps;
+
+import android.content.Context;
+import androidx.annotation.VisibleForTesting;
+import com.google.android.gms.maps.MapsInitializer;
+import com.google.android.gms.maps.MapsInitializer.Renderer;
+import com.google.android.gms.maps.OnMapsSdkInitializedCallback;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+
+/** GoogleMaps initializer used to initialize the Google Maps SDK with preferred settings. */
+final class GoogleMapInitializer
+ implements OnMapsSdkInitializedCallback, MethodChannel.MethodCallHandler {
+ private final MethodChannel methodChannel;
+ private final Context context;
+ private static MethodChannel.Result initializationResult;
+ private boolean rendererInitialized = false;
+
+ GoogleMapInitializer(Context context, BinaryMessenger binaryMessenger) {
+ this.context = context;
+
+ methodChannel =
+ new MethodChannel(binaryMessenger, "plugins.flutter.dev/google_maps_android_initializer");
+ methodChannel.setMethodCallHandler(this);
+ }
+
+ @Override
+ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
+ switch (call.method) {
+ case "initializer#preferRenderer":
+ {
+ String preferredRenderer = (String) call.argument("value");
+ initializeWithPreferredRenderer(preferredRenderer, result);
+ break;
+ }
+ default:
+ result.notImplemented();
+ }
+ }
+
+ /**
+ * Initializes map renderer to with preferred renderer type. Renderer can be initialized only once
+ * per application context.
+ *
+ * <p>Supported renderer types are "latest", "legacy" and "default".
+ */
+ private void initializeWithPreferredRenderer(
+ String preferredRenderer, MethodChannel.Result result) {
+ if (rendererInitialized || initializationResult != null) {
+ result.error(
+ "Renderer already initialized", "Renderer initialization called multiple times", null);
+ } else {
+ initializationResult = result;
+ switch (preferredRenderer) {
+ case "latest":
+ initializeWithRendererRequest(Renderer.LATEST);
+ break;
+ case "legacy":
+ initializeWithRendererRequest(Renderer.LEGACY);
+ break;
+ case "default":
+ initializeWithRendererRequest(null);
+ break;
+ default:
+ initializationResult.error(
+ "Invalid renderer type",
+ "Renderer initialization called with invalid renderer type",
+ null);
+ initializationResult = null;
+ }
+ }
+ }
+
+ /**
+ * Initializes map renderer to with preferred renderer type.
+ *
+ * <p>This method is visible for testing purposes only and should never be used outside this
+ * class.
+ */
+ @VisibleForTesting
+ public void initializeWithRendererRequest(MapsInitializer.Renderer renderer) {
+ MapsInitializer.initialize(context, renderer, this);
+ }
+
+ /** Is called by Google Maps SDK to determine which version of the renderer was initialized. */
+ @Override
+ public void onMapsSdkInitialized(MapsInitializer.Renderer renderer) {
+ rendererInitialized = true;
+ if (initializationResult != null) {
+ switch (renderer) {
+ case LATEST:
+ initializationResult.success("latest");
+ break;
+ case LEGACY:
+ initializationResult.success("legacy");
+ break;
+ default:
+ initializationResult.error(
+ "Unknown renderer type", "Initialized with unknown renderer type", null);
+ }
+ initializationResult = null;
+ }
+ }
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java
index 715b357..20fc15e 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/main/java/io/flutter/plugins/googlemaps/GoogleMapsPlugin.java
@@ -46,6 +46,7 @@
VIEW_TYPE,
new GoogleMapFactory(
registrar.messenger(),
+ registrar.context(),
new LifecycleProvider() {
@Override
public Lifecycle getLifecycle() {
@@ -57,7 +58,10 @@
.platformViewRegistry()
.registerViewFactory(
VIEW_TYPE,
- new GoogleMapFactory(registrar.messenger(), new ProxyLifecycleProvider(activity)));
+ new GoogleMapFactory(
+ registrar.messenger(),
+ registrar.context(),
+ new ProxyLifecycleProvider(activity)));
}
}
@@ -73,6 +77,7 @@
VIEW_TYPE,
new GoogleMapFactory(
binding.getBinaryMessenger(),
+ binding.getApplicationContext(),
new LifecycleProvider() {
@Nullable
@Override
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java
new file mode 100644
index 0000000..2f9f5e5
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter_android/android/src/test/java/io/flutter/plugins/googlemaps/GoogleMapInitializerTest.java
@@ -0,0 +1,98 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package io.flutter.plugins.googlemaps;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.Build;
+import androidx.test.core.app.ApplicationProvider;
+import com.google.android.gms.maps.MapsInitializer.Renderer;
+import io.flutter.plugin.common.BinaryMessenger;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import java.util.HashMap;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(sdk = Build.VERSION_CODES.P)
+public class GoogleMapInitializerTest {
+ private GoogleMapInitializer googleMapInitializer;
+
+ @Mock BinaryMessenger mockMessenger;
+
+ @Before
+ public void before() {
+ MockitoAnnotations.openMocks(this);
+ Context context = ApplicationProvider.getApplicationContext();
+ googleMapInitializer = spy(new GoogleMapInitializer(context, mockMessenger));
+ }
+
+ @Test
+ public void initializer_OnMapsSdkInitializedWithLatestRenderer() {
+ doNothing().when(googleMapInitializer).initializeWithRendererRequest(Renderer.LATEST);
+ MethodChannel.Result result = mock(MethodChannel.Result.class);
+ googleMapInitializer.onMethodCall(
+ new MethodCall(
+ "initializer#preferRenderer",
+ new HashMap<String, Object>() {
+ {
+ put("value", "latest");
+ }
+ }),
+ result);
+ googleMapInitializer.onMapsSdkInitialized(Renderer.LATEST);
+ verify(result, times(1)).success("latest");
+ verify(result, never()).error(any(), any(), any());
+ }
+
+ @Test
+ public void initializer_OnMapsSdkInitializedWithLegacyRenderer() {
+ doNothing().when(googleMapInitializer).initializeWithRendererRequest(Renderer.LEGACY);
+ MethodChannel.Result result = mock(MethodChannel.Result.class);
+ googleMapInitializer.onMethodCall(
+ new MethodCall(
+ "initializer#preferRenderer",
+ new HashMap<String, Object>() {
+ {
+ put("value", "legacy");
+ }
+ }),
+ result);
+ googleMapInitializer.onMapsSdkInitialized(Renderer.LEGACY);
+ verify(result, times(1)).success("legacy");
+ verify(result, never()).error(any(), any(), any());
+ }
+
+ @Test
+ public void initializer_onMethodCallWithUnknownRenderer() {
+ doNothing().when(googleMapInitializer).initializeWithRendererRequest(Renderer.LEGACY);
+ MethodChannel.Result result = mock(MethodChannel.Result.class);
+ googleMapInitializer.onMethodCall(
+ new MethodCall(
+ "initializer#preferRenderer",
+ new HashMap<String, Object>() {
+ {
+ put("value", "wrong_renderer");
+ }
+ }),
+ result);
+ verify(result, never()).success(any());
+ verify(result, times(1)).error(eq("Invalid renderer type"), any(), any());
+ }
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart
similarity index 99%
rename from packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart
rename to packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart
index 0945740..bd72b7b 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_test.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/google_maps_tests.dart
@@ -12,15 +12,13 @@
import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
import 'package:google_maps_flutter_example/example_google_map.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
-import 'package:integration_test/integration_test.dart';
const LatLng _kInitialMapCenter = LatLng(0, 0);
const double _kInitialZoomLevel = 5;
const CameraPosition _kInitialCameraPosition =
CameraPosition(target: _kInitialMapCenter, zoom: _kInitialZoomLevel);
-void main() {
- IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+void googleMapsTests() {
GoogleMapsFlutterPlatform.instance.enableDebugInspection();
// Repeatedly checks an asynchronous value against a test condition, waiting
@@ -511,7 +509,9 @@
await waitForValueMatchingPredicate<LatLngBounds>(
tester,
() => mapController.getVisibleRegion(),
- (LatLngBounds bounds) => bounds != zeroLatLngBounds) ??
+ (LatLngBounds bounds) =>
+ bounds != zeroLatLngBounds &&
+ bounds.northeast != bounds.southwest) ??
zeroLatLngBounds;
expect(firstVisibleRegion, isNot(zeroLatLngBounds));
expect(firstVisibleRegion.contains(_kInitialMapCenter), isTrue);
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/latest_renderer_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/latest_renderer_test.dart
new file mode 100644
index 0000000..64bff8f
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/latest_renderer_test.dart
@@ -0,0 +1,40 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
+import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
+import 'package:integration_test/integration_test.dart';
+
+import 'google_maps_tests.dart' show googleMapsTests;
+
+void main() {
+ late AndroidMapRenderer initializedRenderer;
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+ setUpAll(() async {
+ final GoogleMapsFlutterAndroid instance =
+ GoogleMapsFlutterPlatform.instance as GoogleMapsFlutterAndroid;
+ initializedRenderer =
+ await instance.initializeWithRenderer(AndroidMapRenderer.latest);
+ });
+
+ testWidgets('initialized with latest renderer', (WidgetTester _) async {
+ expect(initializedRenderer, AndroidMapRenderer.latest);
+ });
+
+ testWidgets('throws PlatformException on multiple renderer initializations',
+ (WidgetTester _) async {
+ final GoogleMapsFlutterAndroid instance =
+ GoogleMapsFlutterPlatform.instance as GoogleMapsFlutterAndroid;
+ expect(
+ () async => instance.initializeWithRenderer(AndroidMapRenderer.latest),
+ throwsA(isA<PlatformException>().having((PlatformException e) => e.code,
+ 'code', 'Renderer already initialized')));
+ });
+
+ // Run tests.
+ googleMapsTests();
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/legacy_renderer_test.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/legacy_renderer_test.dart
new file mode 100644
index 0000000..95b1134
--- /dev/null
+++ b/packages/google_maps_flutter/google_maps_flutter_android/example/integration_test/legacy_renderer_test.dart
@@ -0,0 +1,40 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
+import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
+import 'package:integration_test/integration_test.dart';
+
+import 'google_maps_tests.dart' show googleMapsTests;
+
+void main() {
+ late AndroidMapRenderer initializedRenderer;
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+
+ setUpAll(() async {
+ final GoogleMapsFlutterAndroid instance =
+ GoogleMapsFlutterPlatform.instance as GoogleMapsFlutterAndroid;
+ initializedRenderer =
+ await instance.initializeWithRenderer(AndroidMapRenderer.legacy);
+ });
+
+ testWidgets('initialized with legacy renderer', (WidgetTester _) async {
+ expect(initializedRenderer, AndroidMapRenderer.legacy);
+ });
+
+ testWidgets('throws PlatformException on multiple renderer initializations',
+ (WidgetTester _) async {
+ final GoogleMapsFlutterAndroid instance =
+ GoogleMapsFlutterPlatform.instance as GoogleMapsFlutterAndroid;
+ expect(
+ () async => instance.initializeWithRenderer(AndroidMapRenderer.legacy),
+ throwsA(isA<PlatformException>().having((PlatformException e) => e.code,
+ 'code', 'Renderer already initialized')));
+ });
+
+ // Run tests.
+ googleMapsTests();
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/readme_excerpts.dart b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/readme_excerpts.dart
index 5911c06..0f6b26d 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/example/lib/readme_excerpts.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_android/example/lib/readme_excerpts.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// ignore_for_file: public_member_api_docs
+
import 'package:flutter/material.dart';
// #docregion DisplayMode
import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
@@ -15,7 +17,44 @@
mapsImplementation.useAndroidViewSurface = true;
}
// #enddocregion DisplayMode
- runApp(const MaterialApp());
+ runApp(const MyApp());
// #docregion DisplayMode
}
// #enddocregion DisplayMode
+
+class MyApp extends StatefulWidget {
+ const MyApp({Key? key}) : super(key: key);
+
+ @override
+ State<MyApp> createState() => _MyAppState();
+}
+
+class _MyAppState extends State<MyApp> {
+ // #docregion MapRenderer
+ AndroidMapRenderer mapRenderer = AndroidMapRenderer.platformDefault;
+ // #enddocregion MapRenderer
+
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ home: Scaffold(
+ appBar: AppBar(
+ title: const Text('README snippet app'),
+ ),
+ body: const Text('See example in main.dart'),
+ ),
+ );
+ }
+
+ Future<void> initializeLatestMapRenderer() async {
+ // #docregion MapRenderer
+ final GoogleMapsFlutterPlatform mapsImplementation =
+ GoogleMapsFlutterPlatform.instance;
+ if (mapsImplementation is GoogleMapsFlutterAndroid) {
+ WidgetsFlutterBinding.ensureInitialized();
+ mapRenderer = await mapsImplementation
+ .initializeWithRenderer(AndroidMapRenderer.latest);
+ }
+ // #enddocregion MapRenderer
+ }
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart
index 06c5bdc..11af3fe 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart
+++ b/packages/google_maps_flutter/google_maps_flutter_android/lib/src/google_maps_flutter_android.dart
@@ -41,6 +41,19 @@
}
}
+/// The possible android map renderer types that can be
+/// requested from the native Google Maps SDK.
+enum AndroidMapRenderer {
+ /// Latest renderer type.
+ latest,
+
+ /// Legacy renderer type.
+ legacy,
+
+ /// Requests the default map renderer type.
+ platformDefault,
+}
+
/// An implementation of [GoogleMapsFlutterPlatform] for Android.
class GoogleMapsFlutterAndroid extends GoogleMapsFlutterPlatform {
/// Registers the Android implementation of GoogleMapsFlutterPlatform.
@@ -48,6 +61,10 @@
GoogleMapsFlutterPlatform.instance = GoogleMapsFlutterAndroid();
}
+ /// The method channel used to initialize the native Google Maps SDK.
+ final MethodChannel _initializerChannel = const MethodChannel(
+ 'plugins.flutter.dev/google_maps_android_initializer');
+
// Keep a collection of id -> channel
// Every method call passes the int mapId
final Map<int, MethodChannel> _channels = <int, MethodChannel>{};
@@ -480,6 +497,52 @@
/// Currently defaults to true, but the default is subject to change.
bool useAndroidViewSurface = true;
+ /// Requests Google Map Renderer with [AndroidMapRenderer] type.
+ ///
+ /// See https://pub.dev/packages/google_maps_flutter_android#map-renderer
+ /// for more information.
+ ///
+ /// The renderer must be requested before creating GoogleMap instances as the
+ /// renderer can be initialized only once per application context.
+ /// Throws a [PlatformException] if method is called multiple times.
+ ///
+ /// The returned [Future] completes after renderer has been initialized.
+ /// Initialized [AndroidMapRenderer] type is returned.
+ Future<AndroidMapRenderer> initializeWithRenderer(
+ AndroidMapRenderer? rendererType) async {
+ String preferredRenderer;
+ switch (rendererType) {
+ case AndroidMapRenderer.latest:
+ preferredRenderer = 'latest';
+ break;
+ case AndroidMapRenderer.legacy:
+ preferredRenderer = 'legacy';
+ break;
+ case AndroidMapRenderer.platformDefault:
+ default:
+ preferredRenderer = 'default';
+ }
+
+ final String? initializedRenderer = await _initializerChannel
+ .invokeMethod<String>('initializer#preferRenderer',
+ <String, dynamic>{'value': preferredRenderer});
+
+ if (initializedRenderer == null) {
+ throw AndroidMapRendererException('Failed to initialize map renderer.');
+ }
+
+ // Returns mapped [AndroidMapRenderer] enum type.
+ switch (initializedRenderer) {
+ case 'latest':
+ return AndroidMapRenderer.latest;
+ case 'legacy':
+ return AndroidMapRenderer.legacy;
+ default:
+ throw AndroidMapRendererException(
+ 'Failed to initialize latest or legacy renderer, got $initializedRenderer.');
+ }
+ }
+
Widget _buildView(
int creationId,
PlatformViewCreatedCallback onPlatformViewCreated, {
@@ -689,3 +752,16 @@
/// Set of TileOverlays to be changed in this update.
Set<TileOverlay> get tileOverlaysToChange => objectsToChange;
}
+
+/// Thrown to indicate that a platform interaction failed to initialize renderer.
+class AndroidMapRendererException implements Exception {
+ /// Creates a [AndroidMapRendererException] with an optional human-readable
+ /// error message.
+ AndroidMapRendererException([this.message]);
+
+ /// A human-readable error message, possibly null.
+ final String? message;
+
+ @override
+ String toString() => 'AndroidMapRendererException($message)';
+}
diff --git a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml
index d20322b..bdf2f41 100644
--- a/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml
+++ b/packages/google_maps_flutter/google_maps_flutter_android/pubspec.yaml
@@ -2,7 +2,7 @@
description: Android implementation of the google_maps_flutter plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/google_maps_flutter/google_maps_flutter_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
-version: 2.3.3
+version: 2.4.0
environment:
sdk: ">=2.14.0 <3.0.0"