Windows Phone 8.1 Support in Xamarin Forms

Recently Xamarin Forms has been expanded to support Windows Phone 8.1 and Windows 8.1. There are instructions online for adding a Windows Phone 8.1 app to your solution and plugging it all together here:-

http://developer.xamarin.com/guides/cross-platform/xamarin-forms/windows/getting-started/phone/

However there is a small omission which will lead to a build error – #6 tells you to remove the PhonePage base class from your MainPage definition but you actually need to replace it with:-

public sealed partial class MainPage : Xamarin.Forms.Platform.WinRT.WindowsPhonePage

WindowsPhonePage contains the LoadApplication method which you add in #7.

The instructions for Windows 8.1 require the same tweak except using WindowsPage instead of WindowsPhonePage

Background Bluetooth Services on Windows Phone 8.1

Added in Windows Phone 8.1 was a new RfcommConnectionTrigger which allows you to host a Bluetooth service on the device and have your background task triggered when an incoming connection is established. This makes a lot of sense as having to have your app in the foreground to receive connections limits the usage somewhat.

In its simplest form you just need to specify an RfcommServiceId for your service, register your background task and the system publishes the required SDP record which allows other devices to discover your service. Your background task is executed when an incoming connection is received and you can cast the TriggerDetails of the received IBackgroundTaskInstance to an RfcommConnectionTriggerDetails. This gives you two useful things – RemoteDevice – a BluetoothDevice which describes the device which initiated the connection and Socket a StreamSocket which allows you to talk to the remote device.

This works well for most devices but what if you have more specific requirements for the published SDP record. In a foreground app you’d use RfcommServiceProvider and this allows you to set individual SDP attributes which are appended to the default record. The RfcommConnectionTrigger mechanism provides something similar but there is literally no documentation on how it is expected to work. The difference from the foreground approach is that rather than setting attributes with id and raw body it has a property called SdpRecord which accepts an iBuffer. It’s very easy to get from a byte array to an iBuffer but we still have to create the SDP record…

At first I thought the best approach was to look at what the default record contained – but unless you assign a record the property returns null (even once the background task is registered and the SDP record is published). The only way to see the exposed record is to read it remotely from another Bluetooth device (one which is a desktop app since device and service discovery is not supported from WinRT). I used Alan’s SdpBrowserDesktop app from 32feet.This showed a fairly standard set of attributes:-

• Record:
AttrId: 0x0000 -- ServiceRecordHandle
UInt32: 0x10009
AttrId: 0x0001 -- ServiceClassIdList
ElementSequence
    Uuid16: 0x1101 -- SerialPort
AttrId: 0x0004 -- ProtocolDescriptorList
ElementSequence
    ElementSequence
        Uuid16: 0x100 -- L2CapProtocol
        UInt16: 0x3
    ElementSequence
        Uuid16: 0x3 -- RFCommProtocol
        UInt8: 0x6
( ( L2Cap, PSM=Rfcomm ), ( Rfcomm, ChannelNumber=6 ) )
AttrId: 0x0005 -- BrowseGroupList
ElementSequence
    Uuid16: 0x1002 -- PublicBrowseGroup

The ServiceRecordHandle is allocated by the host device as is the Rfcomm channel (here 6). If I want to add a service name to this I realised I would have a problem – how can I build a record when I don’t yet know the port that will be assigned (and there is never a way to find this out from WinRT). I built the record anyway hoping that the system would simply read it and replace the value at registration. You get an ArgumentException at the point you call BackgroundTaskBuilder.Register() and it doesn’t contain any useful information. I tried a few variations of this approach and then happened upon another approach – what if I build a valid record but just for the attributes I want to add. Luckily this approach works – your custom attributes are appended to the end of the record and registration succeeds.

I’m documenting this here because there isn’t a way to add to the MSDN documentation and hopefully someone searching will find the answer. I’m working on porting code across so that there is a friendly API available for all current Windows flavours which helps in reading and writing SDP records and attribute values. I can only assume the approaches used by the foreground and background APIs differ because they were written at different times by different teams.

My custom record consists of an ElementSequence, with a 16bit UUID for the attribute (0x0100 – ServiceName) followed by a UTF-8 encoded string e.g.

Element Sequence
   Uuid16: 0x0100
   String (len 11): "Hello World"

Windows 10 supports this same approach and it is no longer for Phones only – it should be universal across phones, desktop and IOT so I anticipate people doing more advanced things with Bluetooth…

iRAPP Remote Desktop

Firstly, just to clarify, I don’t rap – this is a post about a useful Remote Desktop server for OSX. Wait, I hear you cry, you’re a Windows developer! Well that is true but I also use Xamarin to produce apps for iOS and Android and to build and deploy iOS apps you have to have a Mac in your workflow. Xamarin have done a great job to minimise this – you can do your development in Visual Studio on your PC but you have to connect to a Mac running their Build Server and you need to use the Mac to deploy apps to the iTunes store.

Because it was only for occasional interaction I don’t want the Mac Mini (which is a very nice looking piece of hardware BTW) setup with a Keyboard/Mouse/Monitor taking up space so it’s running as a headless device. I originally used TeamViewer to occasionally connect to the device but randomly last month the PC client started crashing on load and even an uninstall/reinstall wouldn’t get it working again so I looked for an alternative. I came across iRAPP by CodeRebel. I’d not heard of it before but it seemed perfect – it’s a Remote Desktop provider supporting Microsoft’s RDP protocol which means you can connect using the standard Windows Remote Desktop app. The app is available for Windows, Windows Phone, Android, Mac and iOS and since I use other Windows machines I have it installed on every device I use. By installing iRAPP on my Mac it just works in my Windows environment with no hassles. I found it very reliable over the trial period and have just purchased a license – $79 for a year and even that process is straight-forward and just works. Purchase the license online and click Update License from the iRAPP control panel and boom it’s up and running again!

There is also an iRAPP client for Windows which adds an extra dimension – it allows you to “blend” your desktop – switching to it adds the OSX menubar and dock to your desktop and will open apps in windows transparently on your desktop so you can feel like you are running OSX applications side by side with your Windows applications. Fun stuff but I didn’t really need this.

If you’re interested take a look here – http://www.coderebel.com/products/irapp-client/. There’s no ulterior motive here – I’m not receiving a commission or anything, I was just really impressed by the product and it’s proved reliable and useful.

Bluetooth HID on Windows Phones

Microsoft have already announced that Bluetooth HID (keyboard) support is finally coming in Windows 10, but it was quietly added in Windows Phone 8.1 GDR2. The problem is this update won’t be circulated to most phones. It is however present on the new Lumia 640 series. WP_20150511_19_41_09_Pro

It’s very easy to setup a Bluetooth Keyboard with your phone once you’ve paired the devices you just type when you’re in an app which accepts text input and it just works. That could be writing an opus in Word or a quick text message. As a developer there is nothing special we have to do to support this. There are a couple of things to be aware of:-

  1. If the keyboard has special function keys like volume, search, windows etc these do nothing (even if they map to a logical function on the phone).
  2. The Page Up and Page Down keys raise and lower the soft input panel on screen
  3. The keyboard won’t allow you to skip to a section in jump lists (like picking a mail recipient for example)
  4. Although it paired successfully my Symbol CS3070 Barcode Scanner doesn’t actually do anything (When in HID mode it should work as a Bluetooth Keyboard and put the barcode value directly into the keyboard buffer).

There are some interesting subtle visual changes in GDR2. The circular right-arrow button at the bottom of the start screen which provides an alternative to swiping to get to the programs list has been replaced with a more “Big Windows” all apps link

All Apps GDR2

Clear signs of the “oneness” of Windows which will follow!

Charming Updates

I’ve made a couple of steps forward with the Charming project:

1. I’ve added a new library for Windows Phone 8.0 and 8.1 Silverlight to provide a “Universal Apps” style ResourceLoader for Silverlight (.resx) resources. It currently supports the default AppResources string table only but this is enough in most cases to reduce your #ifdefs a little where you are sharing code between a Silverlight phone app and a Windows Store app. It could also be useful to help move an existing Silverlight app to the new runtime model in stages.

https://www.nuget.org/packages/InTheHand.ApplicationModel.Resources/

2. I’ve changed the license on the project to the MIT license which is even less restrictive than the previous Microsoft license. While this is currently showing on the project site it won’t be reflected in NuGet until each of the packages is updated.

3. I’m still looking into the Windows 10 SDKs to see which bits are still relevant going forwards. Despite the core Universal App Platform there are still different APIs on Phones and PCs where it might still be necessary to bridge the gap.

Moving Forwards: Geolocation

Recently I open-sourced a number of Compact Framework projects and when I was working on re-writing an application which used them as a Windows Runtime app I started to think about how much of the code might be useful for app projects. Obviously the API surface for Windows Runtime is totally different to the .NET Compact Framework. In some cases functionality which I wrote is built into the runtime, in other cases I’d made use of P/Invoke to call native APIs which is not an option. However one thing I noticed was that the Windows.Devices.Geolocation namespace which supersedes System.Device.Location was missing one key feature – a built in method to determine the distance between two points. Since I had code for this which was using the same method as the .NET framework I thought this was a prime candidate for migration.

The Windows Runtime is a rather more complex API and whereas .NET had a single GeoCoordinate type the runtime has BasicGeoposition (containing raw latitude, longitude etc) and a number of other types – Geocoodinate, Geocircle, Geopoint etc I decided to first implement an extension method which would work with two BasicGeopositions and then as a helper added an extension method for Geocoordinate which used the logic from the first.

The methods now live in a new NuGet package currently supporting Windows 8.1 and Windows Phone 8.1 – Charming Geolocation and the code will be available in the Charming project. Just add:-

using InTheHand.Devices.Geolocation;

and you can use the GetDistanceTo methods.

Part of the project using this code required an iOS implementation too for which I’ve used Xamarin. Anyone who has used this will know that while the location functionality is similar to what we are familiar with on Windows the API is significantly different. Because I wanted to fix that just the once too I wrote a wrapper API to expose the Windows API wrapping all the CoreLocation stuff. I’ll be adding this library to the NuGet package shortly and am also in the process of moving all the Charming code from CodePlex to GitHub too.

Microsoft Windows Platform Development MVP

Follow

Get every new post delivered to your Inbox.

Join 698 other followers