在我的应用程序中,我要求用户在自动完成文本框中输入一个位置,我能够从 JSON 对象成功获取位置,并且我成功地提取了经度和纬度并为这些位置创建了一个 GeoPoint。我在为所需的 GeoPoint 创建覆盖项时遇到问题。
以下是我在 SiteOverlay 构造函数中的 ItemziedOverlay 类的代码,我正在使用新的位置覆盖来绘制和调用 populate() 但没有成功,它一直说 Null 点 ItemizedOverlay。
private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
private Drawable marker = null;
private OverlayItem inDrag = null;
private ImageView dragImage = null;
private int xDragImageOffset = 0;
private int yDragImageOffset = 0;
private int xDragTouchOffset = 0;
private int yDragTouchOffset = 0;
public SitesOverlay(Drawable marker) {
super(marker);
this.marker = marker;
dragImage = (ImageView) findViewById(R.id.drag);
xDragImageOffset = dragImage.getDrawable().getIntrinsicWidth() / 2;
yDragImageOffset = dragImage.getDrawable().getIntrinsicHeight();
// items.add(new OverlayItem(getPoint(24.893379, 67.028061),
// "Karachi", "Sindh, Pakistan"));
}
public SitesOverlay(Drawable marker, OverlayItem newlocationItem) {
super(marker);
this.marker = marker;
dragImage = (ImageView) findViewById(R.id.drag);
xDragImageOffset = dragImage.getDrawable().getIntrinsicWidth() / 2;
yDragImageOffset = dragImage.getDrawable().getIntrinsicHeight();
// items.add(new OverlayItem(getPoint(24.893379, 67.028061),
// "Karachi", "Sindh, Pakistan"));
items.add(newlocationItem);
populate();
}
@Override
protected boolean onTap(int index) {
// TODO Auto-generated method stub
OverlayItem item = items.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(
getApplicationContext());
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return super.onTap(index);
}
@Override
protected OverlayItem createItem(int i) {
return (items.get(i));
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
boundCenterBottom(marker);
}
@Override
public int size() {
return (items.size());
}
@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
final int action = event.getAction();
final int x = (int) event.getX();
final int y = (int) event.getY();
boolean result = false;
if (action == MotionEvent.ACTION_DOWN) {
for (OverlayItem item : items) {
Point p = new Point(0, 0);
map.getProjection().toPixels(item.getPoint(), p);
if (hitTest(item, marker, x - p.x, y - p.y)) {
result = true;
inDrag = item;
items.remove(inDrag);
populate();
xDragTouchOffset = 0;
yDragTouchOffset = 0;
setDragImagePosition(p.x, p.y);
dragImage.setVisibility(View.VISIBLE);
xDragTouchOffset = x - p.x;
yDragTouchOffset = y - p.y;
break;
}
}
} else if (action == MotionEvent.ACTION_MOVE && inDrag != null) {
setDragImagePosition(x, y);
result = true;
} else if (action == MotionEvent.ACTION_UP && inDrag != null) {
dragImage.setVisibility(View.GONE);
GeoPoint pt = map.getProjection().fromPixels(
x - xDragTouchOffset, y - yDragTouchOffset);
OverlayItem toDrop = new OverlayItem(pt, inDrag.getTitle(),
inDrag.getSnippet());
Toast.makeText(
MainActivity.this,
"Latitude " + pt.getLatitudeE6() + "," + " "
+ "Longitude " + pt.getLongitudeE6(),
Toast.LENGTH_SHORT).show();
items.add(toDrop);
populate();
inDrag = null;
result = true;
/*
* //--- Get the name of the location by Longitude and
* latitude--- Geocoder geoCoder = new
* Geocoder(getBaseContext(), Locale.getDefault()); try {
* List<Address> addresses = geoCoder.getFromLocation(
* pt.getLatitudeE6() / 1E6, pt.getLongitudeE6() / 1E6, 1);
* String add = ""; if (addresses.size() > 0) { for (int i=0;
* i<addresses.get(0).getMaxAddressLineIndex(); i++) add +=
* addresses.get(0).getAddressLine(i) + "\n"; }
* Toast.makeText(getBaseContext(), add,
* Toast.LENGTH_SHORT).show();
*
* } catch (IOException e) { e.printStackTrace(); }
*/
}
return (result || super.onTouchEvent(event, mapView));
}
private void setDragImagePosition(int x, int y) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) dragImage
.getLayoutParams();
lp.setMargins(x - xDragImageOffset - xDragTouchOffset, y
- yDragImageOffset - yDragTouchOffset, 0, 0);
dragImage.setLayoutParams(lp);
}
}
class GetPlaces extends AsyncTask<String, Void, ArrayList<String>> {
@Override
// three dots is java for an array of strings
protected ArrayList<String> doInBackground(String... args) {
Log.d("gottaGo", "doInBackground");
ArrayList<String> predictionsArr = new ArrayList<String>();
try {
URL googlePlaces = new URL(
// URLEncoder.encode(url,"UTF-8");
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input="
+ URLEncoder.encode(args[0].toString(), "UTF-8")
+ "&types=geocode&language=en&sensor=true&key=AIzaSyBBILczt124ZWZHlSYsB6hb_Fqjb2nFEaE");
URLConnection tc = googlePlaces.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
String line;
StringBuffer sb = new StringBuffer();
// take Google's legible JSON and turn it into one big string.
while ((line = in.readLine()) != null) {
sb.append(line);
}
// turn that string into a JSON object
JSONObject predictions = new JSONObject(sb.toString());
// now get the JSON array that's inside that object
JSONArray ja = new JSONArray(
predictions.getString("predictions"));
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
// add each entry to our array
predictionsArr.add(jo.getString("description"));
}
} catch (IOException e) {
Log.e("YourApp", "GetPlaces : doInBackground", e);
} catch (JSONException e) {
Log.e("YourApp", "GetPlaces : doInBackground", e);
}
return predictionsArr;
}
// then our post
@Override
protected void onPostExecute(ArrayList<String> result) {
Log.d("YourApp", "onPostExecute : " + result.size());
// update the adapter
adapter = new ArrayAdapter<String>(getBaseContext(),
R.layout.item_list);
adapter.setNotifyOnChange(true);
// attach the adapter to textview
textView.setAdapter(adapter);
for (String string : result) {
Log.d("YourApp", "onPostExecute : result = " + string);
adapter.add(string);
adapter.notifyDataSetChanged();
}
Log.d("YourApp",
"onPostExecute : autoCompleteAdapter" + adapter.getCount());
}
}
我的活动代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;
public class MainActivity extends MapActivity {
private MapView map = null;
private MyLocationOverlay me = null;
Button btn_Go;
Drawable marker;
EditText txtSearch;
AutoCompleteTextView textView;
private static final String API_KEY = "0f7ZWSUbQaZNR9_csQVFdRHpjnARCHAR1WbkFAQ";
ArrayAdapter<String> adapter;
private List<OverlayItem> items = new ArrayList<OverlayItem>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = (MapView) findViewById(R.id.map);
btn_Go = (Button) findViewById(R.id.BtnSearch);
// txtSearch = (EditText) findViewById(R.id.txt_searchbox);
// Set the default Location of push pin
map.getController().setCenter(getPoint(24.893379, 67.028061));
map.setBuiltInZoomControls(true);
marker = getResources().getDrawable(R.drawable.pushpin);
marker.setBounds(0, 0, marker.getIntrinsicWidth(),
marker.getIntrinsicHeight());
map.getOverlays().add(new SitesOverlay(marker));
me = new MyLocationOverlay(this, map);
map.getOverlays().add(me);
adapter = new ArrayAdapter<String>(this, R.layout.item_list);
textView = (AutoCompleteTextView) findViewById(R.id.txtSearchBox);
adapter.setNotifyOnChange(true);
textView.setAdapter(adapter);
textView.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (count % 3 == 1) {
adapter.clear();
GetPlaces task = new GetPlaces();
// now pass the argument in the textview to the task
task.execute(textView.getText().toString());
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable s) {
}
});
}
public void GoTolocation(View v) {
String value = textView.getText().toString();
// Do something with value!
Log.d("value", value);
MapController mc = map.getController();
JSONObject Response = getLocationInfo(value);
GeoPoint p = getGeoPoint(Response);
// map.getOverlays().remove(0);
// map.getController().setCenter(getPoint(24.893379, 67.028061));
map.getController().setCenter(p);
map.setBuiltInZoomControls(true);
marker = getResources().getDrawable(R.drawable.pushpin);
marker.setBounds(0, 0, marker.getIntrinsicWidth(),
marker.getIntrinsicHeight());
OverlayItem newlocation = new OverlayItem(p, value,
"You Selected This place");
SitesOverlay s = new SitesOverlay(marker, newlocation);
// s.SetPoint(newlocation);
map.getOverlays().add(s);
me = new MyLocationOverlay(this, map);
map.getOverlays().add(me);
mc.setZoom(10);
mc.animateTo(p);
map.invalidate();
}
public static JSONObject getLocationInfo(String address) {
StringBuilder stringBuilder = new StringBuilder();
try {
address = address.replaceAll(" ", "%20");
HttpPost httppost = new HttpPost(
"http://maps.google.com/maps/api/geocode/json?address="
+ address + "&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
stringBuilder = new StringBuilder();
response = client.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
JSONObject jsonObject = new JSONObject();
try {
jsonObject = new JSONObject(stringBuilder.toString());
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject;
}
public static GeoPoint getGeoPoint(JSONObject jsonObject) {
Double lon = new Double(0);
Double lat = new Double(0);
try {
lon = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
.getJSONObject("geometry").getJSONObject("location")
.getDouble("lng");
lat = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
.getJSONObject("geometry").getJSONObject("location")
.getDouble("lat");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new GeoPoint((int) (lat * 1E6), (int) (lon * 1E6));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.location:
Toast.makeText(this, "You pressed the location!", Toast.LENGTH_LONG)
.show();
return true;
case R.id.street:
Toast.makeText(this, "You pressed the street!", Toast.LENGTH_LONG)
.show();
if (map.isSatellite() == true) {
map.setSatellite(false);
}
return true;
case R.id.satallite:
Toast.makeText(this, "You pressed the satallite!",
Toast.LENGTH_LONG).show();
if (map.isSatellite() == false) {
map.setSatellite(true);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onResume() {
super.onResume();
me.enableCompass();
}
@Override
public void onPause() {
super.onPause();
me.disableCompass();
}
@Override
protected boolean isRouteDisplayed() {
return (false);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_S) {
map.setSatellite(!map.isSatellite());
return (true);
} else if (keyCode == KeyEvent.KEYCODE_Z) {
map.displayZoomControls(true);
return (true);
}
return (super.onKeyDown(keyCode, event));
}
private GeoPoint getPoint(double lat, double lon) {
return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
}
这是我的主要 xml 代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.maps.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="0f7ZWSUbQaZNR9_csQVFdRHpjnARCHAR1WbkFAQ"
android:clickable="true" />
<ImageView android:id="@+id/drag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pushpin"
android:visibility="gone"
android:contentDescription="@string/todo"/>
<Button
android:id="@+id/BtnSearch"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:onClick="GoTolocation"
android:text="Go" />
<AutoCompleteTextView
android:id="@+id/txtSearchBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/BtnSearch"
android:ems="10"
android:hint="Search Here" >
<requestFocus />
</AutoCompleteTextView>
</RelativeLayout>
这是我的主要文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mapview_dragdrop_marker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<uses-library android:name="com.google.android.maps" />
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
下面是显示错误的 logcat。
12-23 16:02:03.647: E/AndroidRuntime(788): FATAL EXCEPTION: main
12-23 16:02:03.647: E/AndroidRuntime(788): java.lang.NullPointerException
12-23 16:02:03.647: E/AndroidRuntime(788): at com.google.android.maps.ItemizedOverlay.getIndexToDraw(ItemizedOverlay.java:211)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.google.android.maps.ItemizedOverlay.draw(ItemizedOverlay.java:240)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.example.mapview_dragdrop_marker.MainActivity$SitesOverlay.draw(MainActivity.java:393)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.google.android.maps.Overlay.draw(Overlay.java:179)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.google.android.maps.OverlayBundle.draw(OverlayBundle.java:42)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.google.android.maps.MapView.onDraw(MapView.java:530)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.View.draw(View.java:6880)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.View.draw(View.java:6883)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.widget.FrameLayout.draw(FrameLayout.java:357)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.View.draw(View.java:6883)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.widget.FrameLayout.draw(FrameLayout.java:357)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewRoot.draw(ViewRoot.java:1522)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewRoot.performTraversals(ViewRoot.java:1258)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.os.Handler.dispatchMessage(Handler.java:99)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.os.Looper.loop(Looper.java:130)
12-23 16:02:03.647: E/AndroidRuntime(788): at android.app.ActivityThread.main(ActivityThread.java:3683)
12-23 16:02:03.647: E/AndroidRuntime(788): at java.lang.reflect.Method.invokeNative(Native Method)
12-23 16:02:03.647: E/AndroidRuntime(788): at java.lang.reflect.Method.invoke(Method.java:507)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
12-23 16:02:03.647: E/AndroidRuntime(788): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
12-23 16:02:03.647: E/AndroidRuntime(788): at dalvik.system.NativeStart.main(Native Method)
我不知道我在做什么错我什至填充列表以生成覆盖但它仍然给我错误
我正在使用 googleapi 10