android中的Mapapi v2导致片段错误

时间:2013-03-01 06:49:00

标签: android android-fragments google-maps-api-2

我在fragment的地图实施中遇到的问题很少。 以下是我的代码。

import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.tfick.android.R;

public class PoiFragment extends Fragment{

private GoogleMap mGoogleMap;

private static final LatLng SYDNEY = new LatLng(23.03,72.62);

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View v=inflater.inflate(R.layout.poi_fragment, container,false);


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

     if(mGoogleMap ==null){

            /*initializing map */

            mGoogleMap=mMapFragment.getMap();

            /*cretaing custom camera position*/

            CameraPosition mCameraPosition=new CameraPosition.Builder().target(SYDNEY).bearing(0).tilt(30).build();

            /*setting custom camera position*/

            mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));

            /*adding custom marker on the map.*/
             mGoogleMap.addMarker(new MarkerOptions().draggable(true).position(new LatLng(22.03, 72.56)).title("hello world").snippet("Ahmedabad").icon(BitmapDescriptorFactory.fromResource(R.drawable.wifi)));

            mGoogleMap.addMarker(new MarkerOptions().draggable(true).position(new LatLng(23.03, 78.10)).title("hello world").snippet("Baroda").icon(BitmapDescriptorFactory.fromResource(R.drawable.wifi)));

        }

        if(mGoogleMap !=null){


            /* map is already initialized then setting map type */
            /*
             * normal 
             * satellite
             * hybrid
             * terrain
             * none
             */
            mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        }

    return v;
}
}
03-01 12:15:31.439: E/AndroidRuntime(9299): FATAL EXCEPTION: main
03-01 12:15:31.439: E/AndroidRuntime(9299): java.lang.RuntimeException: Unable to start activity    ComponentInfo{com.tfick.android/com.tfick.android.PointOfIntrest}: java.lang.NullPointerException: CameraUpdateFactory is not initialized
03-01 12:15:31.439: E/AndroidRuntime(9299):     at    android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.ActivityThread.access$600(ActivityThread.java:140)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.os.Looper.loop(Looper.java:137)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at  android.app.ActivityThread.main(ActivityThread.java:4898)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at java.lang.reflect.Method.invokeNative(Native Method)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at java.lang.reflect.Method.invoke(Method.java:511)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at dalvik.system.NativeStart.main(Native Method)
03-01 12:15:31.439: E/AndroidRuntime(9299): Caused by: java.lang.NullPointerException: CameraUpdateFactory is not initialized
03-01 12:15:31.439: E/AndroidRuntime(9299):     at com.google.android.gms.internal.at.a(Unknown Source)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at com.google.android.gms.maps.CameraUpdateFactory.J(Unknown Source)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at com.google.android.gms.maps.CameraUpdateFactory.newCameraPosition(Unknown Source)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at com.tfick.fragment.PoiFragment.onCreateView(PoiFragment.java:51)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:829)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.BackStackRecord.run(BackStackRecord.java:635)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.Activity.performStart(Activity.java:5215)
03-01 12:15:31.439: E/AndroidRuntime(9299):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2073)
03-01 12:15:31.439: E/AndroidRuntime(9299):     ... 11 more

5 个答案:

答案 0 :(得分:1)

感谢我,我找到了解决方案 如果有任何一次有相同问题,请使用以下代码。

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.tfick.android.R;

public class PoiFragment extends MapFragment {
    /*object of google map*/
    public GoogleMap mGoogleMap;
    /* summy location*/
    private static final LatLng SYDNEY = new LatLng(23.03, 72.62);


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);

        if (getMap() != null) {
            Log.d(getClass().getSimpleName(), "Map ready for use!");

            mGoogleMap = getMap();

            /* cretaing custom camera position */

            CameraPosition mCameraPosition = new CameraPosition.Builder()
                    .target(SYDNEY).bearing(0).tilt(30).build();
            Log.i("gmap", mGoogleMap.toString());

            /* setting custom camera position */

            mGoogleMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(mCameraPosition));

            /* adding custom marker on the map. */
            mGoogleMap
                    .addMarker(new MarkerOptions()
                            .draggable(true)
                            .position(new LatLng(22.03, 72.56))
                            .title("hello world")
                            .snippet("Ahmedabad")
                            .icon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.wifi)));

            mGoogleMap
                    .addMarker(new MarkerOptions()
                            .draggable(true)
                            .position(new LatLng(23.03, 78.10))
                            .title("hello world")
                            .snippet("Baroda")
                            .icon(BitmapDescriptorFactory
                                    .fromResource(R.drawable.wifi)));

        }

    }

}

答案 1 :(得分:0)

初始化CameraUpdateFactory。
根据文档 -
致电初始化(上下文)。只要不引发 GooglePlayServicesNotAvailableException ,就会正确初始化此类。

链结
http://developer.android.com/reference/com/google/android/gms/maps/MapsInitializer.html#initialize(android.content.Context)
如何初始化 -

try {
     MapsInitializer.initialize(this /*the context*/);
 } catch (GooglePlayServicesNotAvailableException e) {
     e.printStackTrace();
 }

参考 - mapview and cameraupdate in api v2

答案 2 :(得分:0)

问题是getMap()返回null,因此CameraUpdateFactory会抛出异常,因为它需要初始化GoogleMap

MapFragment内使用Fragment时遇到类似问题。我通过将地图初始化移动到OnResume来解决它。

答案 3 :(得分:0)

Google地图实现在很大程度上依赖于几种生命周期方法(onCreate,onCreateView,onDestroy,onResume和onPause)。如果将这些调用封装在自己的片段中,则应将这些调用中继到MapFragment。在调用mapView.getMap()并获得GoogleMap后,应该已经初始化了地图。

如果你从getMap()得到null,可能会发生几件事:

  • 您没有在MapFragment上调用onCreate和/或onCreateView(在这些方法之后调用getMap())
  • 您缺少清单中的OpenGL ES 2功能条目
  • 您缺少地图所需的权限
  • 设备上未安装Google Play SDK服务,或者它们太旧了

我在StackOverflow上经常阅读初始化(this)解决方案,但在大多数情况下实际上并不需要它。

修改 我刚看到你正在通过一个事务添加Mapfragment。您是否考虑在PoiFragment中使用MapView?我相信通过使用MapFragment并通过事务添加它会产生计时问题。当您仍在PoiFragment.onCreateView方法中时,事务可能尚未完成(因此尚未初始化Maps)。您可以尝试使用onResume,但是您必须确保只启动地图代码一次,因为onResume会被更频繁地调用。

我在架构方面的建议:

  • 如果可行,请直接在您的活动中使用MapFragment
  • 如果您有足够的代码放在那里,请扩展Mapfragment

答案 4 :(得分:0)

我遇到了完全相同的问题。当getMap()返回null时会发生此错误。

我做了以下事情:

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
googleMap = mapFragment.getMap();

/* if googleMap == null then there may be following problem :
 * 1. google play service version are not matching on both device and installed apk.Will show update message on map.
 * 2. No google play service installed. Will show a install message on map.
 */
if (googleMap != null) {
    LatLng iniLoc = new LatLng(44.97651081283853, -93.2245754142059);
    googleMap.moveCamera(CameraUpdateFactory.newLatLng(iniLoc));
    googleMap.getUiSettings().setZoomGesturesEnabled(false);
    currentMarkerOption = new MarkerOptions();
    currentMarkerOption.position(iniLoc);
    currentMarker = googleMap.addMarker(currentMarkerOption);
    currentMarker.setIcon((BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
    currentMarker.setTitle("Current Position");
    currentMarker.showInfoWindow();
    currentMarker.setVisible(false);
    initDestinationMarker();
}