C#:让我的整个程序在后台运行

时间:2017-03-30 12:16:03

标签: xamarin gps

我正在开发一个创建模拟位置的应用。现在,在我开始之后 - 一切似乎都在这里工作 - 然后进入地图,我总是被设置到我实际上的位置 - 而不是我的假坐标。所以我想,这是由于我的程序立即停止,我把它推到Android手机即时调试的背景。

1)你会这么说吗? 2)那么,我如何让我的程序继续模拟位置,即使它在后台?我已经设置了一个计时器,每隔5秒就会瞄准一个新位置。这是我的主要活动(碰巧有点长,请原谅..)

任何帮助都会很棒!

  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();
    }

}

}

2 个答案:

答案 0 :(得分:1)

首先,您需要为每个平台创建服务的本机实现。

对于Android:

您需要将服务包装到Android服务中以使功能在后台运行。请参阅此参考文献https://developer.android.com/guide/components/services.html https://developer.xamarin.com/guides/android/application_fundamentals/services/

对于iOS:

小小的打法。首先阅读此参考,特别是&#34;声明您的应用程序支持的后台任务&#34;部分(https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html) 所以你可以使用&#34;位置更新&#34;后台模式并将您的模拟生成器服务注入&#34;位置更新&#34;服务。 以下是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 }

答案 1 :(得分:1)

这里可能有两件事情 - 服务和后台处理。

您可以将模拟位置设置为在后台运行的服务。您可以在本机代码中执行此操作。

如果您使用的是Xamarin或Xamarin Forms,则可以使用MessagingCenter功能来通话/访问该服务。

您可以在后台运行本机代码,并且您的PCL /共享代码可以从您需要的本机代码信息中访问。

您可以查看此link以获取一些非常有用的示例和演练。