CLLocationManager get location at set time interval while in background

SCADATACOPERSCADATACOPER USMember
edited October 2015 in Xamarin.iOS

Hello , I need to collect the user's location every 15 minutes, for example , I am using the timer with the application running , it works, but in background mode , the timer does not work ...

Hello , I need to collect the User location one EVERY 15 minutes, for example , I am using timer with the application on executions , runs IT , BUT no background mode , the TIMER NOT work ...

What can I do to set an explicit time frame and still be able to perform location updates in the background ?

Anyone have any ideas , any kind of service would be possible ?

thank you!

My code:

public partial class LoginViewController : MainViewController
{
public static LocationManager _locationManager { get; set; }
public static System.Timers.Timer _timer;

public LoginViewController(IntPtr handle)
        : base(handle)
    {
}

public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        InicializaColeta();

        _locationManager._atualizaLocalizacao += AtualizaLocalizacao;

        UIApplication.Notifications.ObserveDidEnterBackground((sender, args) =>
        {
            _locationManager._atualizaLocalizacao -= AtualizaLocalizacao;
        });

        UIApplication.Notifications.ObserveDidBecomeActive((sender, args) =>
        {
            _locationManager._atualizaLocalizacao += AtualizaLocalizacao;
        });
}

private void InicializaColeta()
    {
        InicializaGps();
        InicializaTimer();
        InicializaRegionalSettings();
    }

    private void InicializaGps()
    {
        if (_locationManager == null)
        {
            _locationManager = new LocationManager();
            _locationManager.StartLocationUpdates();
        }
    }

    private void InicializaTimer()
    {
        if (_timer == null)
        {
            _timer = new System.Timers.Timer();
            _timer.Interval = TimeSpan.FromSeconds(Convert.ToDouble("5")).TotalMilliseconds;
            _timer.Elapsed += Timer_Elapsed;
            _timer.Start();
        }
    }

    private void Timer_Elapsed(object sender, ElapsedEventArgs e)
    {
        InvokeOnMainThread(() =>
        {
            GravarLocalizacao();
        });
    }

    public static void GravarLocalizacao()
    {
        var location = _locationManager.LocMgr.Location;

        if (location != null)
        {
            string info = string.Format("{0};{1};{2};{3}\n",
                            DateTime.Now.ToString(),
                            location.Coordinate.Latitude.ToString(getNumberFormat()),
                            location.Coordinate.Longitude.ToString(getNumberFormat()),
                            location.Altitude.ToString(getNumberFormat()));

            // WriteLocation
        }
    }

public void AtualizaLocalizacao(object sender, LocationUpdatedEventArgs e)
    {
        CLLocation location = e.Location;

        var msg = string.Format("Altitude: {0}\nLongitude: {1}\nLatitude: {2}\nCourse: {3}\nSpeed: {4}",
                                location.Altitude,
                                location.Coordinate.Longitude.ToString(),
                                location.Coordinate.Latitude.ToString(),
                                location.Course.ToString(),
                                location.Speed.ToString());
    }

}

public class LocationManager
{
public event EventHandler _atualizaLocalizacao = delegate { };
protected CLLocationManager _location;

    public LocationManager()
    {
        this._location = new CLLocationManager();

        if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
        {
            _location.RequestAlwaysAuthorization(); // works in background
            //locMgr.RequestWhenInUseAuthorization (); // only in foreground
        }

        this._location.DistanceFilter = 1;
        this._location.DesiredAccuracy = 1;
        this._atualizaLocalizacao += PrintLocation;
    }

    public CLLocationManager LocMgr
    {
        get { return this._location; }
    }

    public void StartLocationUpdates()
    {
        //set the desired accuracy, in meters
        LocMgr.LocationsUpdated += (object sender, CLLocationsUpdatedEventArgs e) =>
        {
            // fire our custom Location Updated event
            _atualizaLocalizacao(this, new LocationUpdatedEventArgs(e.Locations[e.Locations.Length - 1]));
        };

        LocMgr.StartUpdatingLocation();
    }

    public void StopLocationUpdates()
    {
        LocMgr.StopUpdatingLocation();
    }

    public void PrintLocation(object sender, LocationUpdatedEventArgs e)
    {
        CLLocation location = e.Location;

        var msg = string.Format("Altitude: {0}\nLongitude: {1}\nLatitude: {2}\nCourse: {3}\nSpeed: {4}",
                                location.Altitude,
                                location.Coordinate.Longitude.ToString(),
                                location.Coordinate.Latitude.ToString(),
                                location.Course.ToString(),
                                location.Speed.ToString());

        //UtilsUI.ShowUIAlertView(msg, "Inativo");
    }

}

Best Answers

Answers

  • SCADATACOPERSCADATACOPER USMember

    @AlexWhite if the location change or not does not matter , I'll always write given the time ...

    The problem is that the _timer does not work in the background ...

    I 've seen some topics saying this is not possible in the ios (get location every x time) . I need to solve this doubt .

    thank you

  • SCADATACOPERSCADATACOPER USMember

    @AlexWhite then it is impossible!! :(

    thanks man

  • GreigFieldsGreigFields USMember
    edited January 2017

    You might want to look into Background Fetch, I believe you can set the time limit on how often it calls and I believe it will call you within or somewhere around that time limit if your location has changed:
    Fetch (iOS 7+) - An application registered for background fetch privileges can check a provider for new content at regular intervals, presenting the user with updated content when they return to the application.
    Here's the Documentation Link: https://developer.xamarin.com/guides/ios/application_fundamentals/backgrounding/part_3_ios_backgrounding_techniques/updating_an_application_in_the_background/#background_fetch
    Just thought it might be a solution
    Here's an article also: https://possiblemobile.com/2013/09/ios-7-background-fetch/

Sign In or Register to comment.