Google Maps Android API v2授权失败

Rus*_*uth 92 android google-maps android-maps google-maps-android-api-2

我的步骤:

  • 从debug.keystore获取SHA1代码
  • 在谷歌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>
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建布局

  • 把"google-play-services.jar"放到libs上

编译后我崩溃了:

  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)
Run Code Online (Sandbox Code Playgroud)

之后我将布局更改为:

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

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/map"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />
Run Code Online (Sandbox Code Playgroud)

并将MyActivity更改为

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

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

    transaction.add(R.id.map, MapFragment.newInstance());           
    transaction.commit();
Run Code Online (Sandbox Code Playgroud)

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

控制台日志:

ERROR/Google Maps Android API(10369): Authorization failure.
Run Code Online (Sandbox Code Playgroud)

Rus*_*uth 100

步骤:

  • 确保该设备具有Google Play服务APK
  • 安装Google Play服务版.超过2

在此输入图像描述

  • 通过https://code.google.com/apis/console/创建项目
  • 启用"Google Maps Android API v2" 在此输入图像描述
  • 在API控制台中注册项目中的SHA1(现在,您需要写入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();

}
Run Code Online (Sandbox Code Playgroud)

现在,您已准备好使用适用于Android的Google Map API V2创建自己的Google地图应用.

如果使用min SDK = 8创建应用程序,请使用android支持库v4 + SupportMapFragment而不是MapFragment.


ade*_*ago 34

另请查看这篇文章:谷歌地图Android Api V2示例代码无法正常工作,如果你完全确定你做了正确的步骤然后按照第二个答案,身份验证被缓存到某个地方,尝试手动卸载应用程序(就像你做的那样)正常应用)然后再次"运行"项目

  • 我简直不敢相信.谢谢@Alejandro del Rio :) (6认同)
  • 对于未来的读者.删除`bin`和`gen`.清除,重建和缓存的凭据已更新. (2认同)

Gun*_*ein 19

由于我浪费了大量时间让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
Run Code Online (Sandbox Code Playgroud)

你会得到类似的东西:

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
Run Code Online (Sandbox Code Playgroud)

然后查看地图活动的包名称,例如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
Run Code Online (Sandbox Code Playgroud)

在哪里获得API密钥:

AZzaSyDhkhNotUseFullKey49ylKD2bw1HM
Run Code Online (Sandbox Code Playgroud)

第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" />
Run Code Online (Sandbox Code Playgroud)

第4步.清单功能:

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

<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />
Run Code Online (Sandbox Code Playgroud)

别担心,99.7%的设备支持此功能.

步骤5.清单库:

添加Google图书馆.

    <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.
Run Code Online (Sandbox Code Playgroud)

步骤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" />
Run Code Online (Sandbox Code Playgroud)

添加以下权限:

<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" />
Run Code Online (Sandbox Code Playgroud)

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

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Run Code Online (Sandbox Code Playgroud)

步骤7.将地图片段包含在布局中:

<fragment
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    class="com.google.android.gms.maps.SupportMapFragment"
    map:cameraTargetLat="47.621120"
    map:cameraTargetLng="-122.349594"
    map:cameraZoom="15" />
Run Code Online (Sandbox Code Playgroud)

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

import android.support.v4.app.FragmentActivity;
Run Code Online (Sandbox Code Playgroud)

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

xmlns:map="http://schemas.android.com/apk/res-auto"
Run Code Online (Sandbox Code Playgroud)

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

在我的情况下,每次我在布局中更改某些内容时,我都必须清理项目.似乎是一个bug.

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

请享用!


Sco*_*edy 16

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

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

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

  • 我发现为什么它不起作用.我启用了Google Map API v2而不是Google Map Android API v2服务.=(对我感到羞耻.... (17认同)

Yay*_*aya 5

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

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

现在它有效.


gol*_*aza 5

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

  1. 我使用 Android Studio 的右键单击选项列表创建了一个新的 MapActivity:New -> Google -> Google Maps Activity

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

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

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

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

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

android:name="com.google.android.maps.v2.API_KEY
Run Code Online (Sandbox Code Playgroud)

已被替换为:

android:name="com.google.android.geo.API_KEY"
Run Code Online (Sandbox Code Playgroud)

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

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