2

I just registered an OnLongClickListener on my my MapView on an Android app I'm currently writing. For some reason however the onLongClick event doesn't fire.

Here's what I've written so far:

public class FriendMapActivity extends MapActivity implements OnLongClickListener {
    private static final int CENTER_MAP = Menu.FIRST;
    private MapView mapView;
    private MapController mapController;
    //...
    private boolean doCenterMap = true;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.friendmapview);
        this.mapView = (MapView) findViewById(R.id.map_view);
        this.mapController = mapView.getController();

        mapView.setBuiltInZoomControls(true);
        mapView.displayZoomControls(true);
        mapView.setLongClickable(true);
        mapView.setOnLongClickListener(new OnLongClickListener() {
            public boolean onLongClick(View v) {
                //NEVER FIRES!!
                return false;
            }
        });

        //...
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
        case KeyEvent.KEYCODE_3:
            mapController.zoomIn();
            break;
        case KeyEvent.KEYCODE_1:
            mapController.zoomOut();
            break;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int actionType = ev.getAction();
        switch (actionType) {
        case MotionEvent.ACTION_MOVE:
            doCenterMap = false;
            break;
        }

        return super.dispatchTouchEvent(ev);
    }

        ...
}

May overlays which I'm adding cause the problem?? Any suggestions?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
Juri
  • 32,424
  • 20
  • 102
  • 136

4 Answers4

3

I ran into the same problem and there is a simple solution to your problem actually; it's because you're using the wrong type of listener.

You should use the OnMapLongClickListener() object from the OnMapLongClickListener interface.

Hopefully everything should work properly :) Please tell me if it works.

Jimbo
  • 25,790
  • 15
  • 86
  • 131
NerdHamel
  • 390
  • 4
  • 5
  • Maybe this is something they have introduced on a later version. I can't remember to have seen such an event at the time I was implementing this functionality. – Juri Jan 22 '13 at 14:35
2

In the mean time I found the "solution" (or workaround, call it as you like) by myself. The way I worked through this issue is by using a GestureDetector and forwarding all touch events to that object by implementing an according OnGestureListener interface.

I've posted some code on my blog if anyone is interested: http://juristr.com/blog/2009/12/mapview-doesnt-fire-onlongclick-event/

Don't ask me why this didn't work by hooking up the OnLongClickListener directly on the MapView. If someone has an explanation let me know :)

UPDATE:
My previously suggested solution using a GestureDetector posed some drawbacks. So I updated the blog post on my site.

Juri
  • 32,424
  • 20
  • 102
  • 136
2

I just ran into this problem. I tried the solution above, but it doesn't quite work 100% in that we want the long press action to fire, even if the user is still holding a finger down.

This is how I implemented a solution, using a handler and a delayed task - As a side note, I used a similar type implementation, but in reverse, to hide/show zoom controls on touch/etc..

private Handler mHandler = new Handler();

private final Runnable mTask = new Runnable() {
    @Override
    public void run() {
        // your code here
    }
};

@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        // record the start time, start the timer
        mEventStartTime = ev.getEventTime();
        mHandler.postDelayed(mTask, LONG_PRESS_TIME);
    } else if (ev.getAction() == MotionEvent.ACTION_UP) {
        // record the end time, dont show if not long enough
        mEventEndTime = ev.getEventTime();
        if (mEventEndTime - mEventStartTime < LONG_PRESS_TIME) {
            mHandler.removeCallbacks(mTask);        
        }
    } else {
        // moving, panning, etc .. up to you whether you want to
        // count this as a long press - reset timing to start from now
                    mEventStartTime = ev.getEventTime();
        mHandler.removeCallbacks(mTask);
                    mHandler.postDelayed(mTask, LONG_PRESS_TIME);
    }

    return super.onTouchEvent(ev);
}
ratana
  • 175
  • 3
  • 12
0

In WebView framework code performLongClick() is used to handle long press event, this is how Android copy Text Feature is implemented in Browser, that is why onLongClick is not been fired.

Pratik Sharma
  • 1,435
  • 1
  • 9
  • 3