首页 > 解决方案 > Flutter:尝试在 android 上使用 map_view 显示交互式地图时应用程序崩溃

问题描述

map_view当用户使用插件单击地址时,我正在尝试显示交互式地图。我遇到的问题是每次单击地址时,应用程序都会崩溃。

这是我的项目结构/配置(详细):

lib\main.dart

import 'package:flutter/material.dart';

import 'package:map_view/map_view.dart';

import './pages/product.dart';

void main() {
  MapView.setApiKey(<my_google_developer_api_key>);
  runApp(MyApp());
}

lib\pages\product.dart

import 'package:flutter/material.dart';

import 'package:map_view/map_view.dart';

class ProductPage extends StatelessWidget {
  void _showMap() {
    final List<Marker> markers = <Marker>[
      Marker('position', 'Position', product.location.latitude,
          product.location.longitude)
    ];
    final cameraPosition = CameraPosition(
        Location(product.location.latitude, product.location.longitude), 14.0);
    final mapView = MapView();
    mapView.show(
        MapOptions(
            initialCameraPosition: cameraPosition,
            mapViewType: MapViewType.normal,
            title: 'Product Location'),
        toolbarActions: [
          ToolbarAction('Close', 1),
        ]);
    mapView.onToolbarAction.listen((int id) {
      if (id == 1) {
        mapView.dismiss();
      }
    });
    mapView.onMapReady.listen((_) {
      mapView.setMarkers(markers);
    });
  }
}

发布规范.yaml

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  scoped_model: ^1.0.1
  http: ^0.12.0+2
  shared_preferences: ^0.5.3+4
  rxdart: ^0.22.1+1
  map_view: ^0.0.14
  location: ^1.4.1

android\build.gradle

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.0'
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.50'
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}
subprojects {
    project.configurations.all {
        resolutionStrategy.eachDependency { details ->
            if (details.requested.group == 'com.android.support'
                    && !details.requested.name.contains('multidex')) {
                details.useVersion '27.1.1'
            }
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

android\app\src\main\AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.easy_list">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="easy_list"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name="com.apptreesoftware.mapview.MapActivity" android:theme="@style/Theme.AppCompat.Light.DarkActionBar"/>
        <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value=<my-google-developer-api-key>/>
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
        <meta-data android:name="com.google.android.geo.API_KEY" android:value=<my-google-developer-api-key>/>
    </application>
</manifest>

控制台中显示的错误消息

I/flutter ( 5555): {showUserLocation: false, showMyLocationButton: false, showCompassButton:
false, hideToolbar: false, cameraPosition: {latitude: 21.0277644, longitude: 105.8341598, tim
e: 0, altitude: 0.0, speed: 0.0, bearing: 0.0, horizontalAccuracy: 0.0, verticalAccuracy: 0.0
, zoom: 14.0, tilt: 0.0}, title: Product Location, mapViewType: normal}
W/art     ( 5555): Before Android 4.1, method android.graphics.PorterDuffColorFilter android.
support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffCo
lorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have i
ncorrectly overridden the package-private method in android.graphics.drawable.Drawable
I/zzbz    ( 5555): Making Creator dynamically
I/art     ( 5555): Enter while loop.
I/DynamiteModule( 5555): Considering local module com.google.android.gms.maps_dynamite:0 and
remote module com.google.android.gms.maps_dynamite:221
I/DynamiteModule( 5555): Selected remote version of com.google.android.gms.maps_dynamite, ver
sion >= 221
W/System  ( 5555): ClassLoader referenced unknown path:
W/System  ( 5555): ClassLoader referenced unknown path: /data/user_de/0/com.google.android.gm
s/app_chimera/m/00000071/n/armeabi-v7a
W/System  ( 5555): ClassLoader referenced unknown path: /data/user_de/0/com.google.android.gm
s/app_chimera/m/00000071/n/armeabi
I/Google Maps Android API( 5555): Google Play services client version: 12451000
I/Google Maps Android API( 5555): Google Play services package version: 18382017
D/AndroidRuntime( 5555): Shutting down VM
E/AndroidRuntime( 5555): FATAL EXCEPTION: main
E/AndroidRuntime( 5555): Process: com.example.easy_list, PID: 5555
E/AndroidRuntime( 5555): java.lang.RuntimeException: Unable to start activity ComponentInfo{c
om.example.easy_list/com.apptreesoftware.mapview.MapActivity}: android.view.InflateException:
 Binary XML file line #2: Binary XML file line #2: Error inflating class fragment
E/AndroidRuntime( 5555):        at android.app.ActivityThread.performLaunchActivity(ActivityT
hread.java:2724)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.handleLaunchActivity(ActivityTh
read.java:2789)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.-wrap12(ActivityThread.java)
E/AndroidRuntime( 5555):        at android.app.ActivityThread$H.handleMessage(ActivityThread.
java:1527)
E/AndroidRuntime( 5555):        at android.os.Handler.dispatchMessage(Handler.java:110)
E/AndroidRuntime( 5555):        at android.os.Looper.loop(Looper.java:203)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.main(ActivityThread.java:6251)
E/AndroidRuntime( 5555):        at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5555):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:1063)
E/AndroidRuntime( 5555):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:92
4)
E/AndroidRuntime( 5555): Caused by: android.view.InflateException: Binary XML file line #2: B
inary XML file line #2: Error inflating class fragment
E/AndroidRuntime( 5555): Caused by: android.view.InflateException: Binary XML file line #2: E
rror inflating class fragment
E/AndroidRuntime( 5555): Caused by: java.lang.RuntimeException: The API key can only be speci
fied once. It is recommended that you use the meta-data tag with the name: com.google.android
.geo.API_KEY in the <application> element of AndroidManifest.xml
E/AndroidRuntime( 5555):        at com.google.maps.api.android.lib6.drd.r.b(:com.google.andro
id.gms.dynamite_mapsdynamite@18382046@18.3.82 (040306-260264002):23)
E/AndroidRuntime( 5555):        at com.google.maps.api.android.lib6.auth.f.a(:com.google.andr
oid.gms.dynamite_mapsdynamite@18382046@18.3.82 (040306-260264002):10)
E/AndroidRuntime( 5555):        at com.google.maps.api.android.lib6.impl.f.a(:com.google.andr
oid.gms.dynamite_mapsdynamite@18382046@18.3.82 (040306-260264002):41)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.internal.CreatorImpl.a(:com.go
ogle.android.gms.dynamite_mapsdynamite@18382046@18.3.82 (040306-260264002):61)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.internal.CreatorImpl.newMapFra
gmentDelegate(:com.google.android.gms.dynamite_mapsdynamite@18382046@18.3.82 (040306-26026400
2):25)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.internal.j.a(:com.google.andro
id.gms.dynamite_mapsdynamite@18382046@18.3.82 (040306-260264002):73)
E/AndroidRuntime( 5555):        at hs.onTransact(:com.google.android.gms.dynamite_mapsdynamit
e@18382046@18.3.82 (040306-260264002):4)
E/AndroidRuntime( 5555):        at android.os.Binder.transact(Binder.java:504)
E/AndroidRuntime( 5555):        at com.google.android.gms.internal.maps.zza.transactAndReadEx
ception(Unknown Source)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.internal.zzf.zzc(Unknown Sourc
e)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.SupportMapFragment$zzb.zzc(Unk
nown Source)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.SupportMapFragment$zzb.createD
elegate(Unknown Source)
E/AndroidRuntime( 5555):        at com.google.android.gms.dynamic.DeferredLifecycleHelper.zza
(Unknown Source)
E/AndroidRuntime( 5555):        at com.google.android.gms.dynamic.DeferredLifecycleHelper.onI
nflate(Unknown Source)
E/AndroidRuntime( 5555):        at com.google.android.gms.maps.SupportMapFragment.onInflate(U
nknown Source)
E/AndroidRuntime( 5555):        at android.support.v4.app.Fragment.onInflate(Fragment.java:13
02)
E/AndroidRuntime( 5555):        at android.support.v4.app.FragmentManagerImpl.onCreateView(Fr
agmentManager.java:3714)
E/AndroidRuntime( 5555):        at android.support.v4.app.FragmentController.onCreateView(Fra
gmentController.java:114)
E/AndroidRuntime( 5555):        at android.support.v4.app.FragmentActivity.dispatchFragmentsO
nCreateView(FragmentActivity.java:374)
E/AndroidRuntime( 5555):        at android.support.v4.app.BaseFragmentActivityApi14.onCreateV
iew(BaseFragmentActivityApi14.java:39)
E/AndroidRuntime( 5555):        at android.support.v4.app.FragmentActivity.onCreateView(Fragm
entActivity.java:68)
E/AndroidRuntime( 5555):        at android.view.LayoutInflater.createViewFromTag(LayoutInflat
er.java:777)
E/AndroidRuntime( 5555):        at android.view.LayoutInflater.createViewFromTag(LayoutInflat
er.java:727)
E/AndroidRuntime( 5555):        at android.view.LayoutInflater.inflate(LayoutInflater.java:49
5)
E/AndroidRuntime( 5555):        at android.view.LayoutInflater.inflate(LayoutInflater.java:42
6)
E/AndroidRuntime( 5555):        at android.view.LayoutInflater.inflate(LayoutInflater.java:37
7)
E/AndroidRuntime( 5555):        at android.support.v7.app.AppCompatDelegateImplV9.setContentV
iew(AppCompatDelegateImplV9.java:287)
E/AndroidRuntime( 5555):        at android.support.v7.app.AppCompatActivity.setContentView(Ap
pCompatActivity.java:139)
E/AndroidRuntime( 5555):        at com.apptreesoftware.mapview.MapActivity.onCreate(MapActivi
ty.kt:31)
E/AndroidRuntime( 5555):        at android.app.Activity.performCreate(Activity.java:6666)
E/AndroidRuntime( 5555):        at android.app.Instrumentation.callActivityOnCreate(Instrumen
tation.java:1118)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.performLaunchActivity(ActivityT
hread.java:2677)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.handleLaunchActivity(ActivityTh
read.java:2789)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.-wrap12(ActivityThread.java)
E/AndroidRuntime( 5555):        at android.app.ActivityThread$H.handleMessage(ActivityThread.
java:1527)
E/AndroidRuntime( 5555):        at android.os.Handler.dispatchMessage(Handler.java:110)
E/AndroidRuntime( 5555):        at android.os.Looper.loop(Looper.java:203)
E/AndroidRuntime( 5555):        at android.app.ActivityThread.main(ActivityThread.java:6251)
E/AndroidRuntime( 5555):        at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 5555):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:1063)
E/AndroidRuntime( 5555):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:92
4)
Lost connection to device.

我希望交互式地图显示在屏幕上,但应用程序崩溃了。任何帮助表示赞赏。提前致谢。

标签: androidflutterdart

解决方案


您的案件的主要问题是:

E/AndroidRuntime( 5555): Caused by: java.lang.RuntimeException: The API key can only be speci
fied once. It is recommended that you use the meta-data tag with the name: com.google.android
.geo.API_KEY in the <application> element of AndroidManifest.xml

尝试删除这一行:

    <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value=<my-google-developer-api-key>/>

并再次运行它......


推荐阅读