将经度和经度传递给Android中的Google API地方搜索

几个星期以来,我一直在寻找这个。 我是一名新手java程序员,但我已经能够拼凑出一个可以在同一个类中使用硬编码的双纬度和经度的应用程序。 它将显示这些点周围的当前位置列表。 我有另一个单独的类,其方法能够基于gps / network获取当前位置,但我无法将从第二个类创建的变量传递给PlaceRequest类。 我已经查看了上述主题的所有教程,但没有任何组合当前位置和地点搜索结果。 我声明了两个getter但是无法在这些中调用变量。 再一次是一个菜鸟,所以可能很容易解决。 有任何想法吗?

更新 – 这是我的代码到目前为止:GooglePlaceActivity.java

public class GooglePlaceActivity extends Activity { /** Called when the activity is first created. */ Button btn1; TextView txt1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.main); btn1 = (Button)findViewById(R.id.button1); txt1 = (TextView)findViewById(R.id.textView1); btn1.setOnClickListener(l); } private class SearchSrv extends AsyncTask{ @Override protected PlacesList doInBackground(Void... params) { PlacesList pl = null; try { pl = new PlaceRequest().performSearch(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return pl; } @Override protected void onPostExecute(PlacesList result) { String text = "Result \n"; if (result!=null){ for(Place place: result.results){ text = text + place.name +"\n"; } txt1.setText(text); } setProgressBarIndeterminateVisibility(false); } } View.OnClickListener l = new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub SearchSrv srv = new SearchSrv(); setProgressBarIndeterminateVisibility(true); srv.execute(); } }; 

}

//////////////////////

PlaceRequest.java

  public class PlaceRequest { private static final HttpTransport transport = new ApacheHttpTransport(); private static final String API_KEY = "keyhere"; private static final String LOG_KEY = "GGPlace"; // The different Places API endpoints. private static final String PLACES_SEARCH_URL = "https://maps.googleapis.com/maps/api/place/search/json?"; private static final String PLACES_AUTOCOMPLETE_URL = "https://maps.googleapis.com/maps/api/place/autocomplete/json?"; private static final String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json?"; private static final boolean PRINT_AS_STRING = true; //double latitude; //double longitude; CurrentLocation clo = new CurrentLocation(null); //clo.onLocationChanged(latitude); //double longitude = CurrentLocation.getLongitude(); //double latitude = CurrentLocation.getLatitude(); double longi = clo.getLongitude(); double lat = clo.getLatitude(); public PlacesList performSearch() throws Exception { try { //CurrentLocation currlo = new CurrentLocation(); //double lat = currlo.getLatitude(); //double longi = currlo.getLongitude(); Log.v(LOG_KEY, "Start Search"); GenericUrl reqUrl = new GenericUrl(PLACES_SEARCH_URL); reqUrl.put("key", API_KEY); //reqUrl.put("location", latitude + "," + longitude); //reqUrl.put("location", getLatitude(latitude) + "," + getLongitude()); reqUrl.put("location", lat + "," + longi); reqUrl.put("radius", 1600); reqUrl.put("types", "food"); reqUrl.put("sensor", "false"); Log.v(LOG_KEY, "url= " + reqUrl); HttpRequestFactory httpRequestFactory = createRequestFactory(transport); HttpRequest request = httpRequestFactory.buildGetRequest(reqUrl); Log.v(LOG_KEY, request.execute().parseAsString()); PlacesList places = request.execute().parseAs(PlacesList.class); Log.v(LOG_KEY, "STATUS = " + places.status); for (Place place : places.results) { Log.v(LOG_KEY, place.name); } return places; } catch (HttpResponseException e) { Log.v(LOG_KEY, e.getResponse().parseAsString()); throw e; } catch (IOException e) { // TODO: handle exception throw e; } } public static HttpRequestFactory createRequestFactory(final HttpTransport transport) { return transport.createRequestFactory(new HttpRequestInitializer() { public void initialize(HttpRequest request) { GoogleHeaders headers = new GoogleHeaders(); headers.setApplicationName("Google-Places-DemoApp"); request.setHeaders(headers); JsonHttpParser parser = new JsonHttpParser(new JacksonFactory()) ; //JsonHttpParser.builder(new JacksonFactory()); //parser.jsonFactory = new JacksonFactory(); request.addParser(parser); } }); } 

}

///////////// CurrentLocation.java

  public class CurrentLocation { private static final long MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; // in Meters private static final long MINIMUM_TIME_BETWEEN_UPDATES = 1000; // in Milliseconds LocationManager locationManager ; double latitude=0; double longitude=0; public CurrentLocation(Context ctxt) { super(); locationManager = (LocationManager) ctxt.getSystemService(Context.LOCATION_SERVICE); // Register the listener with the Location Manager to receive location updates locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MINIMUM_TIME_BETWEEN_UPDATES, MINIMUM_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() { @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} @Override public void onLocationChanged(Location location) { longitude = location.getLongitude(); latitude = location.getLatitude(); } }); } public double getLatitude() { return latitude; } public double getLongitude() { return longitude; } } 

编辑:在查看完整的代码之后,我看到了一些基本的设计缺陷,所以我将向您展示我是如何做到的,并且您可以根据您的程序流程进行调整。 请记住,这个例子与我的原始版本大大简化,但它应该足以让你前进。

首先是CurrentLocation.java文件。 我的设计决定是将它包装在一个Future中 ,以便我可以在多个活动中重复使用它,并在必要时杀死它。

 public class CurrentLocation implements Callable { private static final String TAG = "CurrentLocation"; private Context context; private LocationManager lm; private Criteria criteria; private Location bestResult; private boolean locationListenerWorking; public CurrentLocation(Context context) { lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); this.context = context; criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); bestResult = null; locationListenerWorking = false; } public Location call() { return getLoc(); } private Location getLoc() { String provider = lm.getBestProvider(criteria, true); if (provider != null) { Log.d(TAG, "Using provider: " +provider); locationListenerWorking = true; lm.requestLocationUpdates(provider, 0, 0, singeUpdateListener, context.getMainLooper()); } else { Log.w(TAG, "Couldn't find a location provider"); return null; } while (locationListenerWorking) { // Check for the interrupt signal - terminate if necessary if (Thread.currentThread().isInterrupted()) { Log.i(TAG, "User initiated interrupt (cancel signal)"); cleanup(); break; } try { // ghetto implementation of a busy wait... Thread.sleep(500); // Sleep for half a second } catch (Exception e) { Log.d(TAG, "Thread interrupted.."); cleanup(); break; } } return bestResult; } private void cleanup() { if (lm != null) { Log.d(TAG, "Location manager not null - cleaning up"); lm.removeUpdates(singeUpdateListener); } else { Log.d(TAG, "Location manager was NULL - no cleanup necessary"); } } /** * This one-off {@link LocationListener} simply listens for a single location * update before unregistering itself. The one-off location update is * returned via the {@link LocationListener} specified in {@link * setChangedLocationListener}. */ private LocationListener singeUpdateListener = new LocationListener() { public void onLocationChanged(Location location) { Log.d(TAG, "Got a location update"); if (location == null) { Log.d(TAG, "Seems as if we got a null location"); } else { bestResult = location; } cleanup(); locationListenerWorking = false; } public void onStatusChanged(String provider, int status, Bundle extras) {} public void onProviderEnabled(String provider) {} public void onProviderDisabled(String provider) {} }; } 

然后在你的调用类中(即你需要lat / lon坐标的位置 – 你想从一个Activity执行此操作):

 private class GetLocationTask extends AsyncTask  { private Future future; private ExecutorService executor = new ScheduledThreadPoolExecutor(5); private boolean cancelTriggered = false; protected void onPreExecute() { Log.d(TAG, "Starting location get..."); } public Location doInBackground(Void... arg) { CurrentLocation currLoc = new CurrentLocation(getApplicationContext()); future = executor.submit(currLoc); long LOCATION_TIMEOUT = 20000; // ms = 20 sec try { // return future.get(Constants.LOCATION_TIMEOUT, TimeUnit.MILLISECONDS); return future.get(LOCATION_TIMEOUT, TimeUnit.MILLISECONDS); } catch (Exception e) { Log.w(TAG, "Location get timed out"); future.cancel(true); return null; } } public boolean killTask() { cancelTriggered = true; boolean futureCancelRes = future.cancel(true); this.cancel(true); Log.d(TAG, "Result of cancelling task: " +futureCancelRes); return futureCancelRes; } protected void onPostExecute(Location res) { if (cancelTriggered) { Log.d(TAG, "User initiated cancel - this is okay"); cancelTriggered = false; } else if (res == null) { Log.d(TAG, "Could not get a location result"); } else { double lat = res.getLatitude(); double lon = res.getLongitude(); Log.d(TAG, "Latitude: " +lat); Log.d(TAG, "Longitude: " +lon); } } } 

最后要总结一下,以下是你如何称呼它:

 GetLocationTask t = new GetLocationTask(); t.execute(); 

如果您因任何原因需要终止位置更新(如果您的用户切换到您的活动等),这将AsyncTask以及相关的Future任务。

 t.killTask(); 

PS您可能希望更改API密钥并从post中进行编辑。