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

标签 android xamarin wear-os xamarin.forms runtimeexception

如何在 Android Wear 设备上运行 Xamarin.Forms.Platform.Android.FormsApplicationActivity?在我的类的 onCreate 方法中调用 base.OnCreate(bundle) 总是抛出 RuntimeException“你不能在 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 的实现应该无关紧要,因为异常已经在调用 super onCreate 时抛出,而不是通过调用 LoadApplication (new App () ) 用于加载应用程序。然而,它是由 Xamarin 移动应用程序的项目向导生成的基础实现。

最佳答案

尽管有 James Montemagno 的回答,但我发现可以在 Xamarin Forms 中同步数据。我用了Vincent Maverick的方法并将其合并到 Xamarin Forms 中。首先注意你已经安装了正确的 Android SDK ( Android Wear Tutorial - A Comprehensive Introduction )。 假设你有标准应用程序,建议在单独的 Xamarin Forms 跨平台应用程序中创建 Wear 应用程序。这是因为 Wear 尺寸与手机尺寸不同。

在 Wear 应用和手机应用中,右键单击 Android 项目的引用并选择管理 NUGET 包。浏览磨损并选择
Xamarin.GooglePlayServices.Wearable 版本 29.0.0(更高版本会出现问题)。

enter image description here

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

enter image description here

在两个项目的 Android MainActivity 中添加 usings

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

}

在您的 Phone 应用程序中,将静态字符串设备更改为 Phone 并根据需要更改消息文本:

    static string device = "Phone";

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

然后将 WearService 类添加到您的两个 Android 项目中,添加与添加到 MAinActivity 中相同的用法,并按如下方式更改 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);
    }
}

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

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

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

关于android - 如何在 Android Wear 设备上运行 Xamarin.Forms 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29692220/

相关文章:

android - 获取Android系统开机时间的方法

android - 如何获取 Xamarin Studio 创建的 keystore 的 SHA-1 指纹?

ios - 未在可移植类库中实现。在 iOS 应用程序中将 Riverts 与 Xamarin 结合使用

android - 通知操作不打开服务

android - 如何运行 Android Sample Watch Face?

bluetooth - "LG G Watch"是否支持经典蓝牙

android - 如何使用kivy处理android运行时权限

android - 如何恢复协程的真实调用轨迹?

android - 包签名与之前安装的版本不匹配

iOS,TableViewCell,动态更新单元格的高度