如何在Android Wear设备上运行Xamarin.Forms应用程序 [英] How to run a Xamarin.Forms Application on an Android Wear Device

查看:125
本文介绍了如何在Android Wear设备上运行Xamarin.Forms应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How can I run a Xamarin.Forms.Platform.Android.FormsApplicationActivity on an Android Wear device? The call base.OnCreate(bundle) inside the onCreate method of my class always throws a RuntimeException "You cannot use indeterminate progress on a watch".

这是我的代码:

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的实现应该无关紧要,因为在超级onCreate的调用上已经引发了异常,而不是通过调用LoadApplication (new App ())来加载应用程序.但是,它是项目向导为Xamarin移动应用程序生成的基本实现.

The implementation of App should not matter since the exception gets already thrown on the call of the super onCreate and not by calling LoadApplication (new App ()) for loading the application. However its the base implementation generated by the project wizard for a Xamarin Mobile Application.

推荐答案

尽管James Montemagno给出了答案,但我发现可以在Xamarin Forms中同步数据.我使用了 Vincent Maverick 并将其合并到Xamarin Forms中.首先,请确保您已安装正确的Android SDK( Android Wear教程-全面介绍). 假设您拥有标准应用程序,建议在单独的Xamarin Forms Cross Platform应用程序中创建Wear应用程序.这是因为Wear尺寸与Phone尺寸不同.

Despite the answer of James Montemagno I discovered it is possible to sync data in Xamarin Forms. I used the method of Vincent Maverick and incorporated it in Xamarin Forms. First of all take care you have the right Android SDK installed (Android Wear Tutorial - A Comprehensive Introduction). Assuming you hve your standard app, it is advised to create Wear app in a separate Xamarin Forms Cross Platform application. This because the Wear sizes are different from Phone sizes.

在Wear应用程序和电话应用程序中,右键单击Android项目的参考,然后选择MANAGE NUGET PACKAGES.浏览磨损并选择
Xamarin.GooglePlayServices.Wearable版本29.0.0(较高的版本会带来问题).

In both you Wear app and your phone app right click on the References of your Android project and select MANAGE NUGET PACKAGES. Browse for wear and select
Xamarin.GooglePlayServices.Wearable Version 29.0.0 (higher versions give problems).

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

Click on the Properties of your Android project in both applications. Make sure the Default Namespace (Application tab) and Package name (Android Manifest tab) are the same. Also make sure the Package name does not have capitals, this will cause problems in releasing your app to the Android store. Change the value of "Compile using Android version" to "API Level 21 (Xamarin.Android v5.0 Support).

在您的两个项目的Android MainActivity中添加使用方法

In your Android MainActivity of both projects add usings

using Android.Gms.Wearable;
using Android.Gms.Common.Apis;
using Android.Support.V4.Content;

然后将两个应用程序的MainActivity更改为以下内容:

Then change your MainActivity of both applications to the following:

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();
        }

}

在您的电话"应用程序中,如果需要,将静态字符串设备更改为电话"并更改消息文本:

In your Phone application change the static string device to Phone and change the message text if you want to:

    static string device = "Phone";

            map.PutString("Message", "Xamarin Forms says Hello from Phone!");

然后将WearService类添加到两个Android项目中,添加与添加到MAinActivity中相同的用法,并更改Wearservice,如下所示:

Then add the WearService class to both your Android Projects add the same usings as added to the MAinActivity an change the Wearservice as follows:

[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);
    }
}

最后,在元素下的AndroidManifest.xml中添加元数据:

And finally, Add the meta data in the AndroidManifest.xml under element:

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

如果您不希望在Wear应用程序中使用IOS和Windows项目,只需删除它们即可.现在,您可以像使用电话应用程序一样,在Xamarin Forms中构建Wear应用程序.编码愉快.

If you don't want the IOS and Windows projects in your Wear application, just delete them. Now you can build your Wear application in Xamarin Forms just as you do with your phone application. Happy Coding.

这篇关于如何在Android Wear设备上运行Xamarin.Forms应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆