通过经纬度来谷歌API地方搜索Android中 [英] Pass Latitude and Longitude to Google API Places Search in Android

查看:168
本文介绍了通过经纬度来谷歌API地方搜索Android中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经从字面上一直在寻找这几个星期。我是新手Java程序员,但我已经能够拼凑出一个应用程序,可以使用双纬度和经度硬codeD在同一个班级。它将显示周边的那些点当前地点的列表。我有即能获得基于GPS /网络上的当前位置的方法的另一个单独的类,但我不能通过从这个二等创建到PlaceRequest类的变量。我已经通过所有上述科目的教程看了,但没有什么结合当前的位置和地点的搜索结果。我声明了两个getter方法​​,但不能调用这些变量。再次排序一名新秀,所以可能是一个容易解决。有任何想法吗?

更新 - 这是我的code到目前为止:
GooglePlaceActivity.java

 公共类GooglePlaceActivity延伸活动{
/ **当第一次创建活动调用。 * /
按钮BTN1;
TextView的TXT1;@覆盖
公共无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    的setContentView(R.layout.main);
    BTN1 =(按钮)findViewById(R.id.button1);
    TXT1 =(的TextView)findViewById(R.id.textView1);
    btn1.setOnClickListener(升);
}私有类SearchSrv扩展的AsyncTask<太虚,太虚,PlacesList> {    @覆盖
    保护PlacesList doInBackground(虚空...... PARAMS){        PlacesList PL = NULL;
        尝试{
            PL =新PlaceRequest()performSearch()。
        }赶上(例外五){
            // TODO自动生成catch块
            e.printStackTrace();
        }
        返回PL;
    }    @覆盖
    保护无效onPostExecute(PlacesList结果){        字符串文本=结果\\ n;        如果(结果!= NULL){
            对于(地点地点:result.results){
                文本=文本+ place.name +\\ n;
            }
            txt1.setText(文本);
        }
        setProgressBarIndeterminateVisibility(假);
    }
}View.OnClickListener L =新View.OnClickListener(){    @覆盖    公共无效的onClick(视图v){
        // TODO自动生成方法存根        SearchSrv SRV =新SearchSrv();
        setProgressBarIndeterminateVisibility(真);
        srv.execute();    }
};

}

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

PlaceRequest.java

 公共类PlaceRequest {私有静态最终HttpTransport运输=新ApacheHttpTransport();私有静态最后弦乐API_KEY =keyhere;
私有静态最后弦乐LOG_KEY =GGPlace;
//不同的地方API端点。
私有静态最后弦乐PLACES_SEARCH_URL =htt​​ps://maps.googleapis.com/maps/api/place/search/json?
私有静态最后弦乐PLACES_AUTOCOMPLETE_URL =htt​​ps://maps.googleapis.com/maps/api/place/autocomplete/json?
私有静态最后弦乐PLACES_DETAILS_URL =htt​​ps://maps.googleapis.com/maps/api/place/details/json?私有静态最终布尔PRINT_AS_STRING = TRUE;
//双纬度;
//双经度;CurrentLocation CLO =新CurrentLocation(NULL);
//clo.onLocationChanged(latitude);
//双经度= CurrentLocation.getLongitude();
//双纬度= CurrentLocation.getLatitude();
双隆基= clo.getLongitude();
双纬度= clo.getLatitude();公共PlacesList performSearch()抛出异常{    尝试{
        // CurrentLocation currlo =新CurrentLocation();
        //双纬度= currlo.getLatitude();
        //双隆基= currlo.getLongitude();
        Log.v(LOG_KEY,开始搜索);
        GenericUrl reqUrl =新GenericUrl(PLACES_SEARCH_URL);
        reqUrl.put(钥匙,API_KEY);
        //reqUrl.put(\"location,纬度+,+经度);
        //reqUrl.put(\"location,getLatitude(纬度)+,+ getLongitude());
        reqUrl.put(位置,纬度+,+隆基);
        reqUrl.put(半径,1600);
        reqUrl.put(类,食品);
        reqUrl.put(传感器,假);
        Log.v(LOG_KEY,URL =+ reqUrl);
        HTT prequestFactory HTT prequestFactory = createRequestFactory(运输);
        HTT prequest请求= HTT prequestFactory.buildGetRequest(reqUrl);            Log.v(LOG_KEY,request.execute()parseAsString());
            。PlacesList地方= request.execute()parseAs(PlacesList.class);
            Log.v(LOG_KEY,STATUS =+ places.status);
            对于(地点地点:places.results){
                Log.v(LOG_KEY,place.name);            }
            回到地方;    }赶上(HTT presponseException E){
        Log.v(LOG_KEY,e.getResponse()parseAsString());
        Ë扔掉;
    }    赶上(IOException异常五){
        // TODO:处理异常
        Ë扔掉;
    }
}公共静态的Htt prequestFactory createRequestFactory(最终HttpTransport运输){      返回transport.createRequestFactory(新的Htt prequestInitializer(){
       公共无效初始化(HTT prequest要求){
        GoogleHeaders标题=新GoogleHeaders();
        headers.setApplicationName(谷歌 - 地方 - DemoApp);
        request.setHeaders(头);
        JsonHttpParser解析器=新JsonHttpParser(新JacksonFactory());
        //JsonHttpParser.builder(new JacksonFactory());
        //parser.jsonFactory =新JacksonFactory();
        request.addParser(分析器);
       }
    });
}

}

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

 公共类CurrentLocation {    私有静态最后长MINIMUM_DISTANCE_CHANGE_FOR_UPDATES = 1; //在米
    私有静态最后长MINIMUM_TIME_BETWEEN_UPDATES = 1000; //(毫秒)    的LocationManager的LocationManager;
    双纬度= 0;
    双经度= 0;
    公共CurrentLocation(上下文ctxt){
超();
的LocationManager =(的LocationManager)ctxt.getSystemService(Context.LOCATION_SERVICE);//注册监听器与位置管理器来接收位置更新
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
        MINIMUM_TIME_BETWEEN_UPDATES,
        MINIMUM_DISTANCE_CHANGE_FOR_UPDATES,
        新LocationListener的(){            @覆盖
            公共无效onStatusChanged(字符串提供商,INT地位,捆绑演员){}            @覆盖
            公共无效onProviderEnabled(字符串提供商){}            @覆盖
            公共无效onProviderDisabled(字符串提供商){}            @覆盖
            公共无效onLocationChanged(地点){
                经度= location.getLongitude();
                纬度= location.getLatitude();            }
        });    }
    公共双getLatitude(){
返回纬度;
    }
    公共双getLongitude(){
返回经度;
    }
    }


解决方案

编辑:看到自己完整的code后,我看到一些基本的设计缺陷,所以我要告诉你我是如何做到的,你可以它适应你的程序流程。请记住,这个例子的极大地的从我原来的简化,但它应该足以让你去。

首先, CurrentLocation.java 文件。我对在未来是这样我可以在多个活动,额外的收获的的它,当必要的。

再次使用

 公共类CurrentLocation实现可赎回<地点> {  私有静态最后弦乐TAG =CurrentLocation;
  私人上下文的背景下;
  私人的LocationManager流明;
  私人准则标准;
  私人位置bestResult;
  私人布尔locationListenerWorking;
  公共CurrentLocation(上下文的背景下){
    LM =(的LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
    this.context =背景;
    标准=新标准();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    bestResult = NULL;
    locationListenerWorking = FALSE;
  }
  公共场所调用(){
    返回getLoc();
  }
  私人位置getLoc(){
    字符串提供商= lm.getBestProvider(标准,真正的);
    如果(供应商!= NULL){
      Log.d(TAG使用提供商:+供应商);
      locationListenerWorking = TRUE;
      lm.requestLocationUpdates(供应商,
                                0,
                                0,
                                singeUpdateListener,
                                context.getMainLooper());
    }其他{
      Log.w(TAG,无法找到位置提供者);
      返回null;
    }    而(locationListenerWorking){
      //检查中断信号 - 终止如有必要,
      如果(Thread.currentThread()。isInterrupted()){
        Log.i(TAG,用户发起的中断(取消信号));
        清理(​​);
        打破;
      }      尝试{
        //贫民区实施忙等待的...
        视频下载(500); //睡眠半秒
      }赶上(例外五){
        Log.d(TAG,线程中断..);
        清理(​​);
        打破;
      }
    }    返回bestResult;
  }
  私人无效清理(){
    如果(LM!= NULL){
      Log.d(TAG,位置经理不为空 - 清理);
      lm.removeUpdates(singeUpdateListener);
    }其他{
      Log.d(TAG,位置经理NULL - 没有必要的清理);
    }
  }
  / **
   *该一次性{@link LocationListener的}只需监听一个位置
   *注销本身之前更新。一次性的位置更新
   *通过{LocationListener的@link} {中指定@link返回
   * setChangedLocationListener}。
   * /
  私人LocationListener的singeUpdateListener =新LocationListener的(){
      公共无效onLocationChanged(地点){
        Log.d(TAG,得到了一个位置更新);
        如果(位置== NULL){
          Log.d(TAG,好像我们得到了一个空位置);
        }其他{
          bestResult =位置;
        }        清理(​​);
        locationListenerWorking = FALSE;
      }      公共无效onStatusChanged(字符串提供商,INT地位,捆绑演员){}
      公共无效onProviderEnabled(字符串提供商){}
      公共无效onProviderDisabled(字符串提供商){}
    };}

然后在你的呼叫的类(即你需要的纬度/经度坐标 - 您希望从活动做到这一点):

 私有类GetLocationTask扩展的AsyncTask<太虚,太虚,地点> {
  私人未来<地点>未来;
  私人ExecutorService的执行人=新的ScheduledThreadPoolExecutor(5);
  私人布尔cancelTriggered = FALSE;  在preExecute保护无效(){
    Log.d(TAG启动位置得到...);
  }  公共场所doInBackground(无效... ARG){
    CurrentLocation currLoc =新CurrentLocation(getApplicationContext());
    未来= executor.submit(currLoc);
    长LOCATION_TIMEOUT = 20000; //毫秒= 20秒
    尝试{
      //返回的Future.get(Constants.LOCATION_TIMEOUT,TimeUnit.MILLISECONDS);
      返回的Future.get(LOCATION_TIMEOUT,TimeUnit.MILLISECONDS);
    }赶上(例外五){
      Log.w(TAG,位置得到超时);
      future.cancel(真);
      返回null;
    }
  }  公共布尔killTask​​(){
    cancelTriggered = TRUE;
    布尔futureCancelRes = future.cancel(真);
    this.cancel(真);
    Log.d(TAG,取消任务的结果:+ futureCancelRes);
    返回futureCancelRes;
  }
  保护无效onPostExecute(RES位置){
    如果(cancelTriggered){
      Log.d(TAG,用户发起的取消 - 这是好的);
      cancelTriggered = FALSE;
    }否则如果(RES == NULL){
      Log.d(TAG,无法得到位置);
    }其他{
      双纬度= res.getLatitude();
      双LON = res.getLongitude();
      Log.d(TAG,纬度:+ LAT);
      Log.d(TAG,经度:+ LON);
    }
  }
}

最后包东西,这里是你怎么称呼它:

  GetLocationTask T =新GetLocationTask();
t.execute();

如果你需要杀死不论什么原因,位置更新(如果您的用户切换你的活动,等出),这会杀了的AsyncTask 还有相关的未来任务。

  t.killTask​​();

P.S。你可能希望得到您的API密钥更改,编辑你的帖子。

I have literally been searching for this for weeks. I am a novice java programmer but I have been able to piece together an app that can use a double latitude and longitude hard coded in the same class. It will show a list of current places surrounding those points. I have another separate class with a method that is able to get the current location based on the gps/network but I can't pass the variables created from this second class to the PlaceRequest class. I have looked through all of the tutorials on the above subjects but there isn't anything combining current location and place search results. I have two getters declared but can't call the variables in these. Again sort of a rookie so may be an easy fix. Any ideas?

Update - Here is my code so far: 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<Void, Void, PlacesList>{

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

解决方案

Edit: After looking your complete code, I see a few fundamental design flaws so I'm going to show you how I did it and you can adapt it to your program flow. Please keep in mind that this example is vastly simplified from my original, but it should be enough to get you going.

First, the CurrentLocation.java file. My design decision for wrapping this in a Future was so that I can re-use it in multiple activities with the added bonus of killing it when necessary.

public class CurrentLocation implements Callable<Location> {

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

}

Then in your calling class (i.e. where you need the lat/lon coordinates - you want to do this from an Activity):

private class GetLocationTask extends AsyncTask <Void, Void, Location> {
  private Future<Location> 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);
    }
  }
}

Finally to wrap things up, here's how you call it:

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

And if you need to kill the location update for whatever reason (if your user switches out of your activity, etc), this will kill the AsyncTask as well as the associated Future task.

t.killTask();

P.S. You may want to get your API keys changed and edit it out of your post.

这篇关于通过经纬度来谷歌API地方搜索Android中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆