How can I get the current gps location every time a function is called?

好久不见. 提交于 2019-12-23 03:21:11

问题


What I want to do is to get the location latitude and longitude each time a function is called. As I have understood the best way to do that is to leave the location update for a few seconds to get the correct fix and then disable it, but I can't make it work in my app.

What I have managed until now is to get the last known location of the phone, every time the displayData function is called, but I have not been able to get over all the errors that appear when I'm trying to change to requestLocationUpdates. What exactly I am doing here is to call the displayData function, when there is incoming data from a bluetooth device, in order to get the location and write the data + location in a file.

Can someone help me because all the guides show how to trigger something when location updates but I don't want to do that. I just want a correct location periodically...

private void displayData(final byte[] byteArray) {
try {

    mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.

                    if (byteArray != null) {
                        String data = new String(byteArray);
                        tv.setText(n/2 + " measurements since startup...");
                        n += 1;

                        if (location != null) {
                            double lat = location.getLatitude();
                            double lng = location.getLongitude();
                            latitude = String.valueOf(lat);
                            longitude = String.valueOf(lng);
                        }

                        try
                        {
                            FileWriter fw = new FileWriter(textfile,true); //the true will append the new data
                            if (writeDate()) {
                                fw.write("\n");
                                fw.write(stringDate);
                                fw.write(data); //appends the string to the file
                            }
                            else {
                                fw.write(data); //appends the string to the file
                                fw.write(" - ");
                                fw.write(latitude);
                                fw.write(",");
                                fw.write(longitude);
                            }
                            fw.close();
                        }
                        catch(IOException ioe)
                        {
                            System.err.println("IOException: " + ioe.getMessage());
                        }


                        // find the amount we need to scroll. This works by
                        // asking the TextView's internal layout for the position
                        // of the final line and then subtracting the TextView's height
                        final int scrollAmount = tv.getLayout().getLineTop(
                                tv.getLineCount())
                                - tv.getHeight();
                        // if there is no need to scroll, scrollAmount will be <=0
                        if (scrollAmount > 0)
                            tv.scrollTo(0, scrollAmount);
                        else
                            tv.scrollTo(0, 0);
                    }
                }
            });

} catch (SecurityException e) {
    // lets the user know there is a problem with the gps
}
}

回答1:


Here's what I understand of your problem:

  • You want GPS location on demand, but:
  • You don't want the GPS to run constantly, and:
  • You accept that the GPS will have to be run for a short period of time

Try not to think in terms of a "function that returns the phone's current location", because that implies that it's a simple, synchronous operation that provides an answer without blocking. We can't do that here.

Instead, I suggest you think of this more as an FSM, since you need an arbitrary amount of time (perhaps a few seconds, perhaps more) between the time you call displayData() and the time you start getting real-time GPS fixes. In other words, displayData() will not produce a location, directly; it'll set into motion a chain of events which eventually results in you obtaining a location.

You'll have to commit to using requestLocationUpdates() (or a similar method):

private void displayData(final byte[] byteArray) {
    //This call turns the GPS on, and returns immediately:
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {

        //This function gets called some time after displayData() returns (possibly
        //*way* after). It executes on the UI thread.
        public void onLocationChanged(Location location) {
            locationManager.removeUpdates(this); //Shut down the GPS

            //(Execute the remainder of your onSuccess() logic here.)

            //Now our state machine is complete, and everything is cleaned up.
            //We are ready for the next call to displayData().
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {}

        public void onProviderEnabled(String provider) {}

        public void onProviderDisabled(String provider) {}
    );
}

That way,

  • We don't block the UI thread (displayData() returns immediately)
  • The state machine eventually converges to an answer (provided the GPS is functional)
  • GPS turns off once we have the information we need

Some improvements to this scheme you might want to consider:

  • A way to avoid a repeat call to requestLocationUpdates() if displayData() gets called before the previous request has resolved
  • Handling the case where the UI elements referred to in your onSuccess() method are no longer available b/c the Activity has onDestroy()'d during the time the GPS request was "in progress"
  • Cancelling the request-in-progress if you need to clean up, etc.



回答2:


I followed Markus Kauppinen's approach requesting for location updates at a time interval that suits my app and then just using the get last known location when there is incoming data from bluetooth. So I just added the following in my activity:

    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(30000);
    mLocationRequest.setFastestInterval(10000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    LocationCallback mLocationCallback = new LocationCallback();



// Register the listener with the Location Manager to receive location updates
    try {
        mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                mLocationCallback,
                null /* Looper */);

    }
    catch (SecurityException e) {
        // lets the user know there is a problem with the gps
    }


来源:https://stackoverflow.com/questions/53614643/how-can-i-get-the-current-gps-location-every-time-a-function-is-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!