2012-10-13 65 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

相關問題