Xamarin.Forms 不同设备上同一应用程序中两个页面之间的通信

Xamarin.Forms Communication Between Two Pages Within Same App on Different Devices

我正在使用的技术、框架和设备:

问题定义

目前我有一个测试 Xamarin.Forms 项目,它包含两个不同的 UI(XAML 文件):

使用下面的代码,我确保 HomePage.XAML 已部署到智能手机并且 watchscreen 已部署到智能手表:

Page homePage = new NavigationPage(new HomePage());

// BuildVersionCodes.R is a reference to Android version 11 (mostly now used by Wear OS 3.x)
if (Build.VERSION.SdkInt == BuildVersionCodes.R)
{
    // SM-R870 is a reference to the Samsung Galaxy Watch4
    // Note: This is needed to ensure the UI is specific to the UI of a smartwatch
    if (Build.Model == "SM-R870")
    {
        Page watchScreen = new NavigationPage(new WatchScreen());
        MainPage = watchScreen;
    }
}
else
{
    MainPage = homePage;
}

现在我想让这些页面在不同的设备上相互通信。 HomePage.xaml 存在于主 Xamarin.Forms 项目以及 WatchScreen.xaml 中。 我希望他们相互交流的方式是通过发送消息或其他方式。 Xamarin.Forms 项目还附带一个本地项目。在本机 Xamarin.Android 项目中,我尝试在 MainActivity.cs 中检索主项目中存在的按钮(在 WatchScreen.xaml 中存在此按钮,在 WatchScreen.xaml.cs 中我有一个返回此按钮的方法)。

WatchScreen.xaml.cs 中返回按钮的方法:

public Button GetSendButtonFromWearableUI() => btnSendMessage;

在 MainActivity.cs 中,我使用以下方法获得此方法:

Button button = (App.Current.MainPage.Navigation.NavigationStack.LastOrDefault() as WatchScreen)
.GetSendButtonFromWearableUI();

每当我通过这样做点击按钮时:

button.Clicked += delegate
{
    SendData();
};

一些数据应该从 MainActivity.cs 发送并被 HomePage.xaml 捕获并显示在上面。我尝试了几种方法,但没有成功实现需要发生的事情。因此,我想知道你们是否可以帮助我解决这个问题,我将不胜感激。

与此同时,我一直在调查这个问题并提出了解决方案。按照以下步骤获得相同的结果。为了使这个解决方案起作用,我结合了 Google 的可穿戴数据层 API 和 Microsoft 的 MessagingCenter。

另外,下面的示例仅显示了从智能手表到智能手机的通信。为了逆转过程,您可以将发送按钮放在主页而不是智能手表屏幕上,并确保订阅正确的消息。

最后一点: 请记住下面使用的来自 Google 的代码已被弃用,但它仍然有效...

用于完成这项工作的参考资料: Syncing Data Between Wearable and Handheld Devices Using Xamarin in Android

在 Xamarin.Forms 项目中安装了 Xamarin.Android 项目的依赖项:

  • Xamarin.Android.Support.v4
  • Xamarin.GooglePlayServices.Base
  • Xamarin.GooglePlayServices.Wearable

MessageKeys.cs

此 class 用于声明用于在设备之间发送和接收消息的消息密钥。

public class MessageKeys
{
   public const string Smartwatch = "Smartwatch";
   public const string Smartphone = "Smartphone";
}

Xamarin.Forms(基础项目)- App.xaml.cs

在 App.xaml.cs 中,如前所述,我确保可穿戴设备 UI 显示 WatchScreen.xaml 并且任何其他设备显示正常 Android UI -> HomePage.xaml.

Xamarin.Forms(基础项目)- WatchScreen.xaml.cs

从可穿戴设备向 Android 智能手机发送消息。

private void btnSendMessage_Clicked(object sender, EventArgs e)
{
    MessagingCenter.Send(Xamarin.Forms.Application.Current, MessageKeys.Smartwatch);
}

Xamarin.Forms(基础项目)- HomePage.xaml.cs

public HomePage()
{
    InitializeComponent();

    MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, MessageKeys.Smartphone, (sender) =>
    {
        DisplayAlert("Message", "Wearable message received!", "OK");
    });
 }

Xamarin.Forms(本机 Android 项目)- MainActivity.cs

在 MainActivity.cs 中,我实现了以下接口:

public class MainActivity : WearableActivity, DataClient.IOnDataChangedListener,
    GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener

变量:

private GoogleApiClient client;
    const string syncPath = "/[project name]/[subdirectory for watch]";

内部class'MessageReceiver'接收广播消息:

[BroadcastReceiver]
public class MessageReciever : BroadcastReceiver
{
    MainActivity main;

    public MessageReciever() { }
    public MessageReciever(MainActivity owner) { this.main = owner; }

    public override void OnReceive(Context context, Intent intent)
    {
            main.ProcessMessage(intent);
    }
 }

注册接收器(通过可穿戴数据层 API 接收),创建 Google 客户端并订阅智能手表消息(通过 MessagingCenter 检索消息)

protected override void OnCreate(Bundle bundle)
{
    IntentFilter filter = new IntentFilter(Intent.ActionSend);
    MessageReciever receiver = new MessageReciever(this);
    LocalBroadcastManager.GetInstance(this).RegisterReceiver(receiver, filter);

    client = new GoogleApiClient.Builder(this, this, this)
       .AddApi(WearableClass.Api)
       .Build();

    MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, MessageKeys.Smartwatch, (sender) =>
    {
        SendData();
    });
}

ProcessMessage 方法:将接收到的消息从可穿戴设备发送到智能手机

public void ProcessMessage(Intent intent)
{
    // For now I'm not sending the payload...
    string message = intent.GetStringExtra("WearMessage");
    MessagingCenter.Send(Xamarin.Forms.Application.Current, MessageKeys.Smartphone);
}

SendData(), OnStart(), OnStop(), OnDataChanged(这部分没有做任何事情,因为这是在项目外接收消息,我不需要它现在)、OnConnected()、OnConnectionSuspended()、OnConnectionFailed():

查看参考以查看使用了哪些代码,因为代码完全相同...P.S.: SendData 的一件事已更改。如果您想继续发送数据,请在 try 和 catch 块之后从 finally 中删除 'client.Disconenct()'。

Xamarin.Forms(本机 Android 项目)- WearableService 继承自 WearableListenerService:

WearableService 是一个新的 class 并在本机项目中创建。对于这部分,请参阅参考资料,因为它与我的项目中使用的代码完全相同。

为了全面了解正在发生的事情,我在下图中将其可视化:(示例显示了从智能手表到智能手机的通信方式)

如果你想从智能手机到智能手表进行通信,你可以这样做:

伙计们,就是这样。现在,您将使用可穿戴数据层 API 和 MessagingCenter 在同一应用程序中接收消息。我们没有单独的项目,而是使用单独的 UI 来实现这一点...