Skip to content
Open
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
3 changes: 3 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ rootProject.allprojects {
apply plugin: 'com.android.library'

android {

namespace 'com.mapbox.mapboxgl'

compileSdkVersion 31
ndkVersion "20.1.5948944"

Expand Down
57 changes: 28 additions & 29 deletions android/src/main/java/com/mapbox/mapboxgl/GlobalMethodHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.mapbox.mapboxsdk.net.ConnectivityReceiver;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
Expand All @@ -24,33 +22,35 @@ class GlobalMethodHandler implements MethodChannel.MethodCallHandler {
private static final String TAG = GlobalMethodHandler.class.getSimpleName();
private static final String DATABASE_NAME = "mbgl-offline.db";
private static final int BUFFER_SIZE = 1024 * 2;

@NonNull private final Context context;
@NonNull private final BinaryMessenger messenger;
@Nullable private PluginRegistry.Registrar registrar;
@Nullable private FlutterPlugin.FlutterAssets flutterAssets;

GlobalMethodHandler(@NonNull PluginRegistry.Registrar registrar) {
this.registrar = registrar;
this.context = registrar.activeContext();
this.messenger = registrar.messenger();
}
@NonNull private final FlutterPlugin.FlutterAssets flutterAssets;

GlobalMethodHandler(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
this.context = binding.getApplicationContext();
this.flutterAssets = binding.getFlutterAssets();
this.messenger = binding.getBinaryMessenger();
}

// Optional convenience constructor if you want to wire it manually
GlobalMethodHandler(
@NonNull Context context,
@NonNull BinaryMessenger messenger,
@NonNull FlutterPlugin.FlutterAssets flutterAssets) {
this.context = context;
this.messenger = messenger;
this.flutterAssets = flutterAssets;
}

private static void copy(InputStream input, OutputStream output) throws IOException {
final byte[] buffer = new byte[BUFFER_SIZE];
final BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
final BufferedOutputStream out = new BufferedOutputStream(output, BUFFER_SIZE);
int count = 0;
int n = 0;
int n;
try {
while ((n = in.read(buffer, 0, BUFFER_SIZE)) != -1) {
out.write(buffer, 0, n);
count += n;
}
out.flush();
} finally {
Expand Down Expand Up @@ -78,49 +78,52 @@ public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
installOfflineMapTiles(tilesDb);
result.success(null);
break;

case "setOffline":
boolean offline = methodCall.argument("offline");
ConnectivityReceiver.instance(context).setConnected(offline ? false : null);
result.success(null);
break;

case "mergeOfflineRegions":
OfflineManagerUtils.mergeRegions(result, context, methodCall.argument("path"));
break;

case "setOfflineTileCountLimit":
OfflineManagerUtils.setOfflineTileCountLimit(
result, context, methodCall.<Number>argument("limit").longValue());
break;

case "setHttpHeaders":
Map<String, String> headers = (Map<String, String>) methodCall.argument("headers");
MapboxHttpRequestUtil.setHttpHeaders(headers, result);
break;

case "downloadOfflineRegion":
// Get args from caller
Map<String, Object> definitionMap = (Map<String, Object>) methodCall.argument("definition");
Map<String, Object> metadataMap = (Map<String, Object>) methodCall.argument("metadata");
String channelName = methodCall.argument("channelName");

// Prepare args
OfflineChannelHandlerImpl channelHandler =
new OfflineChannelHandlerImpl(messenger, channelName);

// Start downloading
OfflineManagerUtils.downloadRegion(
result, context, definitionMap, metadataMap, channelHandler);
OfflineManagerUtils.downloadRegion(result, context, definitionMap, metadataMap, channelHandler);
break;

case "getListOfRegions":
OfflineManagerUtils.regionsList(result, context);
break;

case "updateOfflineRegionMetadata":
// Get download region arguments from caller
Map<String, Object> metadata = (Map<String, Object>) methodCall.argument("metadata");
OfflineManagerUtils.updateRegionMetadata(
result, context, methodCall.<Number>argument("id").longValue(), metadata);
break;

case "deleteOfflineRegion":
OfflineManagerUtils.deleteRegion(
result, context, methodCall.<Number>argument("id").longValue());
OfflineManagerUtils.deleteRegion(result, context, methodCall.<Number>argument("id").longValue());
break;

default:
result.notImplemented();
break;
Expand All @@ -138,17 +141,13 @@ private void installOfflineMapTiles(String tilesDb) {
}

private InputStream openTilesDbFile(String tilesDb) throws IOException {
if (tilesDb == null) throw new IllegalArgumentException("tilesdb is null");

if (tilesDb.startsWith("/")) { // Absolute path.
return new FileInputStream(new File(tilesDb));
} else {
String assetKey;
if (registrar != null) {
assetKey = registrar.lookupKeyForAsset(tilesDb);
} else if (flutterAssets != null) {
assetKey = flutterAssets.getAssetFilePathByName(tilesDb);
} else {
throw new IllegalStateException();
}
// Flutter embedding v2 asset lookup
String assetKey = flutterAssets.getAssetFilePathByName(tilesDb);
return context.getAssets().open(assetKey);
}
}
Expand Down
138 changes: 13 additions & 125 deletions android/src/main/java/com/mapbox/mapboxgl/MapboxMapsPlugin.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
// Copyright 2018 The Chromium 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 com.mapbox.mapboxgl;

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.PluginRegistry.Registrar;

/**
* Plugin for controlling a set of MapboxMap views to be shown as overlays on top of the Flutter
Expand All @@ -28,28 +18,28 @@
public class MapboxMapsPlugin implements FlutterPlugin, ActivityAware {

private static final String VIEW_TYPE = "plugins.flutter.io/mapbox_gl";
private static final String CHANNEL_NAME = "plugins.flutter.io/mapbox_gl";

static FlutterAssets flutterAssets;
private Lifecycle lifecycle;

@Nullable private Lifecycle lifecycle;
@Nullable private MethodChannel methodChannel;

public MapboxMapsPlugin() {
// no-op
}

// New Plugin APIs

@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
flutterAssets = binding.getFlutterAssets();

MethodChannel methodChannel =
new MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/mapbox_gl");
methodChannel = new MethodChannel(binding.getBinaryMessenger(), CHANNEL_NAME);
methodChannel.setMethodCallHandler(new GlobalMethodHandler(binding));

binding
.getPlatformViewRegistry()
.registerViewFactory(
"plugins.flutter.io/mapbox_gl",
VIEW_TYPE,
new MapboxMapFactory(
binding.getBinaryMessenger(),
new LifecycleProvider() {
Expand All @@ -63,7 +53,11 @@ public Lifecycle getLifecycle() {

@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
// no-op
if (methodChannel != null) {
methodChannel.setMethodCallHandler(null);
methodChannel = null;
}
// flutterAssets is static; leave as-is or null it if you prefer.
}

@Override
Expand All @@ -86,111 +80,6 @@ public void onDetachedFromActivity() {
lifecycle = null;
}

// Old Plugin APIs

public static void registerWith(Registrar registrar) {
final Activity activity = registrar.activity();
if (activity == null) {
// When a background flutter view tries to register the plugin, the registrar has no activity.
// We stop the registration process as this plugin is foreground only.
return;
}
if (activity instanceof LifecycleOwner) {
registrar
.platformViewRegistry()
.registerViewFactory(
VIEW_TYPE,
new MapboxMapFactory(
registrar.messenger(),
new LifecycleProvider() {
@Override
public Lifecycle getLifecycle() {
return ((LifecycleOwner) activity).getLifecycle();
}
}));
} else {
registrar
.platformViewRegistry()
.registerViewFactory(
VIEW_TYPE,
new MapboxMapFactory(registrar.messenger(), new ProxyLifecycleProvider(activity)));
}

MethodChannel methodChannel =
new MethodChannel(registrar.messenger(), "plugins.flutter.io/mapbox_gl");
methodChannel.setMethodCallHandler(new GlobalMethodHandler(registrar));
}

private static final class ProxyLifecycleProvider
implements Application.ActivityLifecycleCallbacks, LifecycleOwner, LifecycleProvider {

private final LifecycleRegistry lifecycle = new LifecycleRegistry(this);
private final int registrarActivityHashCode;

private ProxyLifecycleProvider(Activity activity) {
this.registrarActivityHashCode = activity.hashCode();
activity.getApplication().registerActivityLifecycleCallbacks(this);
}

@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity.hashCode() != registrarActivityHashCode) {
return;
}
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

@Override
public void onActivityStarted(Activity activity) {
if (activity.hashCode() != registrarActivityHashCode) {
return;
}
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START);
}

@Override
public void onActivityResumed(Activity activity) {
if (activity.hashCode() != registrarActivityHashCode) {
return;
}
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}

@Override
public void onActivityPaused(Activity activity) {
if (activity.hashCode() != registrarActivityHashCode) {
return;
}
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}

@Override
public void onActivityStopped(Activity activity) {
if (activity.hashCode() != registrarActivityHashCode) {
return;
}
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}

@Override
public void onActivityDestroyed(Activity activity) {
if (activity.hashCode() != registrarActivityHashCode) {
return;
}
activity.getApplication().unregisterActivityLifecycleCallbacks(this);
lifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}

@NonNull
@Override
public Lifecycle getLifecycle() {
return lifecycle;
}
}

interface LifecycleProvider {
@Nullable
Lifecycle getLifecycle();
Expand All @@ -202,12 +91,11 @@ public static class FlutterLifecycleAdapter {
/**
* Returns the lifecycle object for the activity a plugin is bound to.
*
* <p>Returns null if the Flutter engine version does not include the lifecycle extraction code.
* <p>Returns null if the Flutter engine version does not include the lifecycle extraction code
* (this probably means the Flutter engine version is too old).
*/
@NonNull
public static Lifecycle getActivityLifecycle(
@NonNull ActivityPluginBinding activityPluginBinding) {
public static Lifecycle getActivityLifecycle(@NonNull ActivityPluginBinding activityPluginBinding) {
HiddenLifecycleReference reference =
(HiddenLifecycleReference) activityPluginBinding.getLifecycle();
return reference.getLifecycle();
Expand Down
3 changes: 2 additions & 1 deletion lib/mapbox_gl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ export 'package:mapbox_gl_platform_interface/mapbox_gl_platform_interface.dart'
RasterDemSourceProperties,
GeojsonSourceProperties,
VideoSourceProperties,
ImageSourceProperties;
ImageSourceProperties,
TerrainProperties;

part 'src/controller.dart';
part 'src/mapbox_map.dart';
Expand Down
9 changes: 7 additions & 2 deletions lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,10 @@ class MapboxMapController extends ChangeNotifier {
/// platform side.
///
Future<void> addGeoJsonSource(String sourceId, Map<String, dynamic> geojson,
{String? promoteId}) async {
{String? promoteId, bool enableLineMetrics = false}) async {
_disposeGuard();
await _mapboxGlPlatform.addGeoJsonSource(sourceId, geojson,
promoteId: promoteId);
promoteId: promoteId, enableLineMetrics: enableLineMetrics);
}

/// Sets new geojson data to and existing source
Expand Down Expand Up @@ -1296,6 +1296,11 @@ class MapboxMapController extends ChangeNotifier {
return _mapboxGlPlatform.addSource(sourceid, properties);
}

Future<void> setTerrain(TerrainProperties properties) async {
_disposeGuard();
return _mapboxGlPlatform.setTerrain(properties);
}

/// Add a layer to the map with the given properties
///
/// The returned [Future] completes after the change has been made on the
Expand Down
Loading