Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[google_maps_flutter] supports v2 android embedding. #2488

Merged
merged 4 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/google_maps_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.5.22

* Support Android v2 embedding.
* Bump the min flutter version to `1.12.13+hotfix.5`.
* Fixes some e2e tests on Android.

## 0.5.21+17

* Fix Swift example in README.md.
Expand Down
29 changes: 3 additions & 26 deletions packages/google_maps_flutter/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,8 @@ android {

dependencies {
implementation 'com.google.android.gms:play-services-maps:17.0.0'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test:rules:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
}

// TODO(cyanglaz): Remove this hack once androidx.lifecycle is included on stable. https://github.com/flutter/flutter/issues/42348
afterEvaluate {
def containsEmbeddingDependencies = false
for (def configuration : configurations.all) {
for (def dependency : configuration.dependencies) {
if (dependency.group == 'io.flutter' &&
dependency.name.startsWith('flutter_embedding') &&
dependency.isTransitive())
{
containsEmbeddingDependencies = true
break
}
}
}
if (!containsEmbeddingDependencies) {
android {
dependencies {
def lifecycle_version = "1.1.1"
compileOnly "android.arch.lifecycle:runtime:$lifecycle_version"
compileOnly "android.arch.lifecycle:common:$lifecycle_version"
compileOnly "android.arch.lifecycle:common-java8:$lifecycle_version"
}
}
}
}
3 changes: 3 additions & 0 deletions packages/google_maps_flutter/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

package io.flutter.plugins.googlemaps;

import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
import androidx.lifecycle.Lifecycle;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLngBounds;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.PluginRegistry;
import java.util.concurrent.atomic.AtomicInteger;

Expand All @@ -27,9 +30,25 @@ class GoogleMapBuilder implements GoogleMapOptionsSink {
private Rect padding = new Rect(0, 0, 0, 0);

GoogleMapController build(
int id, Context context, AtomicInteger state, PluginRegistry.Registrar registrar) {
int id,
Context context,
AtomicInteger state,
BinaryMessenger binaryMessenger,
Application application,
Lifecycle lifecycle,
PluginRegistry.Registrar registrar,
int activityHashCode) {
final GoogleMapController controller =
new GoogleMapController(id, context, state, registrar, options);
new GoogleMapController(
id,
context,
state,
binaryMessenger,
application,
lifecycle,
registrar,
activityHashCode,
options);
controller.init();
controller.setMyLocationEnabled(myLocationEnabled);
controller.setMyLocationButtonEnabled(myLocationButtonEnabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
Expand All @@ -34,6 +38,8 @@
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.Polyline;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
Expand All @@ -48,6 +54,8 @@
/** Controller of a single GoogleMaps MapView instance. */
final class GoogleMapController
implements Application.ActivityLifecycleCallbacks,
DefaultLifecycleObserver,
ActivityPluginBinding.OnSaveInstanceStateListener,
GoogleMap.OnCameraIdleListener,
GoogleMap.OnCameraMoveListener,
GoogleMap.OnCameraMoveStartedListener,
Expand All @@ -68,7 +76,6 @@ final class GoogleMapController
private final int id;
private final AtomicInteger activityState;
private final MethodChannel methodChannel;
private final PluginRegistry.Registrar registrar;
private final MapView mapView;
private GoogleMap googleMap;
private boolean trackCameraPosition = false;
Expand All @@ -80,8 +87,13 @@ final class GoogleMapController
private boolean disposed = false;
private final float density;
private MethodChannel.Result mapReadyResult;
private final int registrarActivityHashCode;
private final int
activityHashCode; // Do not use directly, use getActivityHashCode() instead to get correct hashCode for both v1 and v2 embedding.
private final Lifecycle lifecycle;
private final Context context;
private final Application
mApplication; // Do not use direclty, use getApplication() instead to get correct application object for both v1 and v2 embedding.
private final PluginRegistry.Registrar registrar; // For v1 embedding only.
private final MarkersController markersController;
private final PolygonsController polygonsController;
private final PolylinesController polylinesController;
Expand All @@ -95,18 +107,23 @@ final class GoogleMapController
int id,
Context context,
AtomicInteger activityState,
BinaryMessenger binaryMessenger,
Application application,
Lifecycle lifecycle,
PluginRegistry.Registrar registrar,
int registrarActivityHashCode,
GoogleMapOptions options) {
this.id = id;
this.context = context;
this.activityState = activityState;
this.registrar = registrar;
this.mapView = new MapView(context, options);
this.density = context.getResources().getDisplayMetrics().density;
methodChannel =
new MethodChannel(registrar.messenger(), "plugins.flutter.io/google_maps_" + id);
methodChannel = new MethodChannel(binaryMessenger, "plugins.flutter.io/google_maps_" + id);
methodChannel.setMethodCallHandler(this);
this.registrarActivityHashCode = registrar.activity().hashCode();
mApplication = application;
this.lifecycle = lifecycle;
this.registrar = registrar;
this.activityHashCode = registrarActivityHashCode;
this.markersController = new MarkersController(methodChannel);
this.polygonsController = new PolygonsController(methodChannel);
this.polylinesController = new PolylinesController(methodChannel, density);
Expand Down Expand Up @@ -152,7 +169,11 @@ void init() {
throw new IllegalArgumentException(
"Cannot interpret " + activityState.get() + " as an activity state");
}
registrar.activity().getApplication().registerActivityLifecycleCallbacks(this);
if (lifecycle != null) {
lifecycle.addObserver(this);
} else {
getApplication().registerActivityLifecycleCallbacks(this);
}
mapView.getMapAsync(this);
}

Expand Down Expand Up @@ -368,6 +389,10 @@ public void onMethodCall(MethodCall call, MethodChannel.Result result) {
result.success(googleMap.isBuildingsEnabled());
break;
}
case "map#getZoomLevel":
{
result.success(googleMap.getCameraPosition().zoom);
}
case "map#setStyle":
{
String mapStyle = (String) call.arguments;
Expand Down Expand Up @@ -472,7 +497,7 @@ public void dispose() {
disposed = true;
methodChannel.setMethodCallHandler(null);
mapView.onDestroy();
registrar.activity().getApplication().unregisterActivityLifecycleCallbacks(this);
getApplication().unregisterActivityLifecycleCallbacks(this);
}

// @Override
Expand All @@ -489,62 +514,129 @@ public void onInputConnectionUnlocked() {
// TODO(mklim): Remove this empty override once https://github.com/flutter/flutter/issues/40126 is fixed in stable.
};

// Application.ActivityLifecycleCallbacks methods
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onCreate(savedInstanceState);
}

@Override
public void onActivityStarted(Activity activity) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onStart();
}

@Override
public void onActivityResumed(Activity activity) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onResume();
}

@Override
public void onActivityPaused(Activity activity) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onPause();
}

@Override
public void onActivityStopped(Activity activity) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onStop();
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onSaveInstanceState(outState);
}

@Override
public void onActivityDestroyed(Activity activity) {
if (disposed || activity.hashCode() != registrarActivityHashCode) {
if (disposed || activity.hashCode() != getActivityHashCode()) {
return;
}
mapView.onDestroy();
}

// DefaultLifecycleObserver and OnSaveInstanceStateListener

@Override
public void onCreate(@NonNull LifecycleOwner owner) {
if (disposed) {
return;
}
mapView.onCreate(null);
}

@Override
public void onStart(@NonNull LifecycleOwner owner) {
if (disposed) {
return;
}
mapView.onStart();
}

@Override
public void onResume(@NonNull LifecycleOwner owner) {
if (disposed) {
return;
}
mapView.onResume();
}

@Override
public void onPause(@NonNull LifecycleOwner owner) {
if (disposed) {
return;
}
mapView.onResume();
}

@Override
public void onStop(@NonNull LifecycleOwner owner) {
if (disposed) {
return;
}
mapView.onStop();
}

@Override
public void onDestroy(@NonNull LifecycleOwner owner) {
if (disposed) {
return;
}
mapView.onDestroy();
}

@Override
public void onRestoreInstanceState(Bundle bundle) {
if (disposed) {
return;
}
mapView.onCreate(bundle);
}

@Override
public void onSaveInstanceState(Bundle bundle) {
if (disposed) {
return;
}
mapView.onSaveInstanceState(bundle);
}

// GoogleMapOptionsSink methods

@Override
Expand Down Expand Up @@ -716,6 +808,22 @@ private int checkSelfPermission(String permission) {
permission, android.os.Process.myPid(), android.os.Process.myUid());
}

private int getActivityHashCode() {
if (registrar != null && registrar.activity() != null) {
return registrar.activity().hashCode();
} else {
return activityHashCode;
}
}

private Application getApplication() {
if (registrar != null && registrar.activity() != null) {
return registrar.activity().getApplication();
} else {
return mApplication;
}
}

public void setIndoorEnabled(boolean indoorEnabled) {
this.indoorEnabled = indoorEnabled;
}
Expand Down
Loading