簡體   English   中英

將緯度和經度傳遞到Android中的Google API地方信息搜索

[英]Pass Latitude and Longitude to Google API Places Search in Android

我從字面上一直在尋找這個星期。 我是Java的新手程序員,但是我已經能夠拼湊一個可以在同一個類中使用經度和緯度雙重編碼的應用程序。 它將顯示這些點周圍的當前位置的列表。 我還有一個單獨的類,該類的方法能夠基於gps /網絡獲取當前位置,但無法將從第二個類創建的變量傳遞給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;
    } 
    }

編輯:查看完完整的代碼后,我看到了一些基本的設計缺陷,因此我將向您展示我是如何做到的,並且您可以將其適應您的程序流程。 請記住,此示例與我的原始示例相比已大大簡化,但足以使您繼續前進。

首先是CurrentLocation.java文件。 我的設計決定是將其包裝在Future中 ,以便我可以在多個活動中重復使用它,並在需要時增加殺死它的好處。

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

}

然后在您的調用類中(即,您需要緯度/經度坐標的位置-您想通過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位置更新,則這將AsyncTask以及關聯的Future任務。

t.killTask();

PS:您可能想更改您的API密鑰,然后在帖子中對其進行編輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM