在基于 Xamarin 表单的应用程序中将数据从 android 服务传递到 ContentPage

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

我有一个基于 XamarinForms 的应用程序。

我在 Android 项目中创建了一个后台服务,该服务想将数据发送到显示给用户的 ContentPage(位于 PCL 中)。

如何将数据传递到 ContentPage(从 xx.Droid 项目到 PCL)?

一个解决方案是:

如果有更好的解决方案,能否提供给我?

这可以使用 C# 的概念来实现

  • 依赖服务
  • 事件

需要 4 个 class 来实现这样的实现:

  1. PCL(例如 CurrentLocationService.cs)中的接口,其中定义了事件处理程序。

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

  event EventHandler<PositionEventArgs> positionChanged;
 }
}

  1. 在 xxx.Droid 项目(例如 CurrentLocationService_Android.cs)中使用依赖服务实现 PCL 的接口

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 - 将具有接口实现的对象。 对象可以通过
  2. 获得

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 class,以便在服务和 ContentPage 之间传递数据。

这对我来说很有魅力。

希望对您有所帮助。