简体   繁体   中英

App force closes when I try to place a marker on my map overlay

In this app i have enabled the user the option to long click that brings up an alert. This alert then has 2 buttons that the user can choose from. The first allows the use to place a marker on the map at the location that was long clicked and the second gets the address of the location that was long clicked. The address button works but, the marker button force closes my app. I'm not sure what i'm doing wrong. Its probably something stupid.

Here is the method from my main class:

 @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    /*
     * We want to capture the place the user long pressed on the map and add
     * a marker (pin) on the map at that lat/long. This solution: 1. Allows
     * you to set the time threshold for what constitutes a long press 2.
     * Doesn't get fooled by scrolling, multi-touch, or non-multi-touch
     * events
     * 
     * Thank you Roger Kind Kristiansen for the main idea
     */

    // get the action from the MotionEvent: down, move, or up
    int actionType = ev.getAction();

    if (actionType == MotionEvent.ACTION_DOWN) {
        // user pressed the button down so let's initialize the main
        // variables that we care about:
        // later on when the "Action Up" event fires, the "DownTime" should
        // match the "startTimeForLongClick" that we set here
        // the coordinate on the screen should not change much during the
        // long press

        startTimeForLongClick = ev.getEventTime();
        xScreenCoordinateForLongClick = ev.getX();
        yScreenCoordinateForLongClick = ev.getY();

    } else if (actionType == MotionEvent.ACTION_MOVE) {
        // For non-long press actions, the move action can happen a lot
        // between ACTION_DOWN and ACTION_UP
        if (ev.getPointerCount() > 1) {
            // easiest way to detect a multi-touch even is if the pointer
            // count is greater than 1
            // next thing to look at is if the x and y coordinates of the
            // person's finger change.
            startTimeForLongClick = 0; // instead of a timer, just reset
                                        // this class variable and in our
                                        // ACTION_UP event, the DownTime
                                        // value will not match and so we
                                        // can reset.
        } else {
            // I know that I am getting to the same action as above,
            // startTimeForLongClick=0, but I want the processor
            // to quickly skip over this step if it detects the pointer
            // count > 1 above
            float xmove = ev.getX(); // where is their finger now?
            float ymove = ev.getY();
            // these next four values allow you set a tiny box around their
            // finger in case
            // they don't perfectly keep their finger still on a long click.
            xlow = xScreenCoordinateForLongClick - xtolerance;
            xhigh = xScreenCoordinateForLongClick + xtolerance;
            ylow = yScreenCoordinateForLongClick - ytolerance;
            yhigh = yScreenCoordinateForLongClick + ytolerance;
            if ((xmove < xlow || xmove > xhigh)
                    || (ymove < ylow || ymove > yhigh)) {
                // out of the range of an acceptable long press, reset the
                // whole process
                startTimeForLongClick = 0;

            }

        }

    } else if (actionType == MotionEvent.ACTION_UP) {
        // determine if this was a long click:
        long eventTime = ev.getEventTime();
        long downTime = ev.getDownTime(); // this value will match the
                                            // startTimeForLongClick
                                            // variable as long as we didn't
                                            // reset the
                                            // startTimeForLongClick
                                            // variable because we detected
                                            // nonsense that invalidated a
                                            // long press in the ACTION_MOVE
                                            // block

        // make sure the start time for the original "down event" is the
        // same as this event's "downTime"
        if (startTimeForLongClick == downTime) {
            // see if the event time minus the start time is within the
            // threshold
            if ((eventTime - startTimeForLongClick) > minMillisecondThresholdForLongClick) {
                // make sure we are at the same spot where we started the
                // long click
                float xup = ev.getX();
                float yup = ev.getY();
                // I don't want the overhead of a function call:
                xlow = xScreenCoordinateForLongClick - xtolerance;
                xhigh = xScreenCoordinateForLongClick + xtolerance;
                ylow = yScreenCoordinateForLongClick - ytolerance;
                yhigh = yScreenCoordinateForLongClick + ytolerance;
                if ((xup > xlow && xup < xhigh)
                        && (yup > ylow && yup < yhigh)) {

                    // **** safe to process your code for an actual long
                    // press ****
                    // comment out these next rows after you confirm in
                    // logcat that the long press works
                    long totaltime = eventTime - startTimeForLongClick;
                    String strtotaltime = Long.toString(totaltime);
                    Log.d("long press detected: ", strtotaltime);
                    // Below is code from my touchy class

                    x = (int) ev.getX();
                    y = (int) ev.getY();
                    touchPoint = mapView.getProjection().fromPixels(x, y);

                    Builder alert = new AlertDialog.Builder(Map.this);
                    alert.setTitle("Pick an option.");
                    alert.setNeutralButton("Place a marker",
                            new DialogInterface.OnClickListener() {

                                public void onClick(DialogInterface dialog,
                                        int which) {

                                    OverlayItem overlayItem = new OverlayItem(
                                            touchPoint, "What's up", "2nd String");
                                    Mark custom = new Mark(d, Map.this);
                                    custom.dropMarker(overlayItem);
                                    mapoverlays.add(custom);

                                }
                            });
                    alert.setPositiveButton("Get Address",
                            new DialogInterface.OnClickListener() {

                                public void onClick(DialogInterface dialog,
                                        int which) {

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

                                    try {

                                        List<Address> address = geocoder.getFromLocation(
                                                touchPoint.getLatitudeE6() / 1E6,
                                                touchPoint.getLongitudeE6() / 1E6,
                                                1);
                                        if (address.size() > 0) {
                                            String display = "";
                                            for (int i = 0; i < address.get(0)
                                                    .getMaxAddressLineIndex(); i++) {

                                                display += address.get(0)
                                                        .getAddressLine(i) + "\n";
                                            }

                                            Toast t = Toast.makeText(
                                                    getBaseContext(), display,
                                                    Toast.LENGTH_LONG);
                                            t.show();
                                        }
                                    } catch (IOException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    } finally {

                                    }

                                }
                            });

                    alert.show();

                }

            }
        }

    }

    return super.dispatchTouchEvent(ev);
}

Here is my Mark class:

 package com.almyz125.stamp.overlay;

 import java.util.ArrayList;

 import android.content.Context;
 import android.graphics.drawable.Drawable;

 import com.google.android.maps.ItemizedOverlay;
 import com.google.android.maps.OverlayItem;

  public class Mark extends ItemizedOverlay<OverlayItem>{

private ArrayList<OverlayItem> markers = new ArrayList<OverlayItem>();
private Context c;



public Mark(Drawable defaultMarker) {
    super(boundCenter(defaultMarker));
    // TODO Auto-generated constructor stub
}

public Mark(Drawable m, Context context){
    this(m);
    c = context;

}

@Override
protected OverlayItem createItem(int i) {
    // TODO Auto-generated method stub
    return markers.get(i);
}

@Override
public int size() {
    // TODO Auto-generated method stub
    return markers.size();
}

public void dropMarker(OverlayItem item){
    markers.add(item);
    this.populate();
}

}

Here is my logcat when the app experiences a FC:

 10-30 13:51:25.548: W/dalvikvm(17616): threadid=1: thread exiting with uncaught       exception (group=0x40dd11f8)
 10-30 13:51:25.548: E/AndroidRuntime(17616): FATAL EXCEPTION: main
 10-30 13:51:25.548: E/AndroidRuntime(17616): java.lang.NullPointerException
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.google.android.maps.ItemizedOverlay.boundCenter(ItemizedOverlay.java:173)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.almyz125.stamp.overlay.Mark. <init>(Mark.java:19)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.almyz125.stamp.overlay.Mark.<init>(Mark.java:24)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.almyz125.stamp.Map$2.onClick(Map.java:255)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at android.os.Handler.dispatchMessage(Handler.java:99)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at android.os.Looper.loop(Looper.java:137)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at android.app.ActivityThread.main(ActivityThread.java:4499)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at java.lang.reflect.Method.invokeNative(Native Method)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at java.lang.reflect.Method.invoke(Method.java:511)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
 10-30 13:51:25.548: E/AndroidRuntime(17616):   at dalvik.system.NativeStart.main(Native Method)

Let me know if I should post more code, any help would be appreciated!

您传递给Mark构造函数的drawable d似乎为null

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM