谷歌地图API v2无法使用。

8
我正在尝试使用Google Maps API v2构建应用程序,但问题是,应用程序仍然会强制关闭,尽管我已经按照所有必需的指示进行了操作。
以下是Android部分:
import android.support.v4.app.FragmentActivity;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class GPSonMap extends FragmentActivity{

 MapView map;
 MapController controller;
 LocationManager locationManager;
 LocationListener listener;
 PendingIntent pendingIntent ;
 Criteria criteria;
 MapOverlay overlay;


@Override
public void onCreate(Bundle onsaved)
{
    super.onCreate(onsaved);
    setContentView(R.layout.map);
    Log.d("", "entered");


    map = (MapView)findViewById(R.id.mapView);
    }

这是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=".MapsActivity" >

<fragment

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

</RelativeLayout>

这是我的清单文件

        <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.bachelor.bond"
        android:versionCode="1"
        android:versionName="1.0" >

        <uses-sdk
            android:minSdkVersion="14"
            android:targetSdkVersion="17" />
      <!--   <permission
              android:name="com.example.example.permission.MAPS_RECEIVE"
              android:protectionLevel="signature"/>
            <uses-permission android:name="com.bachelor.bond.permission.MAPS_RECEIVE"/>. -->

           <uses-permission android:name="android.permission.INTERNET" />
         <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <permission android:name="com.example.example.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="com.example.example.permission.C2D_MESSAGE" /> 

    <!-- App receives GCM messages. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <!-- GCM connects to Google Services. -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
        <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK"
         />
    <uses-permission android:name="com.example.example.permission.MAPS_RECEIVE"/>
    <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" />  
    <!-- Permission to vibrate -->
        <uses-permission android:name="android.permission.VIBRATE"/>
        <uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION"/>

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

        <uses-feature 
        android:glEsVersion="0x00020000" 
        android:required="true"/>
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name">
            <uses-library android:name="com.google.android.maps" />
             <activity
                android:name=".GPSonMap"
                android:label="@string/app_name"
                 > <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

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

            </activity>

             <uses-library android:name="com.google.android.maps" />
             <intent-filter>
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="com.example.example" />
      </intent-filter>
              <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" 
                 android:permission="com.google.android.c2dm.permission.SEND" >

    </receiver>
     <service android:name=".GCMIntentService" />
     <activity android:name="Login"></activity>

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

        </application>

    </manifest>

并且是Log Cat输出

02-15 00:42:35.257: E/AndroidRuntime(2693): FATAL EXCEPTION: main
02-15 00:42:35.257: E/AndroidRuntime(2693): java.lang.RuntimeException: Unable to start         activity ComponentInfo{com.bachelor.bond/com.dxample.example.GPSonMap}:     android.view.InflateException: Binary XML file line #7: Error inflating class fragment
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.os.Looper.loop(Looper.java:137)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.ActivityThread.main(ActivityThread.java:5039)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at java.lang.reflect.Method.invokeNative(Native Method)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at java.lang.reflect.Method.invoke(Method.java:511)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at dalvik.system.NativeStart.main(Native Method)
02-15 00:42:35.257: E/AndroidRuntime(2693): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class fragment
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.Activity.setContentView(Activity.java:1881)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at com.bachelor.bond.GPSonMap.onCreate(GPSonMap.java:54)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.Activity.performCreate(Activity.java:5104)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
02-15 00:42:35.257: E/AndroidRuntime(2693):     ... 11 more
02-15 00:42:35.257: E/AndroidRuntime(2693): Caused by:         android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment     com.google.android.gms.maps.SupportMapFragment: make sure class name exists, is public, and     has an empty constructor that is public
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.support.v4.app.Fragment.instantiate(Fragment.java:401)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.support.v4.app.Fragment.instantiate(Fragment.java:369)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:272)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676)
02-15 00:42:35.257: E/AndroidRuntime(2693):     ... 21 more
02-15 00:42:35.257: E/AndroidRuntime(2693): Caused by: java.lang.ClassNotFoundException:     Didn't find class "com.google.android.gms.maps.SupportMapFragment" on path:     /system/framework/com.google.android.maps.jar:/data/app/com.bachelor.bond-1.apk
02-15 00:42:35.257: E/AndroidRuntime(2693):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
02-15 00:42:35.257: E/AndroidRuntime(2693):     at android.support.v4.app.Fragment.instantiate(Fragment.java:391)
02-15 00:42:35.257: E/AndroidRuntime(2693):     ... 24 more

我面临的另一个问题是,当我尝试导入com.google.android.gms.maps.MapFragment;时,它会出现错误,无法识别包名为com.google.android.gms,因此我甚至无法使用GoogleMapMapFragment等。

那么有没有人对这两个问题有解决方案呢?

4个回答

8
如何通过Google Maps API v2在Android上显示Google地图。
请注意,必须设置Google Play服务和清单文件中包括几个权限和API密钥的两种情况都是必需的。
1. 在(Support)Fragment中显示Google地图。
main.xml
<?xml version="1.0" encoding="utf-8"?>

<!-- This can go anywhere in your layout (see other demos for some examples). -->
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  class="com.google.android.gms.maps.SupportMapFragment"/>

MainActivity.java

/**
 * This shows how to create a simple activity with a map and a marker on the map.
 * <p>
 * Notice how we deal with the possibility that the Google Play services APK is not
 * installed/enabled/updated on a user's device.
 */
public class BasicMapActivity extends android.support.v4.app.FragmentActivity {
    /**
     * Note that this may be null if the Google Play services APK is not available.
     */
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

    /**
     * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
     * installed) and the map has not already been instantiated.. This will ensure that we only ever
     * call {@link #setUpMap()} once when {@link #mMap} is not null.
     * <p>
     * If it isn't installed {@link SupportMapFragment} (and
     * {@link com.google.android.gms.maps.MapView
     * MapView}) will show a prompt for the user to install/update the Google Play services APK on
     * their device.
     * <p>
     * A user can return to this Activity after following the prompt and correctly
     * installing/updating/enabling the Google Play services. Since the Activity may not have been
     * completely destroyed during this process (it is likely that it would only be stopped or
     * paused), {@link #onCreate(Bundle)} may not be called again so we should call this method in
     * {@link #onResume()} to guarantee that it will be called.
     */
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    /**
     * This is where we can add markers or lines, add listeners or move the camera. In this case, we
     * just add a marker near Africa.
     * <p>
     * This should only be called once and when we are sure that {@link #mMap} is not null.
     */
    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }
}

2. 在(支持)Fragment 中显示 MapView。

main.xml

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

<!-- This can go anywhere in your layout. -->
<com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"/>

MainActivity.java

/**
 * This shows how to create a simple activity with a raw MapView and add a marker to it. This
 * requires forwarding all the important lifecycle methods onto MapView.
 */
public class RawMapViewDemoActivity extends android.support.v4.app.FragmentActivity {
    private MapView mMapView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mMapView = (MapView) findViewById(R.id.map);
        mMapView.onCreate(savedInstanceState);


    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();


    }



    @Override
    protected void onPause() {
        mMapView.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }


}

请问,您能否解释一下我需要在Java Build Path中检查哪些依赖项? - Alberto Crespo

3
我发现你的代码中漏掉了几个东西。
回答1:你的GPSonMAP.java必须按以下方式修改;
public class GPSonMap extends android.support.v4.app.FragmentActivity{
 GoogleMap googlemap;  // "MapView map;" is wrong
 //MapController controller;  ==> it was depreciated.
 LocationManager locationManager;
 LocationListener listener;
 PendingIntent pendingIntent ;
 Criteria criteria;
 //MapOverlay overlay; ==> it was depreciated.
 SupportMapFragment fm; // add this


@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map);
        Log.d("", "entered");


    //map = (MapView)findViewById(R.id.mapView); ==> delete it.

     fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapView);
     googleMap = fm.getMap();
    }


}

在修改完上述内容后,按下"Ctrl + Shft + (字母) O",一些必要的类会被导入。

答案2:您在布局中的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=".GPSonMap" >

你的 MainActivity 不是 MapsActivity,而是 GPSonMap。

答案 3: 你的清单文件中的包名与清单文件中描述的包名不匹配。请将包名与相同的名称匹配。

将“com.example.example”修改为你的包名。

在复制和粘贴一些代码后,你必须至少检查一下包名和类名。


3

可能您的应用程序项目中没有添加对Google Play服务库项目的引用。请参见Google Play服务SDK文档,特别是标题为“设置项目以使用Google Play服务SDK”的部分。


可能很蠢,但我真的不知道该怎么做。我把源代码放到了文件夹google-play-services_lib中,但当我尝试从属性=>安卓中导入此库时,没有任何东西可以供我导入,而且当我再次运行应用程序时,仍然存在同样的问题。 - OmAr Hesham
@omar:“我把源代码放到了 google-play-services_lib 文件夹里”-- 我不知道你在指什么。请在Eclipse中导入'google-play-services_lib' 项目,然后从“Project > Properties > Android > Libraries”添加对它的引用。 - CommonsWare
是的,这很好,但当我要添加一个引用时,当我点击“添加”按钮时,会出现一个空列表。 - OmAr Hesham
@OmArHesham:检查导入的google-play-services_lib项目的Project > Properties > Android,确保“Is Library”复选框已被选中。 - CommonsWare
@CommonsWare... 我认为在这种情况下,“是库”复选框是未选中的。 - BBonDoo
@BBonDoo:不,google-play-services_lib 应该是一个库项目。你的 app 不是一个库项目。 - CommonsWare

0

我曾经遇到了这个问题,浪费了很多时间(超过1.5天的头发被拔光的挫败感)。然后我看了一个沉闷的 YouTube 视频,讲述如何将 Google Play 服务添加到应用程序中。在那个视频中,他们从 SDK 管理器中添加了 SDK 后,使用了 Eclipse 的“检查更新”功能。这个小小的魔法去下载了一个 jar 文件,而 SDK 管理器没有这个功能!他们真的需要把这个加到说明书里,以免让人们产生挫败感。我曾经想把 Google 地图从我的应用程序中删除。我使用的是 1.0 版本,需要升级到 2.0 版本或者放弃地图。


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