加载地图失败。无法连接Google服务器。这可能是一个身份验证问题。

32

我每天都在搜索,但是我找不到答案...

所有的东西都准备好了,但是谷歌地图仍然无法在带有选项卡的片段上显示。

我检查过了,已经打开了Google Map Android V2和正确的API_KEY。

我不知道发生了什么事情!

img

MainActivity.java:

public class MainActivity extends FragmentActivity implements
        ActionBar.TabListener {

    SectionsPagerAdapter mSectionsPagerAdapter;

    ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String titles[] = { this.getString(R.string.title_around),
                this.getString(R.string.title_map),
                this.getString(R.string.title_favorite),
                this.getString(R.string.title_achievement), };

        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        mSectionsPagerAdapter = new SectionsPagerAdapter(
                getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);
        mViewPager
                .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
                    @Override
                    public void onPageSelected(int position) {
                        actionBar.setSelectedNavigationItem(position);
                    }
                });

        for (int i = 0; i < titles.length; i++) {
            actionBar.addTab(actionBar.newTab().setText(titles[i])
                    .setTabListener(this));
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
        mViewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
    }

    @Override
    public void onTabReselected(ActionBar.Tab tab,
            FragmentTransaction fragmentTransaction) {
    }

    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // TODO 在這邊決定哪個位置要給什麼 View(Fragment)
            Fragment fragment = null;
            // TODO 建議先在之前就初始化好 4 個 Fragment
            switch (position) {
            case 0:
                fragment = new AroundFragment();
                break;
            case 1:
                fragment = new MapsFragment();
                break;
            case 2:
                fragment = new FavoriteFragment();
                break;
            case 3:
                fragment = new AchievementFragment();
                break;
            default:
                break;
            }

            return fragment;
        }

        @Override
        public int getCount() {
            return 4;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // TODO 在這邊決定每一個 View 的 title
            switch (position) {
            case 0:
                return getString(R.string.title_around);
            case 1:
                return getString(R.string.title_map);
            case 2:
                return getString(R.string.title_favorite);
            case 3:
                return getString(R.string.title_achievement);
            }
            return null;
        }
    }

}

MapsFragment.java:

public class MapsFragment extends Fragment{
    static final LatLng NKUT = new LatLng(23.979548, 120.696745);
    private GoogleMap map;
    SupportMapFragment mMapFragment;
    public MapsFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.map_fragment,container, false);

        map = ((SupportMapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();

         mMapFragment = SupportMapFragment.newInstance();
         FragmentTransaction fragmentTransaction =
                 getFragmentManager().beginTransaction();
         fragmentTransaction.add(R.id.map,mMapFragment);
         fragmentTransaction.commit();

        return rootView;

    }
}

地图片段.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment" />

</RelativeLayout> 

清单文件 Manifest.xml:

<!-- Google Map -->
<permission
        android:name="com.jertt.yummymap.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
<uses-permission android:name="com.jertt.yummymap.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- The following two permissions are not required to use
     Google Maps Android API v2, but are recommended. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

<!-- end -->
    <!-- Google Map API Key -->

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

    <!-- end -->

解决方案:

我找到了解决方法!!!

如果你使用的是私有密钥库来申请API_KEY,那么你无法通过eclipse上传和安装应用程序。

你需要自己将.apk文件上传到设备上并进行安装!

感谢Tarsem和srikanth gr的帮助!!


你的项目中添加了 Google Play 库吗? - Srikanth Roopa
是的,请看,我添加了http://imgur.com/tH5dzZc。 - JackWu
1
我找到了解决方案!!!如果您使用私有密钥库来应用API_KEY,则无法使用eclipse上传和安装应用程序。您需要自己将.apk文件上传到设备并安装它!感谢Tarsem和srikanth gr的帮助!! - JackWu
你在Google API上使用了哪个包来关联密钥?我的应用程序在全屏模式下工作正常,但选项卡视图版本无法工作。我知道我的密钥是有效的,因为全屏版本可以工作。有什么想法吗? - Marty Griffin
https://dev59.com/PmMm5IYBdhLWcg3wm_7z#22653551 - Pratik Butani
25个回答

69

听起来你的问题可能与你从谷歌API Access获取的API_KEY有关,所以请验证你的API_KEY证书指纹包名

同时在<manifest>内使用以下内容

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

同时也需要验证: <meta-data .... > 应该放在 <application> 标签内部


PS.

1. 另外还需添加以下权限

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

2. 更改 AndroidManifest.xml 中的 API 密钥后,必须 清除应用数据

清除应用数据的方法:

要么 前往 设置>应用管理器>选择您的应用>点击清除数据

要么 必须卸载该应用程序,然后再安装它! 请注意:除非您完全卸载应用程序以彻底清除其数据,否则不要重新安装


哦,我的天!我找到问题了!! - JackWu
6
如果您使用私人密钥库来应用API_KEY,则无法通过eclipse上传和安装应用程序。您需要自己上传.apk文件并安装它!感谢Tarsem和srikanth gr的帮助!! - JackWu
2
对我来说关键的部分是,如果 API 密钥更改,则必须清除应用程序数据。谢谢! - Ian Newson
1
对我来说,这非常有用,但最好的方法是使用“清除应用程序数据”: 转到设置>应用程序管理器>选择您的应用程序>单击“清除数据”。 - xarly
我带着同样的问题来到这里。问题是 - 我更改了我的应用程序包名称,但没有在 Google API 控制台中的 API 密钥首选项中反映这种更改。唉,令人恼火的事情 :) - Drew

35

我花了很多时间,有太多类似的问题。

我试图添加自己的权限和WIFI_STATE权限,但真正的问题在应用程序数据中。

在清单中更改API密钥后,您必须“清除应用程序数据”(或完全重新安装)。

这对我有所帮助,我希望这篇文章能帮到某些人。


10

我的问题得到解决是因为在清单文件中添加了权限:

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

1
真是难以置信,想要理解 Android 中一些组件的工作方式是多么的模糊。它仿佛有魔法一般!谢谢你提供的解决方案,它确实对我很有帮助。 - the_dark_destructor
2
请注意,自2014年5月起,不再需要此权限。 - Anthony

6

我有同样的问题,我的问题是我没有在控制台中激活服务:

  1. 进入控制台:https://code.google.com/apis/console/
  2. 进入服务部分
  3. 启用Google Maps Android API v2
  4. 按照文档中的所有步骤进行操作

5

如果您在认证方面遇到问题,请在Logcat中检查您的包名。如果您使用的是Android Studio,请查看您的build.gradle文件。当文件包含applicationIdSuffix '.dev'时,您应该将.dev添加到您的包名中。

例如,包名为:

com.company.main

在API控制台中写入:

...9S.ME.DA.FE;com.company.main.dev


谢谢 - 不是完全相同的问题,但我有一个不同的模拟服务构建版本,导致了不同的包名。 - Tom
我爱你!寻找解决方案三天,你救了我!谢谢,这解决了我的问题 :) - Valerio

4

在做了所有人说的事情,比如检查清单、添加权限、用eclipse生成带有sha1的新密钥等等,但仍然无法正常工作时,我只是做了以下操作:

adb uninstall com.example.hellomap

然后再次通过Eclipse运行。看起来设备没有完全获取到新的数据。希望这可以帮助。


谢谢你提供这个小而强大的解决方案。哈哈!我也遇到了同样的问题,用了相同的方法解决了。 - cmcromance
1
哦!我要添加一些信息。这个问题发生在Gingerbread上,但在ICS和JB上没有发生。 - cmcromance

2

我能够使用调试密钥并从eclipse加载。但是,我的AndroidManifest.xml文件中缺少以下权限:

uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"

1
我已经通过在清单中授权来解决了这个问题。
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

1
我在使用Android Studio时遇到了同样的问题。连接到Android调试器时,Google地图无法显示。
我通过添加位于~/.android/debug.keystore中的调试密钥库的SHA1指纹来解决了这个问题。我认为这个密钥库是默认生成的(不确定)。
以下终端命令可用于获取SHA1指纹:
keytool -list -v -keystore ~/.android/debug.keystore 

当它要求输入密码时,不要输入任何内容,只需按回车键即可。(在我的情况下有效)
将此指纹添加到您在开发人员控制台中的Android应用程序的API密钥中。
干杯!

1

在审查了很多案例并成功运行地图后,需要记住以下几点:

  • 使用Android API 17,同时使用模拟器和项目
  • 引用Google服务
  • 如有需要,请使用Android支持库
  • 按照以下顺序使用库:src、gen、Google APIs、Android支持库、依赖项和私有库
  • 使用正确的API密钥
  • 清除数据,重新安装应用程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接