How to use xamarin to synchronize GPS location updates in Android?

Specifically, I am using xamarin.forms for c# development, but I work on native Android and write a GPS wrapper class, which can be used in xamarin.forms through dependency injection. In most cases, the calls between Android, c# and Java should be the same

In essence, I have this method in the geolocator object (implementing ilocationlister) on the Android side:

public async Task<Tuple<bool, string, GPSData>> GetGPSData() {
        gpsData = null;
        var success = false;
        var error = string.Empty;

        if (!manager.IsProviderEnabled(LocationManager.GpsProvider)) {
            //request permission or location services enabling
            //set error
        } else {
            manager.RequestSingleUpdate(LocationManager.GpsProvider, this, null);
            success = true;
        }

        return new Tuple<bool, string, GPSData>(success, error, gpsData);
 }

and

 public void OnLocationChanged(Location location) {
        gpsData = new GPSData(location.Latitude, location.Longitude);
    }

I hope to call getgpsdata and let it return tuples. At present, the only important thing about tuples is that GPSdata has been filled. I know it may take a few seconds to find the repair method, so I hope this method is asynchronous. Once I really need the value, I can wait at xamarin.forms

My problem is that I can't think of a way for manager.requestsingleupdate to synchronize or do other work. You call this method and eventually trigger onlocationchanged. I tried to throw a disgusting barbarian

 while (gpsData == null);

After the call that forces it not to continue until onlocationchanged is triggered, but when I put the row in, onlocationchanged will never be called. I assume this is because onlocationchanged is called on the same thread rather than the background thread

What can I do to take this situation and not return getgpsdata before onlocationchanged is triggered?

thank you

Edit: to add, this method will not be called periodically. It is spontaneous and rare, so I don't want to use requestlocationupdates to get regular updates and return the latest updates, because it will need to always turn on GPS and unnecessarily rain the battery

resolvent:

You can use taskcompletionsource to perform the required operations. I have encountered the same problem. This is my solution:

TaskCompletionSource<Tuple<bool, string, GPSData> tcs;
// No need for the method to be async, as nothing is await-ed inside it.
public Task<Tuple<bool, string, GPSData>> GetGPSData() {
    tcs = new TaskCompletionSource<Tuple<bool, string, GPSData>>();
    gpsData = null;
    var success = false;
    var error = string.Empty;

    if (!manager.IsProviderEnabled(LocationManager.GpsProvider)) {
        //request permission or location services enabling
        //set error
        tcs.TrySetException(new Exception("some error")); // This will throw on the await-ing caller of this method.
    } else {
        manager.RequestSingleUpdate(LocationManager.GpsProvider, this, null);
        success = true;
    }

    //return new Tuple<bool, string, GPSData>(success, error, gpsData); <-- change this to:
    return this.tcs.Task;
}

And:

public void OnLocationChanged(Location location) {
        gpsData = new GPSData(location.Latitude, location.Longitude);
        // Here you set the result of TaskCompletionSource. Your other method completes the task and returns the result to its caller.
        tcs.TrySetResult(new Tuple<bool, string, GPSData>(false, "someString", gpsData));
    }

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>