如何在Android Wear设备上运行Xamarin.Forms应用程序

如何在Android Wear设备上运行Xamarin.Forms应用程序,android,xamarin,wear-os,xamarin.forms,runtimeexception,Android,Xamarin,Wear Os,Xamarin.forms,Runtimeexception,如何在Android Wear设备上运行Xamarin.Forms.Platform.Android.FormsApplicationActivity?我的类的OnCreate方法中的调用base.OnCreate(bundle)总是抛出一个运行时异常“您不能在手表上使用不确定的进度” 这是我的密码: namespace Test { [Activity (Label = "Temp.Droid", Icon = "@drawable/icon", MainLauncher = true

如何在Android Wear设备上运行
Xamarin.Forms.Platform.Android.FormsApplicationActivity
?我的类的
OnCreate
方法中的调用
base.OnCreate(bundle)
总是抛出一个运行时异常“您不能在手表上使用不确定的进度”

这是我的密码:

namespace Test
{
    [Activity (Label = "Temp.Droid", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
        protected override void OnCreate (Bundle bundle)
        {
            base.OnCreate (bundle);

            global::Xamarin.Forms.Forms.Init (this, bundle);

            LoadApplication (new App ());
        }
    }
}

App
的实现应该无关紧要,因为调用super
onCreate
时已经抛出异常,而不是调用
LoadApplication(new App())
来加载应用程序。但是,它是项目向导为Xamarin移动应用程序生成的基本实现。

您不会在可穿戴设备上运行Xamarin.Forms应用程序。您需要在原生Xamarin.Android中创建一个新的Android Wear应用程序。可穿戴应用程序使用特殊主题、特殊控件和特殊API。一个很好的例子是我如何使用Hanselman.Forms,它是Xamarin.Forms的主要应用程序,但与Android Wear应用程序也有关联:

尽管James Montmagno给出了答案,但我发现可以在Xamarin表单中同步数据。我使用的方法,并纳入它的Xamarin形式。首先,请注意安装了正确的Android SDK()。 假设您使用标准应用程序,建议您在单独的Xamarin Forms跨平台应用程序中创建Wear应用程序。这是因为磨损尺寸与手机尺寸不同

在you Wear应用程序和手机应用程序中,右键单击Android项目的参考,然后选择MANAGE NUGET PACKAGES。浏览磨损并选择
Xamarin.GooglePlayServices.Wearable版本29.0.0(更高版本会出现问题)

在两个应用程序中单击Android项目的属性。确保默认名称空间(应用程序选项卡)和包名称(Android清单选项卡)相同。另外,请确保软件包名称没有大写字母,这将导致在将应用程序发布到Android应用商店时出现问题。 将“使用Android版本编译”的值更改为“API级别21(Xamarin.Android v5.0支持)”

在两个项目的Android Main活动中添加使用

using Android.Gms.Wearable;
using Android.Gms.Common.Apis;
using Android.Support.V4.Content;
然后将两个应用程序的MainActivity更改为以下内容:

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity, IDataApiDataListener, IMessageApiMessageListener
{
    private static GoogleApiClient client;
    const string _syncPath = "/MySyncPath/Data";
    static string device = "Watch";
    static string text= "";

    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App());

        client = new GoogleApiClient.Builder(this)
              .AddApi(WearableClass.API)
              .Build();
        IntentFilter filter = new IntentFilter(Intent.ActionSend);
        MessageReciever receiver = new MessageReciever(this);
        LocalBroadcastManager.GetInstance(this).RegisterReceiver(receiver, filter);
    }

    internal class MessageReciever : BroadcastReceiver
    {
        MainActivity _main;
        public MessageReciever(MainActivity owner) { this._main = owner; }
        public override void OnReceive(Context context, Intent intent)
        {
            _main.ProcessMessage(intent);
        }

    }

    public void OnDataChanged(DataEventBuffer dataEvents)
    {
        var dataEvent = Enumerable.Range(0, dataEvents.Count)
                                  .Select(i => dataEvents.Get(i).JavaCast<IDataEvent>())
                                  .FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));
        if (dataEvent == null)
            return;
        //do stuffs here
    }

    public override void OnBackPressed()
    {
           base.OnBackPressed();
    }

    protected override void OnStart()
    {
        base.OnStart();
        Android.Util.Log.Info("WearIntegration", "Received Message");

        client.Connect();
    }

    public void OnConnected(Bundle p0)
    {
        WearableClass.DataApi.AddListener(client, this);
    }

    public void OnConnectionSuspended(int reason)
    {
        Android.Util.Log.Error("GMSonnection suspended " + reason, "");
        WearableClass.DataApi.RemoveListener(client, this);
    }

    public void OnConnectionFailed(Android.Gms.Common.ConnectionResult result)
    {
        Android.Util.Log.Error("GMSonnection failed " + result.ErrorCode, "");
    }


    protected override void OnStop()
    {
        base.OnStop();
        client.Disconnect();
    }

    public void OnMessageReceived(IMessageEvent messageEvent)
    {
        if (messageEvent.Path.Equals(_syncPath))
        {
            var msg = System.Text.Encoding.UTF8.GetString(messageEvent.GetData());

            this.RunOnUiThread(() =>
                Android.Widget.Toast.MakeText(this, msg, ToastLength.Long).Show());
        }
    }

    public void ProcessMessage(Intent intent) 
    {
        if (intent.GetStringExtra("Device") != device)
        {
            text = intent.GetStringExtra("WearMessage");
            //do stuffs here

        }
    }

    public void SendData() {
        try {
            var request = PutDataMapRequest.Create(_syncPath);
            var map = request.DataMap;
            map.PutString("Device", device);
            map.PutString("Message", "Xamarin Forms says Hello from Wearable!");
            map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
            WearableClass.DataApi.PutDataItem(_client, request.AsPutDataRequest());
        }
        finally {
            _client.Disconnect();
        }

}
然后将WearService类添加到两个Android项目中添加与添加到Main活动中相同的用法,并按如下方式更改WearService:

[Service]
[IntentFilter(new[] { "com.google.android.gms.wearable.BIND_LISTENER" })]
public class WearService : WearableListenerService
{
    const string _syncPath = "/KorfballTimer/Data";
    GoogleApiClient _client;

    public override void OnCreate()
    {
        base.OnCreate();
        _client = new GoogleApiClient.Builder(this.ApplicationContext)
                .AddApi(WearableClass.API)
                .Build();

        _client.Connect();

        Android.Util.Log.Info("WearIntegrationreated", "");
    }

    public override void OnDataChanged(DataEventBuffer dataEvents) 
    {
        var dataEvent = Enumerable.Range(0, dataEvents.Count)
                                  .Select(i => dataEvents.Get(i).JavaCast<IDataEvent)
                                  .FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));
        if (dataEvent == null)
            return;

        //get data from wearable
        var dataMapItem = DataMapItem.FromDataItem(dataEvent.DataItem);
        var map = dataMapItem.DataMap;
        string message = dataMapItem.DataMap.GetString("Message");

        Intent intent = new Intent();
        intent.SetAction(Intent.ActionSend);
        intent.PutExtra("WearMessage", message);
        intent.PutExtra("Device", map.GetString("Device"));
        LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
    }
}
[服务]
[IntentFilter(新[]{“com.google.android.gms.wearable.BIND_LISTENER”}]
公共类WearService:WearableListenerService
{
常量字符串_syncPath=“/KorfballTimer/Data”;
GoogleapClient(用户);
public override void OnCreate()
{
base.OnCreate();
_client=new GoogleApiClient.Builder(this.ApplicationContext)
.AddApi(WearableClass.API)
.Build();
_client.Connect();
Android.Util.Log.Info(“WearIntegrationCreated”和“);
}
公共覆盖无效OnDataChanged(DataEventBuffer dataEvents)
{
var dataEvent=Enumerable.Range(0,dataEvents.Count)
.Select(i=>dataEvents.Get(i).JavaCast x.Type==DataEvent.TypeChanged&&x.DataItem.Uri.Path.Equals(_syncPath));
if(dataEvent==null)
返回;
//从可穿戴设备获取数据
var dataMapItem=dataMapItem.FromDataItem(dataEvent.DataItem);
var map=dataMapItem.DataMap;
字符串消息=dataMapItem.DataMap.GetString(“消息”);
意图=新意图();
intent.SetAction(intent.ActionSend);
intent.PutExtra(“WearMessage”,message);
intent.PutExtra(“设备”,map.GetString(“设备”);
LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
}
}
最后,在元素下的AndroidManifest.xml中添加元数据:

    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />


如果您不想在Wear应用程序中使用IOS和Windows项目,只需删除它们。现在,您可以像使用手机应用程序一样,以Xamarin表单构建Wear应用程序。快乐编码。

它实际上是配置为Wear应用程序还是PCL?引用Wear中不可用的项目?或许可以按照指导操作此处使用版本15.5.1的VS2017社区,此解决方案将不起作用。在VS2017版本15.5.2中,此解决方案将使用最新版本的Xamarin.Forms(v2.5.0.121934)再次起作用Xamarin.GooglePlayservice.Wearable version v42.1001.0.到今天仍然有效吗?因为我刚刚在一个可穿戴模拟器上测试了我的XF应用程序,没有任何改动,它在ui未优化的情况下运行良好。
    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />