Android 地图不适用于 minifyEnabled = true...已设置 apiKey

Android gmaps doesnt work with minifyEnabled = true... apiKey are setted

我不会说英语,但是...

我正在制作一个使用 GMaps v2 的 android 应用程序。 在调试模式下一切都很好,但是当我午餐发布应用程序时,地图代码不执行!

我确定发布的 apiKey 设置得很好(我在 src/release/values/google_maps_api.xml 中设置并且 apiKey 没有限制),因为如果我设置 minifyEnabled = false在发布构建类型中,它有效!,所以我认为这是混淆器的问题...

我尝试了下一个 proguard 规则的所有组合,但没有...

-keep class com.google.** {*;}

-keep class com.hawk.angela.home.activities.MapFragment { *; }


-keep class com.google.android.gms.maps.** { *; }
-keep interface com.google.android.gms.maps.** { *; }

-keep class * extends java.util.ListResourceBundle { protected Object[][] getContents(); }
-keepattributes InnerClasses
-dontoptimize

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment

# The Maps API uses custom Parcelables.
# Use this rule (which is slightly broader than the standard recommended one)
# to avoid obfuscating them.
-keepclassmembers class * implements android.os.Parcelable {
    static *** CREATOR;
}

# The Maps API uses serialization.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

此外,控制台return没有任何异常

地图初始化在片段中:

MapView mapView = (MapView) rootView.findViewById(R.id.mapView);
Bundle mapState = (savedInstanceState != null) ?
        savedInstanceState.getBundle("mapState") :
        null;
mapView.onCreate(mapState);
mapView.onResume(); // needed to get the map to display immediately

mapView.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(GoogleMap mMap) {
        googleMap = mMap;
        googleMap.setMaxZoomPreference(maxZoom);

        // ...
    }
});

有人能帮帮我吗?至少我必须在哪里找到问题...

谢谢!!

编辑: 安卓清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.enzonotario.app">

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-feature
        android:name="android.hardware.location.network"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.location.gps"
        android:required="false" />

    <!-- GCM permissions -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- Pusher service -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

    <!-- Storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="DATABASE"
            android:value="app.db" />
        <meta-data
            android:name="VERSION"
            android:value="2" />
        <meta-data
            android:name="QUERY_LOG"
            android:value="false" />
        <meta-data
            android:name="DOMAIN_PACKAGE_NAME"
            android:value="com.enzonotario.app" />

        <meta-data
            android:name="com.enzonotario.app.utils.GlideConfigurationModule"
            android:value="GlideModule" />

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="AIzaSyAqRP3ZQzc9gOhs3elhs7AL0qUo6wQOwZ8" />

        <!-- Pusher's FCM listeners and services -->
        <service android:name="com.pusher.android.notifications.fcm.FCMMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        <service android:name="com.pusher.android.notifications.fcm.FCMInstanceIDService">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
            </intent-filter>
        </service>
        <service android:name=".SyncService"
            android:exported="false" />

        <receiver android:name=".gps.receivers.GpsLocationReceiver">
            <intent-filter>
                <action android:name="android.location.PROVIDERS_CHANGED" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        // so many activities
    </application>
</manifest>

google_maps_api.xml(发布)

<resources>
    <!--
    TODO: Before you release your application, you need a Google Maps API key.

    To do this, you can either add your release key credentials to your existing
    key, or create a new key.

    Note that this file specifies the API key for the release build target.
    If you have previously set up a key for the debug target with the debug signing certificate,
    you will also need to set up a key for your release certificate.

    Follow the directions here:

    https://developers.google.com/maps/documentation/android/signup

    Once you have your key (it starts with "AIza"), replace the "google_maps_key"
    string in this file.
    -->
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
        AIzaSyAqRP3ZQzc9gOhs3elhs7AL0qUo6wQOwZ8
    </string>
</resources>

Google 地图的 API 键必须在 AndroidManifest.xml 中明确设置才能工作。

对于调试模式,它可以在 google_maps_api.xml 中设置,但对于发布版本,它必须在 AndroidManifest.xml

例如

<meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="<your API key here>"/>

我通常会在执行此操作时创建两个密钥。一个用于调试,一个用于发布。这是必要的,因为用于调试的 SHA 与发布版本不同,因此您需要为每个创建两个单独的 API 密钥。

所以我的 AndroidManifest.xml 看起来有点像下面的那个。当我将构建从调试转移到发布或从发布转移到调试时,我只是取消注释元数据。

    <!-- Development/Debug Google Maps API Key -->
    <!--<meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key"/> -->

    <!-- Release Google Maps API Key -->
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="<my API key here>"/>

好吧,问题不在 gmaps 中,而是在我使用的 materialtabs 库中(https://github.com/neokree/MaterialTabs), now I use https://github.com/ogaclejapan/SmartTabLayout,它工作得很好!