2011-08-31 16 views
1

我有一個Android應用程序,我在其中顯示帶有ItemizedOverlay的MapView,並且我希望允許用戶觸摸地圖以將新標記添加到疊加層。我的onTouchEvent方法使用內容提供者爲觸摸的位置創建一個新項目。這個調用populate()。當我第一次觸摸MapView時,size方法正確返回1,但是我得到了ArrauInde​​xOutofBoundsException異常,並且沒有調用createItem方法。無論如何,迄今爲止我還沒有找到解決方案。這裏的異常跟蹤:從ItemizedOverlay.getIndexToDraw拋出的ArrayIndexOutoutBoundsException

08-31 14:55:03.595: ERROR/AndroidRuntime(15897): java.lang.ArrayIndexOutOfBoundsException 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at uk.ac.aber.dcs.hiker_note.HikerNoteActivity$HikerNotesOverlay.draw(HikerNoteActivity.java:85) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.google.android.maps.Overlay.draw(Overlay.java:179) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.google.android.maps.MapView.onDraw(MapView.java:530) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.View.draw(View.java:6933) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.View.draw(View.java:6936) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.View.draw(View.java:6936) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.widget.FrameLayout.draw(FrameLayout.java:357) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.View.draw(View.java:6936) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.widget.FrameLayout.draw(FrameLayout.java:357) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1901) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewRoot.draw(ViewRoot.java:1530) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1266) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1868) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.os.Handler.dispatchMessage(Handler.java:99) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.os.Looper.loop(Looper.java:123) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at android.app.ActivityThread.main(ActivityThread.java:3691) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at java.lang.reflect.Method.invokeNative(Native Method) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at java.lang.reflect.Method.invoke(Method.java:507) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 
08-31 14:55:03.595: ERROR/AndroidRuntime(15897):  at dalvik.system.NativeStart.main(Native Method) 

這裏的ItemizedOverlay子類代碼:

private class HikerNotesOverlay extends ItemizedOverlay<OverlayItem> { 

     private int startX = -1; 
     private int startY = -1; 


     /** 
     * @param marker the push-pin 
     */ 
     public HikerNotesOverlay(Drawable marker) { 
      super(boundCenterBottom(marker));   
      populate(); 
     } 

     /** 
     * @see com.google.android.maps.ItemizedOverlay#size() 
     */ 
     @Override 
     public int size() { 
      int size = 0; 

      // What's the size of the current cursor? There doesn't seem to be a row count request. 
      // Just get back ID field. Unfortunately this also returns a row for each 
      // record, but at least there is only one column 
      String [] projection = new String[]{"_ID"}; 
      try{ 
       Cursor hikerSizeCursor = managedQuery(HikerNote.Notes.CONTENT_URI, projection, null, null, null); 
       size = hikerSizeCursor.getCount(); 
       if (size > 0) Log.i(LOG_TAG, "size: " + size); 
       //hikerSizeCursor.close(); 
      } 
      catch(IllegalStateException ise){ 
       Log.i(LOG_TAG, "size: ILLEGAL_STATE_EXCEPTION IGNORED"); 
      } 
      return size; 
     } 

     @Override 
     public void draw(Canvas canvas, MapView mapView, 
          boolean shadow) { 
      Log.i(LOG_TAG, "draw"); 
      super.draw(canvas, mapView, shadow); 
     } 

     /** 
     * @see com.google.android.maps.ItemizedOverlay#createItem(int) 
     */ 
     @Override 
     protected OverlayItem createItem(int i) { 
      Log.i(LOG_TAG, "createItem: " + i); 
      OverlayItem result = null; 

      // Get the item. We append the item id onto the URI 
      Uri noteUri = ContentUris.withAppendedId(HikerNote.Notes.CONTENT_URI, i); 
      Cursor itemCursor = managedQuery(noteUri, null, null, null, null); 
      if (itemCursor.moveToFirst()) { 

       // Should only be one item in the cursor 
       String comments = itemCursor.getString(HikerNote.COMMENT_COLUMN); 
       int lat = itemCursor.getInt(HikerNote.LATITUDE_COLUMN); 
       int lon = itemCursor.getInt(HikerNote.LONGITUDE_COLUMN); 
       result = new OverlayItem(new GeoPoint(lat, lon), HikerNote.Notes.NOTES_NAME, comments); 
      } 
      //itemCursor.close(); 
      return result; 
     } 

     /** 
     * React to tap events on Map by showing an appropriate detail activity 
     * 
     * @see com.google.android.maps.ItemizedOverlay#onTap(com.google.android.maps.GeoPoint, com.google.android.maps.MapView) 
     */ 
     @Override 
     public boolean onTap(GeoPoint p, MapView mvMap1) { 

      // Do I need to do anything in here to display the overlay item's contents or will the superclass 
      // do this as default behaviour? 
      Log.i(LOG_TAG, "onTap"); 
      return false; // Get the superclass to handle 
     } 


     @Override 
     public boolean onTouchEvent(MotionEvent event, MapView view){ 
      // Touching the view gives us the chance to fire up the addNote activity 
      // so that we can add the note for the given position to the database 
      Log.i(LOG_TAG, "onTouchEvent"); 
      boolean result = false; 
      final int action=event.getAction(); 
      final int x=(int)event.getX(); 
      final int y=(int)event.getY(); 

      if (action==MotionEvent.ACTION_DOWN){ 
       Log.i(LOG_TAG, "onTouchEvent: ACTION_DOWN. x= " + x + " y= " + y); 
       startX = x; 
       startY = y; 
      } 
      else if (action==MotionEvent.ACTION_UP) { 
       // Check to see if any intermediate points. If none then we have a straightforward 
       // touch without drag 
       Log.i(LOG_TAG, "onTouchEvent: ACTION_UP. x= " + x + " y= " + y); 
       if (x==startX && y==startY){ 
        GeoPoint pt = mvMap.getProjection().fromPixels(x,y); 
        Log.i(LOG_TAG, "onTouchEvent: ACTION_UP. geopoint= " + pt); 

        // Now call the AddNote activity with extra geopoint information 
        Intent addNoteIntent = new Intent(HikerNoteActivity.this, AddNote.class); 
        addNoteIntent.putExtra(AddNote.LOCATION_LATITUDE, pt.getLatitudeE6()); 
        addNoteIntent.putExtra(AddNote.LOCATION_LONGITUDE, pt.getLongitudeE6()); 
        HikerNoteActivity.this.startActivity(addNoteIntent); 

        result = true; 
        startX = -1; 
        startY = -1; 

        //setLastFocusedIndex(-1); 
        populate(); 
       } 

      } 
      //return result || super.onTouchEvent(event, view); 
      return result; 
     } 
    } 

感謝

回答