Передача данных из сервиса Android в ContentPage в приложении на основе Xamarin Form

У меня есть одно приложение, основанное на XamarinForms.

Один фоновый сервис, который я создал в проекте Android, и этот сервис хотел бы отправлять данные в ContentPage(который находится в PCL), который отображается для пользователя.

Как я могу передать данные в ContentPage(из проекта xx.Droid в PCL)?

Одним из решений является:

  • Создать класс в PCL со статической переменной (например, var TEMP_VAR), к которой будет обращаться из проекта xxx.Droid.
  • Обновите значение этой статической переменной (TEMP_VAR) из класса обслуживания из проекта xxx.Droid.
  • Необходимо создать Уведомитель для этой статической переменной (TEMP_VAR)
  • Обновите страницу содержимого с помощью механизма MessageCenter, если требуется.

Если есть лучшее решение, не могли бы вы предоставить мне?

1 ответ

Решение

Это может быть достигнуто с использованием концепции C#

  • Сервис зависимостей
  • Событие

Нужно иметь 4 класса для такой реализации:

  1. Интерфейс в PCL(например, CurrentLocationService.cs) с определенными в нем обработчиками событий.

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

  event EventHandler<PositionEventArgs> positionChanged;
 }
}

  1. Реализация интерфейса PCL в проекте xxx.Droid (например, CurrentLocationService_Android.cs) с использованием сервиса Dependency

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 в PCL - который будет иметь объект реализации интерфейса. Объект можно получить

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. Фоновый сервис в проекте xxx.Droid. Этот сервис будет иметь ссылку на реализацию сервиса зависимостей 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();
        }

    }

Примечание: класс PositionEventArgs должен быть создан в соответствии с использованием для передачи данных между службой и ContentPage.

Это работает для меня как шарм.

Надеюсь, что это будет полезно для вас.

Другие вопросы по тегам