Microsoft Band SDK use with Windows Runtime Component

不羁岁月 提交于 2019-12-08 13:18:41

Yes, it is possible! You have to make sure, that when you test the connection in the Windows Runtime Component (from a Background Task), you have not previously connected the Band from the running main app. Even when you open a connection from within a Using-Statement and all resources should be released, there still is some port in use with the Band. In that case, connecting the Band from the Windows Runtime Component will fail.

Earlier there were bugs in Band SDK, which totally blocked this scenario. With the current version of SDK I succeeded creating a Windows Runtime Component capable of creating a tile and deploying a layout. Unfortunately I was only successful calling it from C# and failed to find a way to provide JavaScript support.

It looks like with the current situation it is not possible. Please look at this post: https://social.msdn.microsoft.com/Forums/en-US/93d04495-171f-411d-bd2c-82f55888827b/windows-runtime-ui-component?forum=winappswithcsharp . The post says that the runtime components using XAML can't be called from JS.

Band SDK has 4 situations when it demands the call arriving from UI thread.

  1. At the very first time the application hosting the SDK is calling into the Bluetooth library, that one talks to OS to request permissions from the user. If that call is not on UI thread the Bluetooth library will throw an exception. Once user agrees then Bluetooth can be called from non-UI thread.

  2. There must be at least one call on UI thread to request consent to obtain user Heart Rate in order to subscribe to Heart Rate data. The subscription itself can be done on any thread. The UI to request the consent is part of SDK.

  3. AddTile always asks permissions from the user. The UI dialog is part of SDK. Calling AddTile from non UI thread will fail.

  4. When adding a tile the code must provide its icon. Current implementation of SDK offers ToBandIcon extension methods for XAML classes like WritableBitmap. Construction of the bitmap will fail with RPC_WRONG_THREAD if the call arrives on non UI thread.

In my mind the need of Windows Runtime Component was justified by the support for JavaScript, C# and C++ together. If you do not need JavaScript then maybe you will succeed with your project.

Here is the piece of code which worked for me. The code works when the component is being called by C# UI thread (from the phone application) and it also works when called by non-UI thread because that magic line of code resolving the dispatcher succeeds in the C# process:

var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;

That line of code is supposed to resolve the dispatcher for the UI thread. So my experimental code obtains the dispatcher and schedules a call which will talk to the Band on UI thread. The "promise" is returned to the caller with the compatible IAsyncAction. JavaScript would handle it well if entire idea worked.

    private bool inCall;

    public IAsyncAction TestBandAsync()
    {
        var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;

        var completionSource = new TaskCompletionSource<int>();

        // x is to suppress CS2014
        var x = dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () =>
        {
            try
            {
                if (this.inCall)
                    throw new InvalidOperationException("Currently in call!");

                this.inCall = true;
                try
                {
                    WriteableBitmap textBitmap = new WriteableBitmap(1, 1);

                    // Get the list of Microsoft Bands paired to the phone.
                    IBandInfo[] pairedBands = await BandClientManager.Instance.GetBandsAsync();
                    if (pairedBands.Length < 1)
                        throw new InvalidOperationException("No bands found!");

                    var bitmap = await LoadBitmapAsync("ms-appx:///Assets/Smile.png");
                    var bandIcon = bitmap.ToBandIcon();

                    // Connect to Microsoft Band.
                    using (IBandClient bandClient = await BandClientManager.Instance.ConnectAsync(pairedBands[0]))
                    {
                        // Create a Tile with a TextButton on it.
                        Guid myTileId = new Guid("12408A60-13EB-46C2-9D24-F14BF6A033C6");

                        BandTile myTile = new BandTile(myTileId)
                        {
                            Name = "My Tile",
                            TileIcon = bandIcon,
                            SmallIcon = bandIcon
                        };

                        var designed = new BandTileLayout1();
                        myTile.PageLayouts.Add(designed.Layout);

                        // Remove the Tile from the Band, if present. An application won't need to do this everytime it runs. 
                        // But in case you modify this sample code and run it again, let's make sure to start fresh.
                        await bandClient.TileManager.RemoveTileAsync(myTileId);

                        await designed.LoadIconsAsync(myTile);

                        // Create the Tile on the Band.
                        await bandClient.TileManager.AddTileAsync(myTile);
                        await bandClient.TileManager.SetPagesAsync
                            (myTileId,
                            new PageData(new Guid("5F5FD06E-BD37-4B71-B36C-3ED9D721F200"),
                            0,
                            designed.Data.All));
                    }
                }
                finally
                {
                    this.inCall = false;
                }

                completionSource.SetResult(0);
            }
            catch (Exception ex)
            {
                completionSource.SetException(ex);
            }
        });

        return completionSource.Task.AsAsyncAction();
    }

Regards, Andrew

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!