开发者

ArrayIndexOutoutBoundsException thrown from ItemizedOverlay.getIndexToDraw

I have an Android app where I display a MapView with an ItemizedOverlay and where I want to allow users to touch the map to add new markers to the overlay. My onTouchEvent method uses an content provider to create a new item for the position touched. This calls populate(). When I touch the MapView for the first time the size method correctly returns 1 but I then get the ArrauIndexOutofBoundsException exception and no call to createItem method. Anyway so far I haven't discovered a solution. Here's the exception trace:

    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)

Here's the ItemizedOverlay subclass code:

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 Int开发者_Go百科ent(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;
        }
    }

Thanks


You probably should uncomment this line: //setLastFocusedIndex(-1); Whenever your list of elements change you should call setLastFocusedIndex(-1) before you call populate() It is documented here: http://groups.google.com/group/android-developers/browse_thread/thread/38b11314e34714c3

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜