Google Maps Android API v2 授权失败

Posted

技术标签:

【中文标题】Google Maps Android API v2 授权失败【英文标题】:Google Maps Android API v2 Authorization failure 【发布时间】:2012-11-21 16:59:30 【问题描述】:

我的步骤:

从 debug.keystore 获取 SHA1 代码 在 google apis 控制台中创建应用程序 启用谷歌地图 api v2 输入 SHA1;my.package.name 获取 API 密钥

创建的 androidManifest 文件:

    <permission
            android:name="my.package.name.permission.MAPS_RECEIVE"
            android:protectionLevel="signature"/>

    <uses-permission android:name="my.package.name.permission.MAPS_RECEIVE"/>

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15"/>

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher" android:hardwareAccelerated="true">

        <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="MY_API_KEY_HERE" />

        <activity android:name="MyActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

创建布局

将“google-play-services.jar”放入库

编译后我崩溃了:

  ERROR/AndroidRuntime(10182): FATAL EXCEPTION: main
                java.lang.NoClassDefFoundError: com.google.android.gms.R$styleable
                at com.google.android.gms.maps.GoogleMapOptions.createFromAttributes(Unknown Source)
                at com.google.android.gms.maps.MapFragment.onInflate(Unknown Source)
                at android.app.Activity.onCreateView(Activity.java:4716)
                at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
                at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
                at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)
                at android.app.Activity.setContentView(Activity.java:1881)
                at com.example.gm2.MyActivity.onCreate(MyActivity.java:16)
                at android.app.Activity.performCreate(Activity.java:5104)
                at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
                at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
                at android.app.ActivityThread.access$600(ActivityThread.java:141)
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
                at android.os.Handler.dispatchMessage(Handler.java:99)
                at android.os.Looper.loop(Looper.java:137)
                at android.app.ActivityThread.main(ActivityThread.java:5039)
                at java.lang.reflect.Method.invokeNative(Native Method)
                at java.lang.reflect.Method.invoke(Method.java:511)
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
                at dalvik.system.NativeStart.main(Native Method)

之后我将布局更改为:

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/map"
             android:layout_
             android:layout_ />

并将 MyActivity 更改为

  super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    FragmentManager manager = getFragmentManager();
    FragmentTransaction transaction = manager.beginTransaction();

    transaction.add(R.id.map, MapFragment.newInstance());           
    transaction.commit();

结果,应用程序启动了,但我没有看到地图。

控制台日志:

ERROR/Google Maps Android API(10369): Authorization failure.

【问题讨论】:

天啊!我总是找不到相同的错误 R$stylable 类。现在我将我的代码更改为您的编程方式来实现 MapFragment 并且它可以工作!谢谢!但是您需要创建如下所述的密钥 【参考方案1】:

步骤

确保设备具有 Google Play 服务 APK 安装 Google Play 服务版本。 2个以上

在https://code.google.com/apis/console/创建项目 启用“Google Maps Android API v2” 在 API 控制台注册项目中的 SHA1(现在,您需要 WRITE SHA1;your.app.package.name)并获取 API KEY 将目录 ANDROID_SDK_DIR/extras/google/google_play_services/libproject/google-play-services_lib 复制到项目的根目录 将下一行添加到 YOUR_PROJECT/project.properties

android.library.reference.1=google-play-services_lib

将下一行添加到YOUR_PROJECT/proguard-project.txt

.

-keep class * extends java.util.ListResourceBundle 

   protected Object[][] getContents();


现在您已准备好使用适用于 Android 的 Google Map APIs V2 创建您自己的 Google Map 应用程序。

如果您创建应用的最低 SDK = 8,请使用 android 支持库 v4 + SupportMapFragment 而不是 MapFragment。

【讨论】:

这些说明并没有完成全部工作。我需要从地图 API 示例应用程序中复制 proguard.cfg。直到那时它才开始起作用。 另外,我注意到签名算法必须是 SHA1withRSA 而不是 SHA256withRSA(eclipse 为调试密钥创建的默认值)。 谢谢! to enable "Google Maps Android API v2" -step 解决了我的问题。 @YoelGluschnaider:如何将默认算法从 SHA256withRSA 更改为 SHA1withRSA? 谢谢!我被您使用 SupportMapFragment 的想法所救。【参考方案2】:

还请查看此帖子:Google Map Android Api V2 Sample Code not working,如果您完全确定您做了正确的步骤然后按照第二个答案,身份验证被缓存在某处,尝试手动卸载应用程序(就像您使用普通应用程序一样)然后再次“运行”该项目

【讨论】:

我不敢相信这真的奏效了。谢谢@Alejandro del Rio :) 我敢打赌,就像我一样,这里 90% 的人真的想要 this 答案而不是选择的答案(虽然也很有帮助) 在我的情况下,缓存 (?) 在我阅读 *** 并在日志中显示身份验证错误消息时已更新。该应用程序在屏幕上运行,几分钟后地图被加载并且没有更多的身份验证错误。我想重新安装也可以做到。 为未来的读者。删除bingen。清理、重建和更新缓存的凭据。【参考方案3】:

由于我只是浪费了很多时间让 API 工作,我将尝试对 Map API v2 进行逐步验证:

第 1 步:申请您的 API 密钥

如果您不熟悉 Google API 控制台,请阅读上面 Rusfearuth 的非常好的回答。

第 2 步:检查 SHA 哈希(在这种情况下,我使用 eclipse 的调试密钥):

在 Windows 机器上通过命令提示符访问您的用户目录:

C:\Users\you>keytool -list -alias androiddebugkey -keystore .android\debug.keyst
ore -storepass android -keypass android

你会得到类似的东西:

androiddebugkey, 15.10.2012, PrivateKeyEntry,
Zertifikat-Fingerprint (SHA1): 66:XX:47:XX:1E:XX:FE:XX:DE:XX:EF:XX:98:XX:83:XX:9A:XX:23:A6

然后查看您的地图活动的包名称,例如 com.example.mypackagename

您将其与您在 Google API 控制台中的设置结合起来:

66:XX:47:XX:1E:XX:FE:XX:DE:XX:EF:XX:98:XX:83:XX:9A:XX:23:A6;com.example.mypackagename

从哪里获取 API 密钥:

AZzaSyDhkhNotUseFullKey49ylKD2bw1HM

第 3 步。显示元数据

检查元数据是否存在并包含正确的键。如果你发布你的应用,你需要一个不同的密钥。

    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="AZzaSyDhkhNotUseFullKey49ylKD2bw1HM" />
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

第 4 步。显示功能:

您需要此条目,因为地图 API 需要一些图形支持:

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

别担心,99.7% 的设备都支持这个。

第 5 步。清单库:

添加谷歌库。

    <uses-library
        android:name="com.google.android.maps"
        android:required="false" /> // This is required if you want your app to start in the emulator. I set it to false also if map is not an essential part of the application.

第 6 步。清单权限:

检查包名两次:com.example.yourpackage

<permission
    android:name="com.example.yourpackage.permission.MAPS_RECEIVE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.example.yourpackage.permission.MAPS_RECEIVE" />

添加以下权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />

如果您只是显示地图,则以下权限是可选的,不是必需的。尽量不要使用它们。

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

第 7 步。将地图片段包含到您的布局中:

<fragment
    android:id="@+id/map"
    android:layout_
    android:layout_
    android:layout_weight="1"
    class="com.google.android.gms.maps.SupportMapFragment"
    map:cameraTargetLat="47.621120"
    map:cameraTargetLng="-122.349594"
    map:cameraZoom="15" />

如果您发布到 2.x Android 版本,您需要在 Activity 中添加支持:

import android.support.v4.app.FragmentActivity;

对于地图:要工作的条目包括

xmlns:map="http://schemas.android.com/apk/res-auto"

在您的活动布局中(例如 LinearLayout)。

就我而言,每次更改布局中的某些内容时,我都必须清理项目。似乎是一个错误。

第 8 步:使用 Eclipse - 项目 - 清理。

享受吧!

【讨论】:

我正在按照您的步骤操作,但 api 密钥出错,有什么解决方案吗? +1 for 【参考方案4】:

您需要使用位于以下位置的库项目: ANDROID-SDK-DIRECTORY/extras/google/google_play_services/libproject

这将解决您的第一个问题。

我不确定你的第二个,但它可能是第一个的副作用。我仍在尝试让地图在我自己的应用程序中工作:)

【讨论】:

我将 extras/google/google_play_services/libproject/libs/google-play-services.jar 复制到 MY_PROJECT/libs。 这还不够好。您需要使用整个库项目,因为它包含许多资源。在 Eclipse 中,您可以导入一个新的 Android 项目,并将其指向 libproject 目录。然后在自己项目的属性中,添加对它的引用。 我不使用 Eclipse(使用 Idea) 我不确定库项目如何在 Idea 中工作,但 blogs.jetbrains.com/idea/2010/09/… 应该有这些信息。 我找到了为什么它不起作用。我打开了 Google Map API v2 而不是 Google Map Android API v2 服务。 =(真丢脸……【参考方案5】:

今天我遇到了这个问题。我使用的是 Android Studio 2.1.3,Windows 10。虽然调试它工作正常,但如果我更新到发布模式,它就不起作用。我清除了所有 proguard 条件,更新了,但这不是解决方案。

解决方案与项目结构有关。 app\src\debug\res 和 app\src\release\res 之间的 google_maps_api.xml 文件不同。我做了从调试到发布文件夹的手动复制粘贴。

现在可以了。

【讨论】:

【参考方案6】:

我遵循了上面提到的 Gunnar Bernstein 的大部分(如果不是全部)建议,但仍然没有用。但是,在我遵循他的建议和以下建议后,它开始起作用了:

    我通过使用 Android Studio 的右键单击创建了一个新的 MapActivity 选项列表:新建 -> Google -> Google 地图活动

    然后我打开了 google_maps_api.xml 文件,该文件会自动 生成并使用所述链接创建新的 API KEY。一世 完成所有步骤并将我的新密钥保存在我当前的项目下。一世 然后删除了我旧注册的 API KEY,因为它不再需要了。

    在 Manifest 文件下,我将旧的 API KEY 值替换为 由这个新的 XML 文件创建的字符串快捷方式: android:value="@string/google_maps_key",而不是说明 KEY 直接。

    最后,删除新的 MapActivity,但保留原来的 xml 文件 在该过程中创建。

注意:通过以这种方式创建 API KEY,Credentials 下的 Restrictions 列现在显示为“Android 应用程序”。早些时候,当它不起作用时,该列会显示“Android 应用程序,1 个 API”或类似的内容。我不知道这是否会有所不同。 注意:不,这只是意味着我没有为此 API 密钥选择特定的 API(控制台 -> API 密钥 -> 密钥限制 - > API 限制)。

注意:它看起来像 Manifest 文件下的元数据标记:

android:name="com.google.android.maps.v2.API_KEY

已被替换为:

android:name="com.google.android.geo.API_KEY"

我想两者都可以使用,但最好从一开始就使用后者。

注意:在 build.gradle 文件中,android -> defaultConfig -> applicationId 下的值必须与 Credentials 页面下的 Package name 文本匹配。

【讨论】:

这到底发生在我身上,这个解决方案修复了来自控制台的警告。不知何故,Ionic 构建改变了它。 搜索了8个小时后,我回头应用了这个解决方案。 Solved!!!【参考方案7】:

只需将其添加到您的清单文件中:

**<uses-library android:name="com.google.android.maps" />**

例如...

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name" >
    <uses-library android:name="com.google.android.maps" />

    <activity
        android:name=".California"
        android:label="@string/app_name"
        android:screenOrientation="portrait" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

请更新您的 google play 服务库...转到 Window -> Android sdk manager->更新 google play 服务...安装它..删除旧的并保留这个。取自 ANDROID-SDK-DIRECTORY/extras/google/google_play_services/

谢谢..请投票

【讨论】:

【参考方案8】:

我通过检查清单和应用程序build.gradle中的包名称解决了这个错误。

在清单中:

我使用的包名是:

com.app.triapp

应用内 build.gradle:

 defaultConfig 

        applicationId "com.app.live"
    

build.gradle改成com.app.triapp后,解决了我的问题。

【讨论】:

非常感谢。你节省了我很多时间。 优秀的兄弟。我一切都好,而不是这个【参考方案9】:

我正在从 Google 地图的 V1 迁移到 V2。我在尝试通过 Eclipse 运行应用程序时遇到了这个失败。我的根本原因是使用我的发布证书密钥库而不是 Android 调试密钥库,这是通过 Eclipse 运行它时使用的。以下命令 (OSX/Linux) 将为您获取调试密钥库的 SHA1 密钥:

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

如果您使用的是 Windows 7,则可以使用以下命令:

keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android

最好先从设备上完全卸载您的应用,然后再尝试使用新密钥,因为 Android 会缓存安全凭据。

【讨论】:

【参考方案10】:

“java.lang.NoClassDefFoundError: com.google.android.gms.R$styleable”

A 也有此错误,您需要: File -> import -> Existing Android Code Into Workspace -> Browse -> Android sdks -> extras -> google -> google_play_services -> lib_project -> google_play_services_lib 并确定。检查项目并完成。

项目转到包资源管理器。现在转到您的项目(有错误)-> 属性-> Android 并在库中单击添加... google_play_services_lib 应该在那里!添加并重试:)

【讨论】:

【参考方案11】:

我遇到了同样的问题,但事实证明这是因为我创建了两个不同的地图 API 密钥,它们具有相同的 SHA-1 指纹,包名称几乎相似 com.bla.bla 和另一个 com.bla.bla.something

【讨论】:

【参考方案12】: 确保在 API 控制台中启用 Maps SDK for Android。 此外,您可能需要添加您的包名称和 SHA-1 签名证书指纹,以限制使用您的密钥才能完全启用。

【讨论】:

【参考方案13】:

我遇到了完全相同的问题,我只需要将 MapsApiV2 库项目的 SDK 设置为 Android 2.3.3(API lvl 10)

【讨论】:

我不记得这些东西了【参考方案14】:

我有同样的问题。经过大约两个小时的谷歌搜索、重试、多次重新生成 API 密钥等,我发现我在 Google API 控制台中启用了错误的服务。 我启用了 Google Maps API v2 服务,但对于 Android 应用程序,您必须使用 Google Maps Android API v2。 启用正确的服务后,一切都开始工作了。

【讨论】:

【参考方案15】:

您的 ECLIPSE 可能已更改 SHA1 密钥,因此您必须在此处使用新的 SHA1 密钥重新生成您的 google 密钥: https://console.developers.google.com/project/watchful-net-796/apiui/credential 之后,将新密钥复制到清单并重新加载此谷歌页面几次,您的密钥将被更新,重建您的项目,它会工作。 P/S:对于我的错误,我删除了 .android 文件夹,所以 eclipse regen SHA1。

【讨论】:

【参考方案16】:

我按照 Google Doc 中提供的相同步骤操作,但遇到了同样的错误。后来我意识到我正在用我的 app.keystore 签署我的应用程序,而我用来生成 API 密钥的 SHA 密钥是调试密钥。

所以我只是从build.gradle 文件中删除了signingConfig signingConfig.generic,然后我的地图就开始正常工作了。

希望这对某人有所帮助。

【讨论】:

【参考方案17】:

我遇到了同样的问题。

如果您为应用程序的发布版本发布了 api。 然后该 api 将仅适用于发布版本而不适用于调试版本。 因此,请确保您在手机或模拟器中使用的是发行版。

【讨论】:

【参考方案18】:

对我来说,一切都在模拟器和物理设备上运行。

但是,当我设置第二台机器以在具有较新 API 级别的模拟器中调试同一个应用程序时,它停止了对我的工作。

我没有意识到那台机器的指纹发生了变化。在设备日志中看到身份验证失败错误日志后,我将 Google Developer Console 中的指纹与错误消息中的指纹进行了仔细比较。那是我看到差异的时候。将新指纹添加到开发人员控制台(与包名称结合)后,我的应用程序开始在新系统上的模拟器中按预期工作。

因此,如果您设置了一个新系统,请再次检查您的指纹!

【讨论】:

以上是关于Google Maps Android API v2 授权失败的主要内容,如果未能解决你的问题,请参考以下文章

Maps SDK for Android v.3.0.0 BETA "是否可以在没有Google Play服务的设备上运行?

Google Maps API v.3.31更新会破坏StageWebView和StageWebViewBridge

Google Maps Android API V2 检查 Google Maps 应用程序是不是被禁用

无法运行 Google Maps Android API Utility Demo

Google Geolocation API 和 Google Maps Android SDK

Android:使用 Google API 获取实时方向,还是与 Google Maps 通信?