Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass data from android service to ContentPage in Xamarin Form based application

I am having one Application based on XamarinForms.

One background service I have created in Android project and that service would like to send data to ContentPage(which is in PCL) which is displayed to user.

How could I pass data to ContentPage(From xx.Droid project to PCL)?

One solution is:

  • To Create class in PCL with static variable(e.g. var TEMP_VAR), which will be accessed from xxx.Droid project.
  • Update value of that static variable(TEMP_VAR) from the service class from the xxx.Droid project.
  • Need to create Notifier on that static variable(TEMP_VAR)
  • Update the content page using MessageCenter Mechanism if require.

If there is any better solution, could you please provide me?

like image 279
Nirav Shah Avatar asked May 13 '15 11:05

Nirav Shah


1 Answers

This can be achieved using the concept of C#

  • Dependency service
  • Event

Need to have 4 classes for such an implementation:

  1. Interface in PCL(e.g. CurrentLocationService.cs) with event handlers defined in it.

namespace NAMESPACE
{
	public interface CurrentLocationService
	{
		void start();

		event EventHandler<PositionEventArgs> positionChanged;
	}
}
  1. Implementation of interface of PCL in xxx.Droid project (e.g. CurrentLocationService_Android.cs) using Dependency service

class CurrentLocationService_Android : CurrentLocationService
{

	public static CurrentLocationService_Android mySelf;

	public event EventHandler<PositionEventArgs> positionChanged;
	
	
	public void start()
	{
		mySelf = this;
		Forms.Context.StartService(new Intent(Forms.Context, typeof(MyService)));

	}

	public void receivedNewPosition(CustomPosition pos)
	{
		positionChanged(this, new PositionEventArgs(pos));
	}

}
  1. ContentPage in PCL - which will have object of implementation of interface. Object can be obtained by

public CurrentLocationService LocationService
{
	get
	{
		if(currentLocationService == null)
		{
			currentLocationService = DependencyService.Get<CurrentLocationService>();
			currentLocationService.positionChanged += OnPositionChange;
		}
		return currentLocationService;
	}
   

}

private void OnPositionChange(object sender, PositionEventArgs e)
{
	Debug.WriteLine("Got the update in ContentPage from service ");
}
  1. Background service in xxx.Droid project. This service will have reference of implementation of dependency service CurrentLocationService.cs

[Service]
    public class MyService : Service
    {
        public string TAG = "MyService";
        
      public override IBinder OnBind(Intent intent)
        {
            throw new NotImplementedException();
        }

      

        public override StartCommandResult OnStartCommand(Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {
            Log.Debug(TAG, TAG + " started");

            doWork();

            return StartCommandResult.Sticky;
        }

        public void doWork()
        {
            var t = new Thread(
                () =>
                {
                    Log.Debug(TAG, "Doing work");
                    Thread.Sleep(10000);
                    Log.Debug(TAG, "Work completed");

                    if(CurrentLocationService_Android.mySelf != null)
                    {
                        CustomPosition pos = new CustomPosition();
                        pos.update = "Finally value is updated";
                        CurrentLocationService_Android.mySelf.receivedNewPosition(pos);
                        
                    }

                    StopSelf();
                });
            t.Start();
        }

    }

Note : PositionEventArgs class need to be created as per usage to pass on data between service and ContentPage.

This works for me like charm.

Hope so this would be helpful to you.

like image 111
Nirav Shah Avatar answered Sep 20 '22 17:09

Nirav Shah