user7285912
user7285912

Reputation: 201

C#: Have my whole program run in the background

I am working on an app that creates a mock location. Now, after I start it - everything seems to work here - and then go into maps, I always get set right to where I actually am - not where my fake coordinates are. So im thinking, this is due to my program immediately stopping as soon as i push it into the background of the android phone im debugging with.

1) Would u say so too? 2) So, how do I get my program to continue mocking the location, even though its in the background? I already set up a timer, that mocks a new location every 5 seconds. Here is my main activity (which happens to be a bit long, excuse me..)

Any help would be AWESOME!

  public static double GlobalLongitude = 0.0; // global, cause i need to pull string from void method 
    public static double GlobalLatitude = 0.0;

    static readonly string TAG = "X:" + typeof(Activity1).Name;
    Location _currentLocation;
    LocationManager _locationManager;

    string _locationProvider;
    TextView _locationText;
    static TextView txtAdded;
    static Button btnMain;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        _locationText = FindViewById<TextView>(Resource.Id.GpsTest);
        txtAdded = FindViewById<TextView>(Resource.Id.AddedCoordinates);
        btnMain = FindViewById<Button>(Resource.Id.startbutton);

        CountDown();
        InitializeLocationManager();
    } // start here! :D 

    private void CountDown()
    {

        System.Timers.Timer timer = new System.Timers.Timer();
        timer.Interval = 5000;
        timer.Elapsed += OnTimedEvent;
        timer.Enabled = true;

    }

    private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e) // txt.Added is here!
    {
         txtAdded.Text = SetMockLocation();       
    }

    public void OnLocationChanged(Location location)
    {
        string test = "Null";
        string test2 = "Null";
        bool waitforresult = false;

        _currentLocation = location;
        if (_currentLocation == null)
        {
            _locationText.Text = "Unable to determine your location. Try again in a short while.";
        }
        else
        {
            _locationText.Text = string.Format("Unchanged: {0:f5} {1:f5}", _currentLocation.Latitude, _currentLocation.Longitude);// hh: 53, 10
            //das her wird ausgegeben bei button.click 

            test = string.Format("{0:f5}", _currentLocation.Latitude); // to format 
            test2 = string.Format("{0:f5}", _currentLocation.Longitude);

            double.TryParse(test, out GlobalLatitude);
            double.TryParse(test2, out GlobalLongitude);

            if (test != "Null")
            {
                waitforresult = true;
            }

            if (waitforresult == true)
            {
                Add700ToCoordinates();
            }
        }

    } // ausgabe der koordinaten 

    void InitializeLocationManager()
    {
        _locationManager = (LocationManager)GetSystemService(LocationService);
        Criteria criteriaForLocationService = new Criteria
        {
            Accuracy = Accuracy.Fine
        };
        IList<string> acceptableLocationProviders = _locationManager.GetProviders(criteriaForLocationService, true);

        if (acceptableLocationProviders.Any())
        {
            _locationProvider = acceptableLocationProviders.First();
        }
        else
        {
            _locationProvider = string.Empty;
        }
        Log.Debug(TAG, "Using " + _locationProvider + ".");

    }

    protected override void OnResume()
    {
        base.OnResume();
        _locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
        Log.Debug(TAG, "Listening for location updates using " + _locationProvider + ".");
    }

    protected override void OnPause()
    {
        base.OnPause();
        _locationManager.RemoveUpdates(this);
        Log.Debug(TAG, "No longer listening for location updates.");
    }

    public static double Add700ToCoordinates()
    {
        string xy = "Null";

        double FinalCoordinates = (GlobalLatitude + 0.01065);

        btnMain.Click += (sender, e) =>
        {

            xy = FinalCoordinates.ToString();
            xy = xy + " " + GlobalLongitude.ToString();

        };

        return FinalCoordinates;
    }

    public static string SetMockLocation()
    {

        var context = Android.App.Application.Context;
        var locationManager = context.GetSystemService(LocationService) as LocationManager;

        locationManager.AddTestProvider("Test09", false, false, false, false, false, false, false, Power.Low, Android.Hardware.SensorStatus.AccuracyHigh);
        locationManager.SetTestProviderEnabled("Test09", true);

        var location = new Location("Test09");
        location.Latitude = Add700ToCoordinates();
        location.Longitude = GlobalLongitude;
        location.Accuracy = 0; // ob das geht?... ja, aber was beduetet es?  
        location.Time = DateTime.Now.Ticks;
        location.ElapsedRealtimeNanos = 100;  // hier das gleiche... was hießt es? :D 
        locationManager.SetTestProviderLocation("Test09", location);

        //Check if your event reacted the right way

        locationManager.RemoveTestProvider("Test09");

        return location.Latitude.ToString();
    }

}

}

Upvotes: 1

Views: 135

Answers (2)

Kuchur Andrei
Kuchur Andrei

Reputation: 132

First you need to create native implementation for services for each platform.

For Android:

You need to wrap your service into Android Service to have capability work in background. Please see this references https://developer.android.com/guide/components/services.html https://developer.xamarin.com/guides/android/application_fundamentals/services/

For iOS:

It's little beat harder. First read this reference, especially "Declaring Your App’s Supported Background Tasks" part.(https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html) So you can use "Location updates" background mode and inject your mock-generator service into "locations updates" service. Below example for xamarin iOS:

    private void StartAccelerometerUpdates()
    {
        if (_motionManager.AccelerometerAvailable)
            _motionManager.AccelerometerUpdateInterval = ACCEL_UPDATE_INTERVAL;
        _motionManager.StartAccelerometerUpdates (NSOperationQueue.MainQueue, AccelerometerDataUpdatedHandler);
    }

    public void AccelerometerDataUpdatedHandler(CMAccelerometerData data, NSError error)
    { //your mock-generator code }

Upvotes: 1

ADimaano
ADimaano

Reputation: 426

There are probably two things at play here - service and background processing.

You can set the mock locations, probably, as a service that runs in the background. You can do this in the native code.

And if you are using Xamarin or Xamarin Forms you can utilize the MessagingCenter feature to talk/access the service.

You can have native code running services in the background and your PCL/shared code can access from native code information that you need.

You can check on this link for some very helpful example and walkthrough.

Upvotes: 1

Related Questions