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.