我一直在关注一个教程(http://www.androidhive.info/2012/08/android-working-with-google-places-and-maps-tutorial/),以便将列表视图显示在距离您所在位置最近的餐馆,方圆5公里。
但是我不断收到错误,在我的Runnable中它说状态变量为null。我真的不明白为什么会出现这个错误。你们能给我一个简短的解释并帮助找到解决方案吗?
PlacesList.java
public class PlacesList implements Serializable {
public String status;
public List<Place> results;
}
DisplayLocations.java
public class DisplayLocations extends Activity {
boolean isInternetPresent = false;
ConnectionDetector cd;
GooglePlaces googlePlaces;
PlacesList nearPlaces;
GPSTracker gps;
Button shownOnMap;
ProgressDialog pDialog;
ListView lv;
ArrayList<HashMap<String, String>> placesListItems = new ArrayList<HashMap<String, String>>();
public static String KEY_REFERENCE = "reference";
public static String KEY_NAME = "name";
public static String KEY_VICINITY = "vicinity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_locations);
cd = new ConnectionDetector(getApplicationContext());
isInternetPresent = cd.isConnectingToInternet();
if(!isInternetPresent){
Toast.makeText(getApplicationContext(), "Get a working connection", Toast.LENGTH_SHORT).show();
return;
}
gps = new GPSTracker(DisplayLocations.this);
if(gps.canGetLocation()){
}else{
gps.showSettingsAlert();
}
lv = (ListView)findViewById(R.id.list);
shownOnMap = (Button)findViewById(R.id.btn_show_map);
new LoadPlaces().execute();
shownOnMap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*
Intent i = new Intent(getApplicationContext(), PlacesMapActivity.class);
i.putExtra("user_latitude", Double.toString(gps.getLatitude()));
i.putExtra("user_longitude", Double.toString(gps.getLongitude()));
i.putExtra("near_places", nearPlaces);
startActivity(i);
*/
}
});
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String reference = ((TextView) findViewById(R.id.reference)).getText().toString();
/*
Intent in = new Intent(getApplicationContext(), SingePlaceActivity.class);
in.putExtra(KEY_REFERENCE, reference);
startActivity(in);
*/
}
});
}
class LoadPlaces extends AsyncTask<String, String, String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(DisplayLocations.this);
pDialog.setMessage(Html.fromHtml("<b>Search</b><br/>Loading Places..."));
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected String doInBackground(String... params) {
googlePlaces = new GooglePlaces();
try{
String types = "cafe|restaurant";
double radius = 5000;
nearPlaces = googlePlaces.search(gps.getLatitude(), gps.getLongitude(), radius, types);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
@Override
public void run() {
String status = nearPlaces.status;
if (status.equals("OK")){
if(nearPlaces.results != null){
for (Place p : nearPlaces.results){
HashMap<String, String> map = new HashMap<String, String>();
map.put(KEY_REFERENCE, p.reference);
map.put(KEY_NAME, p.name);
placesListItems.add(map);
}
ListAdapter adapter = new SimpleAdapter(DisplayLocations.this, placesListItems, R.layout.location_listview_item,
new String[]{KEY_REFERENCE, KEY_NAME}, new int[]{R.id.reference, R.id.name});
lv.setAdapter(adapter);
}
}
else if(status.equals("ZERO_RESULTS")){
// Zero results found
Toast.makeText(getApplicationContext(), "No Results", Toast.LENGTH_SHORT);
}
else if(status.equals("UNKNOWN_ERROR"))
{
Toast.makeText(getApplicationContext(), "Unknown error", Toast.LENGTH_SHORT);
}
else if(status.equals("OVER_QUERY_LIMIT"))
{
Toast.makeText(getApplicationContext(), "Query limit reached !", Toast.LENGTH_SHORT);
}
else if(status.equals("REQUEST_DENIED"))
{
Toast.makeText(getApplicationContext(), "Request denied", Toast.LENGTH_SHORT);
}
else if(status.equals("INVALID_REQUEST"))
{
Toast.makeText(getApplicationContext(), "Invalid request", Toast.LENGTH_SHORT);
}
else
{
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT);
}
}
});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_display_locations, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
GooglePlaces.java
public class GooglePlaces {
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private final String API_KEY = "AIzaSyCxY1X7hC7SOab7V3GbWd1u42fGThgYOhg";
//GooglePlaces search URL
private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
private static final String PLACES_TEXT_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?";
private static final String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json?";
private double mLatitiude;
private double mLongitude;
private double mRadius;
public PlacesList search(double latitude, double longitude, double radius, String types) throws Exception{
this.mLatitiude = latitude;
this.mLongitude = longitude;
this.mRadius = radius;
try {
HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_SEARCH_URL));
request.getUrl().put("key", API_KEY);
request.getUrl().put("location", mLatitiude + "," + mLongitude);
request.getUrl().put("radius", mRadius); // in meters
request.getUrl().put("sensor", "false");
if (types != null)
request.getUrl().put("types", types);
PlacesList list = request.execute().parseAs(PlacesList.class);
// Check log cat for places response status
Log.d("Places Status", "" + list.status);
return list;
} catch (HttpResponseException e) {
Log.e("Error:", e.getMessage());
return null;
}
}
public PlaceDetails getPlaceDetails(String reference) throws Exception{
try{
HttpRequestFactory httpRequestFactory = createRequestFactory(HTTP_TRANSPORT);
HttpRequest request = httpRequestFactory.buildGetRequest(new GenericUrl(PLACES_DETAILS_URL));
request.getUrl().put("reference", reference);
request.getUrl().put("key", API_KEY);
request.getUrl().put("sensor",false);
PlaceDetails place = request.execute().parseAs(PlaceDetails.class);
return place;
}catch (HttpResponseException e){
throw e;
}
}
public static HttpRequestFactory createRequestFactory(final HttpTransport transport){
return transport.createRequestFactory(new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest request) throws IOException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setUserAgent("Application Test");
request.setHeaders(httpHeaders);
JsonObjectParser parser = new JsonObjectParser(new JsonFactory() {
@Override
public JsonParser createJsonParser(InputStream in) throws IOException {
return null;
}
@Override
public JsonParser createJsonParser(InputStream in, Charset charset) throws IOException {
return null;
}
@Override
public JsonParser createJsonParser(String value) throws IOException {
return null;
}
@Override
public JsonParser createJsonParser(Reader reader) throws IOException {
return null;
}
@Override
public JsonGenerator createJsonGenerator(OutputStream out, Charset enc) throws IOException {
return null;
}
@Override
public JsonGenerator createJsonGenerator(Writer writer) throws IOException {
return null;
}
});
request.setParser(parser);
}
});
}
}
DisplayLocations.java的第132行是:
String status = nearPlaces.status;
这是堆栈跟踪:
java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.example.dell.exampleapplication.PlacesList.status' on a null object reference
at com.example.dell.exampleapplication.DisplayLocations$LoadPlaces$1.run(DisplayLocations.java:132)
at android.app.Activity.runOnUiThread(Activity.java:5517)
at com.example.dell.exampleapplication.DisplayLocations$LoadPlaces.onPostExecute(DisplayLocations.java:129)
at com.example.dell.exampleapplication.DisplayLocations$LoadPlaces.onPostExecute(DisplayLocations.java:98)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5834)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
任何帮助和解释都将不胜感激。
谢谢,祝你有愉快的一天。
答案 0 :(得分:0)
编辑:
在doInBackGround中nearPlaces.status = ...(状态:可能来自GooglePlaces)
然后你可以这样做: String status = nearPlaces.status;在onPostExecute
答案 1 :(得分:0)
添加行
@Override
protected String doInBackground(String... params) {
googlePlaces = new GooglePlaces();
try{
String types = "cafe|restaurant";
double radius = 5000;
nearPlaces = googlePlaces.search(gps.getLatitude(), gps.getLongitude(), radius, types);
nearPlaces.status = "OK"; //Add this line for testing, your code should work now, because status is not NULL anymore.
}catch (Exception e){
e.printStackTrace();
}
return null;
}