2012-10-13 54 views
0

这在一个有点复杂的问题,所以仔细阅读。致命错误,当我尝试启动我的自定义MapActivity

我试图实现一个地图,

- 显示我的当前位置,

- 当我点击在地图上的一个点,应用程序应该把自定义的GeoPoint获取经纬度传递这些以活动来创建一个新的酒吧对象

-the地图上开始必须出示酒馆的位置

之前保存继this tutorial我创建了这些类

类MyMap中

public class MyMap extends MapActivity implements LocationListener { 
    private MapView mapView; 
    private LocationManager locManager; 
    private MapLocationOverlay itemizedOverlay; 
    GeoPoint point ; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // Inflate our UI from its XML layout description. 
     setContentView(R.layout.mymap); 

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

     // invalidate the map in order to show changes 
     mapView.invalidate(); 

     MapController controller = mapView.getController(); 


     // Use the location manager through GPS 
     locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 
       0, this); 

     //get the current location (last known location) from the location manager 
     Location location = locManager 
       .getLastKnownLocation(LocationManager.GPS_PROVIDER); 



      //if location found display as a toast the current latitude and longitude 
     if (location != null) { 
      point = new GeoPoint((int)(location.getLatitude()*1E6),(int)(location.getLongitude() *1E6)); 
      Toast.makeText(
        this, 
        "Current location:\nLatitude: " + location.getLatitude() 
          + "\n" + "Longitude: " + location.getLongitude(), 
        Toast.LENGTH_LONG).show(); 


      controller.animateTo(point); 
      controller.setZoom(13); 

     } else { 

      Toast.makeText(this, "Cannot fetch current location!", 
        Toast.LENGTH_LONG).show(); 
     } 


     // fetch the drawable - the pin that will be displayed on the map 
     Drawable drawable = this.getResources().getDrawable(R.drawable.pin_custom); 

     // create and add an OverlayItem to the MyItemizedOverlay list 
     OverlayItem overlayItem = new OverlayItem(point, "", ""); 
     itemizedOverlay = new MapLocationOverlay(drawable,this); 
     itemizedOverlay.addOverlay(overlayItem); 

     // add the overlays to the map 
     mapView.getOverlays().add(itemizedOverlay); 
     mapView.invalidate(); 

     GestureDetector gd=new GestureDetector(this, new MyGestureDetector()); 
     itemizedOverlay.setGestureDetector(gd); 

     //when the current location is found – stop listening for updates (preserves battery) 
     locManager.removeUpdates(this); 
    } 





    protected boolean isRouteDisplayed() { 
     return false; 

    } 

    /* When the activity starts up, request updates */ 

    protected void onResume() { 
     super.onResume(); 
     locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 
       0, this); 
    } 


    protected void onPause() { 
     super.onPause(); 
     locManager.removeUpdates(this); //activity pauses => stop listening for updates 
    } 

    public void onLocationChanged(Location location) { 

    } 



    public void onProviderDisabled(String provider) { 

    } 


    public void onProviderEnabled(String provider) { 

    } 


    public void onStatusChanged(String provider, int status, Bundle extras) { 

    } 

    public class MyGestureDetector extends SimpleOnGestureListener { 


     public boolean onSingleTapConfirmed(MotionEvent event) { 

      // fetch the correspondent point from the map 
      GeoPoint p = mapView.getProjection().fromPixels((int) event.getX(),(int) event.getY()); 

      // create an overlay item and clear all others 
      OverlayItem o = new OverlayItem(p, null, null); 
      itemizedOverlay.clear(); 
      itemizedOverlay.addOverlay(o); 

      // add the overlay item 
      mapView.getOverlays().clear(); 
      mapView.getOverlays().add(itemizedOverlay); 
      mapView.invalidate(); 

      Geocoder geoCoder = new Geocoder(getBaseContext(), 
        Locale.getDefault()); 

      // get the address based on the coordinates 
      try { 
       List<Address> addresses = geoCoder.getFromLocation(p.getLatitudeE6()/1E6, p.getLongitudeE6()/1E6, 1); 

       String addressString = ""; 
       if (addresses.size() > 0) { 
        for (int i = 0; i < addresses.get(0) 
          .getMaxAddressLineIndex(); i++) 
         addressString += addresses.get(0).getAddressLine(i) 
           + " - "; 
       } 

       Toast.makeText(getBaseContext(), addressString, 
         Toast.LENGTH_SHORT).show(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      return true; 
     } 

     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 
       float velocityY) { 
      return super.onFling(e1, e2, velocityX, velocityY); 
     } 

     public boolean onDown(MotionEvent e) { 
      return false; 
     } 
    } 


} 

和类MapLocationOverlay

public class MapLocationOverlay extends ItemizedOverlay<OverlayItem> { 

     private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>(); 
     private GestureDetector gestureDetector; 

     private List<Pub> pubList; 
     private Context context; 



     public MapLocationOverlay(Context context, List<Pub> pubList, Drawable marker) { 
      super(boundCenterBottom(marker)); 
      try{ 
       this.context = context; 
       this.pubList = pubList; 
       if (pubList == null) { 
        pubList = new ArrayList<Pub>(); 
       } 
       populate(); 
      } 
      catch(RuntimeException e){ 

      } 

     } 

     public MapLocationOverlay(Drawable defaultMarker, Context ctx) { 
      super(boundCenterBottom(defaultMarker)); 

     } 

     @Override 
     protected OverlayItem createItem(int i) { 
      try{ 
      Pub c=pubList.get(i); 
       GeoPoint point = 
         new GeoPoint((int) (c.getLatitude() * 1e6), (int) (c.getLongitude() * 1e6)); 
       return new OverlayItem(point, c.getName(), null); 
      } 
      catch(RuntimeException e){ 

      } 
      return mOverlays.get(i); 
     } 

     public void addOverlay(OverlayItem overlay) { 
      mOverlays.add(overlay); 
      populate(); 
     } 

     public void clear() { 

      mOverlays.clear(); 
      populate(); 
     } 

     @Override 
     public boolean onTap(final int index) { 
      Pub c=pubList.get(index); 
      final String name=c.getName(); 
      final String description=c.getDescription(); 
      final String street=c.getStreet(); 
     // BrewLocation brewLocation = brewLocations.get(index); 
      AlertDialog.Builder builder = new AlertDialog.Builder(context); 
      builder.setTitle("Visualizzare la nota "+name+"?") 
        .setPositiveButton("Si", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int id) { 
         Intent pubDetails = new Intent(context, InfoPub.class); 
         pubDetails.putExtra("name", name); 
         pubDetails.putExtra("description", description); 
         pubDetails.putExtra("street", street); 
         context.startActivity(pubDetails); 
         } 
        }).setNegativeButton("No", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int id) { 
         dialog.cancel(); 
         } 
        }); 
      AlertDialog alert = builder.create(); 
      alert.show(); 

      return true; // we'll handle the event here (true) not pass to another overlay (false) 
     } 


     /** 
     * Override this method to handle a "tap" on a balloon. By default, does nothing 
     * and returns false. 
     * 
     * @param index - The index of the item whose balloon is tapped. 
     * @return true if you handled the tap, otherwise false. 
     */ 
     protected boolean onBalloonTap(int index) { 
      return false; 
     } 

      @Override 
      public boolean onTouchEvent(MotionEvent event, MapView mapView) { 

       // when the user lifts its finger 
       if (gestureDetector.onTouchEvent(event)) { 
        return true; 
       } 

       return false; 
       } 

      public GestureDetector getGestureDetector() { 
        return gestureDetector; 
       } 

      public void setGestureDetector(GestureDetector gestureDetector) { 
       this.gestureDetector = gestureDetector; 
      } 

     @Override 
     public int size() { 
      //return pubList.size(); 
      return mOverlays.size(); 
     } 



    } 

不是完全完成,但应该运行,根据教程其次,不幸的是,当我尝试启动活动应用程序崩溃与致命错误。

这是错误堆栈:

10-13 17:25:56.109: E/AndroidRuntime(28215): FATAL EXCEPTION: main 
10-13 17:25:56.109: E/AndroidRuntime(28215): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.myapp.mymapapp/it.myapp.mymapapp.MyMap}: java.lang.NullPointerException 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.os.Handler.dispatchMessage(Handler.java:99) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.os.Looper.loop(Looper.java:130) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.ActivityThread.main(ActivityThread.java:3687) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at java.lang.reflect.Method.invokeNative(Native Method) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at java.lang.reflect.Method.invoke(Method.java:507) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at dalvik.system.NativeStart.main(Native Method) 
10-13 17:25:56.109: E/AndroidRuntime(28215): Caused by: java.lang.NullPointerException 
10-13 17:25:56.109: E/AndroidRuntime(28215): at com.google.android.maps.ItemizedOverlay.populate(ItemizedOverlay.java:312) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at it.myapp.mymapapp.utility.MapLocationOverlay.addOverlay(MapLocationOverlay.java:72) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at it.myapp.mymapapp.MyMap.onCreate(MyMap.java:89) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
10-13 17:25:56.109: E/AndroidRuntime(28215): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615) 
10-13 17:25:56.109: E/AndroidRuntime(28215): ... 11 more 

我怎么能解决这个问题? 缺少什么?

+0

您是否在清单文件中添加了适当的权限? –

+0

你有一个空指针在第312行 - 在com.google.android.maps.ItemizedOverlay.populate(ItemizedOverlay.java:312)这是什么行? – Simon

+0

@ShashankKadne是有所有的权限, – AndreaF

回答

1

您并未初始化pointonCreate(),除非您获得有效的lastKnownLocation()

这个未初始化的point被添加到OverlayItem,它被添加到ItemizedOverlay。

当Mapview试图让Geopoint绘制标记时,它会得到一个null和bummmm!

只需更换:

由:

GeoPoint point = new Geopoint(0,0); 

,它不会再崩溃。

+0

谢谢你的回答!这是导致崩溃的原因......但是地图不起作用,冻结在起始位置,我什么都不能做:当我尝试点击某个地方时,不滚动,也没有发生任何事情。是什么原因? – AndreaF

+0

问题出在你的MyGestureDetector类上。你在多于一个地方使用'return true',你不应该这样做。只有当你使用运动事件来做某件事情时,你才应该返回true,否则你应该'返回false'来告知运动事件可以被其他类使用(即Mapview移动地图)。 – Luis

0

createItem()实现相当奇怪:

  1. 你抓RuntimeException,什么也不做它。如果没有别的,你应该记录异常,特别是只要你的代码有问题。

  2. size()方法是基于关闭的mOverlays,但你不使用createItem()mOverlays(除非发生不当RuntimeException)。请始终使用mOverlays或完全清除它。

除此之外,一些ItemizedOverlay预计不会null确实null。一种可能性是“片段”(第OverlayItem构造函数的第三个参数),您将其设置为null。另一种可能性是c.getName()正在返回null,或许ItemizedOverlay需要名称为非null

如果没有别的,回到原来的代码从那个博客文章,得到那个工作,然后缓慢修改它有你想要的功能,随时测试。

+0

我已经成功地使用过多次地图叠加以显示我的位置和通过列表的位置上的地理位置,但我有问题也实现了一个函数,以在点击的位置放置一个新的地理位置,所以我已将我的解决方案与代码合并以获得点击上的坐标,但不幸的是没有似乎工作,所以我已经放了一些尝试赶上,看看这个班是否忽略了关键的代码块......但没有,不知道如何获得一个工作实现来解决我的问题。 (对不起,我的英文不好) – AndreaF

相关问题