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

时间:2012-01-03 22:52:41

标签: java 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<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;
    } 
    }

1 个答案:

答案 0 :(得分:0)

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

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

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

}

然后在你的调用类中(即你需要lat / lon坐标 - 你想从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);
    }
  }
}

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

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

如果您因任何原因需要终止位置更新(如果您的用户退出您的活动等),这将会导致AsyncTask以及相关的Future任务被终止。

t.killTask();

P.S。您可能希望更改API密钥并从帖子中进行编辑。