user2404597
user2404597

Reputation: 508

Xamarin.Android Timer in Service

I have a Simple Service, Job of this Service is to Run every minute and get the current Location of the user. My Code Does NOT Repeat itself every Minute.

I get following Error within my Time CallBack

Java.Lang.RuntimeException: Timeout exceeded getting exception details Can't create handler inside thread that has not called Looper.prepare()

I am using the TIMER Class in Xamarin.Android to Repeat the task. below is my example

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {

        InitializeLocationManager();
        timer = new Timer(HandleTimerCallback, startTime, 0, TimerWait);

        return StartCommandResult.NotSticky;
    }

    void HandleTimerCallback(object state)
    {
       _locationManager.RequestLocationUpdates(_locationProvider, 8000, 0, this);

    }


    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 + ".");
    }

Upvotes: 1

Views: 1214

Answers (1)

Elvis Xia - MSFT
Elvis Xia - MSFT

Reputation: 10831

I get following Error within my Time CallBack

Java.Lang.RuntimeException: Timeout exceeded getting exception details Can't create handler inside thread that has not called Looper.prepare()

_locationManager.RequestLocationUpdates needs to be executed on the mainthread, but by creating a timer, you asked this to be executed on a worker thread, thus throws the exception.

Solution:

You can create the a handler in your Service and using handler.Post to execute your _locationManager.RequestLocationUpdates:

[Service]
public class MyService : Android.App.Service, ILocationListener
{

    LocationManager _locationManager;
    string _locationProvider;
    //Define a handler
    Handler handler;

    public override void OnCreate()
    {
        base.OnCreate();
        //init the handler in oncreate
        handler = new Handler();
    }
    ...
  
    void HandleTimerCallback(object state)
    {

        handler.Post(() =>
        {
            _locationManager.RequestLocationUpdates(_locationProvider, 8000, 0, this);
        });
        
    }
    ...
}

Upvotes: 3

Related Questions