You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中无需依赖第三方包,实现经纬度跳转GoogleMap与MapKit

不依赖第三方包实现Flutter跳转谷歌地图(安卓)和MapKit(iOS)

要实现不依赖url_launcher的地图跳转功能,我们可以利用Flutter的**平台通道(MethodChannel)**直接调用安卓和iOS的原生API,分别处理系统地图应用的启动逻辑。

Flutter 端代码

创建一个工具类,通过MethodChannel向原生层传递经纬度参数,并处理调用结果:

import 'package:flutter/services.dart';

class NativeMapLauncher {
  // 定义MethodChannel的通道名称,需和原生端保持一致
  static const _methodChannel = MethodChannel('com.yourapp.map_launcher');

  static Future<void> openMap(double latitude, double longitude) async {
    try {
      await _methodChannel.invokeMethod(
        'launchMap',
        {'latitude': latitude, 'longitude': longitude},
      );
    } on PlatformException catch (e) {
      throw '地图启动失败: ${e.message}';
    }
  }
}

安卓端原生代码(Kotlin)

在MainActivity.kt中实现MethodChannel的处理逻辑,通过Intent启动谷歌地图应用,若未安装则跳转网页版:

package com.example.yourappname

import android.content.Intent
import android.net.Uri
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.yourapp.map_launcher"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "launchMap") {
                val latitude = call.argument<Double>("latitude") ?: 0.0
                val longitude = call.argument<Double>("longitude") ?: 0.0

                // 构建谷歌地图Intent,指定包名确保打开谷歌地图
                val mapUri = Uri.parse("geo:$latitude,$longitude?q=$latitude,$longitude")
                val mapIntent = Intent(Intent.ACTION_VIEW, mapUri).apply {
                    setPackage("com.google.android.apps.maps")
                }

                if (mapIntent.resolveActivity(packageManager) != null) {
                    startActivity(mapIntent)
                    result.success(null)
                } else {
                    // 无谷歌地图时跳转网页版
                    val webUri = Uri.parse("https://www.google.com/maps/search/?api=1&query=$latitude,$longitude")
                    startActivity(Intent(Intent.ACTION_VIEW, webUri))
                    result.success(null)
                }
            } else {
                result.notImplemented()
            }
        }
    }
}

安卓额外配置

针对Android 11+,需要在AndroidManifest.xml中添加查询谷歌地图应用的权限,否则无法检测应用是否安装:

<manifest ...>
    <queries>
        <!-- 允许查询谷歌地图应用 -->
        <package android:name="com.google.android.apps.maps" />
    </queries>
    ...
</manifest>

iOS端原生代码(Swift)

在AppDelegate.swift中实现MethodChannel逻辑,通过URL Scheme打开MapKit,若无法打开则跳转网页版:

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private let CHANNEL = "com.yourapp.map_launcher"

    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        guard let controller = window?.rootViewController as? FlutterViewController else {
            return super.application(application, didFinishLaunchingWithOptions: launchOptions)
        }
        
        let methodChannel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger)
        methodChannel.setMethodCallHandler { [weak self] call, result in
            guard call.method == "launchMap" else {
                result.notImplemented()
                return
            }
            
            guard let latitude = call.arguments?["latitude"] as? Double,
                  let longitude = call.arguments?["longitude"] as? Double else {
                result.error("INVALID_PARAMS", "经纬度参数无效", nil)
                return
            }
            
            // 构建MapKit的URL
            guard let mapUrl = URL(string: "https://maps.apple.com/?q=\(latitude),\(longitude)") else {
                result.error("INVALID_URL", "无法生成地图链接", nil)
                return
            }
            
            if UIApplication.shared.canOpenURL(mapUrl) {
                UIApplication.shared.open(mapUrl) { success in
                    success ? result.success(nil) : result.error("LAUNCH_FAILED", "无法打开地图应用", nil)
                }
            } else {
                // 无MapKit时跳转网页版
                guard let webUrl = URL(string: "https://www.google.com/maps/search/?api=1&query=\(latitude),\(longitude)") else {
                    result.error("INVALID_WEB_URL", "无法生成网页地图链接", nil)
                    return
                }
                UIApplication.shared.open(webUrl) { success in
                    success ? result.success(nil) : result.error("LAUNCH_FAILED", "无法打开网页地图", nil)
                }
            }
        }

        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

使用方式

在你的Flutter页面中直接调用工具类方法即可:

// 示例:跳转到北纬39.908860,东经116.397390
NativeMapLauncher.openMap(39.908860, 116.397390);

内容的提问来源于stack exchange,提问作者Jatin Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:25:17