Pass Latitude and Longitude to Google API Places Search in Android

前端 未结 1 1642
暗喜
暗喜 2021-01-16 13:32

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

相关标签:
1条回答
  • 2021-01-16 14:18

    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.

    0 讨论(0)
提交回复
热议问题