0

このアプリでは、アラートを表示するロングクリックのオプションをユーザーに有効にしました。このアラートには、ユーザーが選択できる 2 つのボタンがあります。1 つ目は、地図上で長くクリックされた場所にマーカーを配置することを可能にし、2 つ目は、長くクリックされた場所の住所を取得します。アドレス ボタンは機能しますが、マーカー ボタンを押すとアプリが閉じます。何が間違っているのかわかりません。それはおそらく愚かなことです。

これが私のメインクラスのメソッドです:

 @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);
}

ここに私のマーククラスがあります:

 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();
}

}

アプリで FC が発生したときの logcat は次のとおりです。

 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)

さらにコードを投稿する必要がある場合はお知らせください。

4

1 に答える 1

0

Mark コンストラクターに渡す drawable d が null のようです

于 2012-10-30T19:53:36.660 に答える