当应用程序启动时,即使在 flutter 中使用有效的 api 密钥,Google 地图也会显示空位置,并且当我进行多次热重新加载时,它会正常工作

问题描述 投票:0回答:2

我正在尝试在我的

android
应用程序中嵌入谷歌地图的本机
flutter
视图。我知道我们已经有了
google_map_plugin
pub.dev
但为了提高自己作为开发人员的水平,我正在尝试将原生 Android 代码集成到我的 flutter 应用程序中

这是我的飞镖代码

const myGoogleMapView = 'myGoogleMapView';

class MyGoogleMapView extends StatelessWidget {
  const MyGoogleMapView({super.key});

  @override
  Widget build(BuildContext context) {
    return Platform.isAndroid
        ? const AndroidView(
            viewType: myGoogleMapView,
            layoutDirection: TextDirection.ltr,
            creationParams: null,
            creationParamsCodec: StandardMessageCodec(),
          )
        : const UiKitView(
            viewType: myGoogleMapView,
            layoutDirection: TextDirection.ltr,
            creationParams: null,
            creationParamsCodec: StandardMessageCodec(),
          );

   
  }
}

接下来在 Android 端,我在

manifest
中添加了我的 apikey 以及互联网权限

MainActivity.kt

class MainActivity: FlutterActivity() {

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)

    flutterEngine
        .platformViewsController
        .registry
        .registerViewFactory("myGoogleMapView", MyGoogleMapViewFactory(this))

}
}

然后我创建了

MyGoogleMapViewFactory
MyGoogleMapView

class MyGoogleMapViewFactory(private val activity: FlutterActivity) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
        val creationParams = args as Map<String?, Any?>?
        return MyGoogleMapView(context, viewId, creationParams,activity)

    }
}

class MyGoogleMapView(context: Context, id: Int, creationParams: Map<String?, Any?>?,activity: FlutterActivity) :
    PlatformView, OnMapReadyCallback {
    private val mapview: MapView = MapView(context)
    private var loadedCallbackPending = false
    private var mMap: GoogleMap? = null
    private var currentMarker: Marker? = null

    override fun getView(): View {
        return mapview
    }

    override fun dispose() {}

    init {
        val layoutParams: ViewGroup.LayoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
        )
        mapview.layoutParams = layoutParams

        mapview.onCreate(null)
        mapview.getMapAsync(this)

    }


    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap
        val myLocation = LatLng(37.7749, -122.4194)
        if (currentMarker != null) {
            currentMarker?.remove()
        }
        currentMarker = mMap?.addMarker(
            MarkerOptions().position(myLocation).title("Marker Title")
        )
        mMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(myLocation, 10f))


    }

    private fun invalidateMapIfNeeded() {
        if (mMap == null || loadedCallbackPending) {
            return
        }
        loadedCallbackPending = true
        mMap!!.setOnMapLoadedCallback {
            loadedCallbackPending = false
            postFrameCallback {
                postFrameCallback {
                    mapview.invalidate()
                }
            }
        }
    }


    private fun postFrameCallback(f: Runnable) {
        Choreographer.getInstance().postFrameCallback { f.run() }
    }


}

我只看到一个空的谷歌地图,上面有我的标记。我 100% 确定我的 apikey 是正确的,因为我在本机

android
应用程序中使用具有相同包名称的同一个 apikey 并且它工作正常

我还检查了谷歌地图插件的代码

github
,他们写了
invalidateMapIfNeeded
,我复制粘贴并尝试在不同的地方调用它,如
init
onMapReady
等,但对我不起作用

我也尝试在飞镖方面使用

Hybrid
组合物

return PlatformViewLink(
      viewType: myGoogleMapView,
      surfaceFactory: (context, controller) {
        return AndroidViewSurface(
          controller: controller as AndroidViewController,
          gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
          hitTestBehavior: PlatformViewHitTestBehavior.opaque,
        );
      },
      onCreatePlatformView: (params) {
        return PlatformViewsService.initSurfaceAndroidView(
          id: params.id,
          viewType: myGoogleMapView,
          layoutDirection: TextDirection.ltr,
          creationParams: null,
          creationParamsCodec: const StandardMessageCodec(),
          onFocus: () {
            params.onFocusChanged(true);
          },
        )
          ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
          ..create();
      },
    );

但这也行不通。当我尝试使用原生 Android 端的

TextView
EditText
等简单视图时,它工作得很好。不知道谷歌地图有什么问题

日志位于此处,因为我超出了文本限制

输出

我注意到的另一件事是,当我第一次运行该应用程序时,谷歌地图是空的,就像我上面显示的那样,但是如果我继续多次进行热重载,地图就会开始缓慢显示。查看此视频了解更多

android flutter google-maps google-maps-android-api-2
2个回答
0
投票

此错误似乎与谷歌控制台的谷歌地图 APi 和授权有关。您是否放置了 SHa-1 并限制了 API?我记得曾经遇到过这样的错误。


-1
投票

此行为可能是由多种因素引起的,调试它可能需要一些调查。您可以采取以下一些步骤来诊断和解决问题:

网络连接:确保您的设备或模拟器在运行应用程序时具有活动的网络连接。 Google 地图需要互联网连接才能加载地图。

初始化:确认您在代码中正确初始化了 Google 地图组件。如果您在 Flutter 中使用 GoogleMap 小部件,您通常应该在 onMapCreated 回调中执行此操作。

错误处理:实现 Google 地图初始化的错误处理。检查地图初始化期间抛出的任何错误消息或异常,并将它们显示在应用程序的 UI 中或记录它们以进行调试。

日志和调试:使用开发人员工具和日志收集有关可能导致问题的原因的更多信息。在日志中查找与 Google 地图组件相关的任何错误消息或警告。

状态管理:确保 Flutter 应用中的状态管理设置正确。在某些情况下,热重载可能有助于通过重新初始化状态来“解决”问题。

依赖项:检查项目的依赖项并确保它们是最新的,尤其是与地图或位置服务相关的任何包。

重建过程:了解 Flutter 中的热重载和重建是如何工作的。多次重建应用程序可能会以某种方式触发地图的正确初始化过程。

插件兼容性:确保您用于 Google 地图的 Flutter 插件与您的 Flutter 版本兼容。有时,兼容性问题可能会导致意外行为。

缓存: 检查多次热重载后是否存在地图数据缓存或初始化,这可能会导致地图显示。

在不同设备上测试:尝试在不同设备或模拟器上运行您的应用程序,看看问题是否特定于特定环境。

© www.soinside.com 2019 - 2024. All rights reserved.