{"id":31489,"date":"2017-05-05T08:39:21","date_gmt":"2017-05-05T15:39:21","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=31489"},"modified":"2017-05-05T08:39:21","modified_gmt":"2017-05-05T15:39:21","slug":"building-remote-control-companion-app-android-project-rome","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/building-remote-control-companion-app-android-project-rome\/","title":{"rendered":"Building a Remote Control Companion App for Android with Project Rome"},"content":{"rendered":"<p>\t\t\t\t<em>This is a special guest post from the Project Rome team at Microsoft. Shawn works at Microsoft on the Project Rome team. You can find him on Twitter at <a href=\"http:\/\/twitter.com\/shawnhenry\">@shawnhenry<\/a>.<\/em><\/p>\n<p>Xamarin allows you to build mobile apps in C# for iOS, Android, and Windows. It&#8217;s easy to share code across these platforms with Xamarin, but what if you want your mobile apps on each of these platforms to talk to each other? Enter <a href=\"https:\/\/github.com\/Microsoft\/project-rome\">Project Rome<\/a>, which allows you to build applications that span devices and mobile platforms. In this blog post, you&#8217;ll learn how to build a companion remote control app for Android to control a UWP media player application using Xamarin and Project Rome.<\/p>\n<h2>What is Project Rome?<\/h2>\n<p><a href=\"https:\/\/github.com\/Microsoft\/project-rome\">Project Rome<\/a> is a platform for creating experiences that span devices and drive user engagement in apps. It enables developers to create human-centric features that move with the user and blur the lines between their devices, regardless of form factor or platform.<\/p>\n<p>Project Rome capabilities first shipped with the Windows 10 Anniversay Update and enable developers to:<\/p>\n<ul>\n<li>Discover devices associated with a user&#8217;s Microsoft Account or Azure Active Directory Account using the <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/uwp\/launch-resume\/discover-remote-devices\">RemoteSystem APIs<\/a>.<\/li>\n<li>Once discovered, use the <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/uwp\/launch-resume\/launch-a-remote-app\">RemoteLauncher APIs<\/a> to launch apps and URIs on the remote device.<\/li>\n<li>Use <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/uwp\/launch-resume\/communicate-with-a-remote-app-service\">Remote App Services<\/a> to enable rich communication between apps across devices.<\/li>\n<\/ul>\n<p>The Project Rome Android SDK was released last month (complete with Xamarin .NET binding), enabling the first two bullet points. This month&#8217;s release adds the ability for Android applications to target App Services on remote Windows machines.<\/p>\n<h2>The Podcast App<\/h2>\n<p>There are many scenarios enabled by Project Rome, but one of the most compelling is building mobile companion applications for UWP applications. In this blog post, we&#8217;ll build a &#8216;remote control&#8217; companion application, but first we need an application to control remotely:<\/p>\n<p>The <a href=\"https:\/\/github.com\/Microsoft\/Windows-universal-samples\/tree\/master\/Samples\/VideoPlayback\">VideoPlayback UWP sample<\/a> from the Windows SDK provides a good place to start. Other than cleaning up the UI a bit (SDK samples typically don&#8217;t win any beauty contests), we added one other piece of functionality: the ability to read and parse RSS feeds of our <a href=\"http:\/\/www.xamarinpodcast.com\/\">favorite podcast<\/a>. We&#8217;ll call this app: RomeCast.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/romecast.png\" alt=\"RomeCast podcast application for UWP for the Xamarin Podcast.\" width=\"866\" height=\"632\" class=\"aligncenter size-full wp-image-31490\" \/><\/p>\n<h3>Adding Launch URI Support<\/h3>\n<p>Now that we have a basic media playback application, let&#8217;s make it command-able from other devices. This is easier than it might seem. First, we&#8217;ll declare that our RomeCast app supports being activated via a protocol. This can be done in the Package.appmanifest XML file or by using the designer, as shown below. Double-click the Package.appmanifest file to launch the designer, select the <strong>Declarations<\/strong> tab and add a <strong>Protocol definition<\/strong>. The only property that needs to be filled out, for now, is <strong>Name<\/strong>. We&#8217;ll call our new protocol &#8220;romecast&#8221;.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/protocol.png\" alt=\"Adding a protocol to our UWP app.\" width=\"897\" height=\"489\" class=\"aligncenter size-full wp-image-31492\" \/><\/p>\n<p>Now we need to write some code to tell the application what to do when it&#8217;s been activated via a protocol. In this case, we&#8217;ll override the <code>OnActivated<\/code> method in <code>App.xaml.cs<\/code> to pass the URI on to our <code>MainPage<\/code>:<\/p>\n<pre>\nprotected override void OnActivated(IActivatedEventArgs e)\n{\n    LoadFrame(e);\n    if (e.Kind == ActivationKind.Protocol)\n    {\n        var uriArgs = e as ProtocolActivatedEventArgs;\n        if (uriArgs != null)\n        {\n            Frame rootFrame = Window.Current.Content as Frame;\n            var page = rootFrame.Content as MainPage;\n                        \n            page?.HandleCommand(uriArgs.Uri.Query);\n        }\n    }\n    Window.Current.Activate();\n}\n<\/pre>\n<p>And in the <code>MainPage<\/code>, we&#8217;ll parse the URI and map it to commands on the <code>MediaPlayer<\/code> object:<\/p>\n<pre>\ninternal void HandleCommand(string commandString)\n{\n    if (commandString != null)\n    {\n        switch (commandString)\n        {\n            \/\/Commands\n            case \"play\": mediaPlayer.Play(); break;\n            case \"pause\": mediaPlayer.Pause(); break;\n            case \"prev\": playbackList.MovePrevious(); break;\n            case \"next\": playbackList.MoveNext(); break;\n        }\n    }\n}\n<\/pre>\n<p>We can test out that everything is working, and that our app can be commanded via URIs, by opening up a web browser and trying some of the commands:<\/p>\n<ul>\n<li>romecast:command?play<\/li>\n<li>romecast:command?pause<\/li>\n<li>romecast:command?prev<\/li>\n<li>romecast:command?next<\/li>\n<\/ul>\n<h2>Setting up the Android App<\/h2>\n<p>We&#8217;re done with the UWP project for now. Next, we&#8217;ll start on the Android project, but first we need to generate a Microsoft Account application ID from <a href=\"https:\/\/apps.dev.microsoft.com\">https:\/\/apps.dev.microsoft.com<\/a>. This will allow users to authenticate with their Microsoft Account and see the list of devices associated with their account.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/GenerateAppId.png\" alt=\"Generating an App Id.\" width=\"1212\" height=\"508\" class=\"aligncenter size-full wp-image-31493\" \/><\/p>\n<p>Back in our Android project, we can add the <a href=\"https:\/\/www.nuget.org\/packages\/Microsoft.ConnectedDevices.Xamarin.Droid\/\">Microsoft.ConnectedDevices.Xamarin.Droid<\/a> NuGet package to our project, authenticate, and initialize the Connected Devices platform:<\/p>\n<pre>\nPlatform.FetchAuthCode += Platform_FetchAuthCode;\nvar result = await Platform.InitializeAsync(this.ApplicationContext, CLIENT_ID); \/\/CLIENT_ID from https:\/\/apps.dev.microsoft.com\n<\/pre>\n<p>The <code>FetchAuthCode<\/code> handler is used when the platform needs an authorization code from the user (i.e. form OAuth with Microsoft Account). <a href=\"https:\/\/github.com\/Microsoft\/\">See the sample<\/a> for more details.<\/p>\n<pre>\nprivate async void Platform_FetchAuthCode(string oauthUrl)\n{\n    var authCode = await AuthenticateWithOAuth(oauthUrl);\n    Platform.SetAuthCode(token);\n}\n<\/pre>\n<h3>Discovering Remote Devices<\/h3>\n<p>Discovering devices is straightforward, create a <code>RemoteSystemWatcher<\/code>, hook up the event handlers, and start discovering devices.<\/p>\n<pre>\nprivate RemoteSystemWatcher _remoteSystemWatcher;\nprivate void DiscoverDevices()\n{\n    \/\/create watcher\n\t_remoteSystemWatcher = RemoteSystem.CreateWatcher();\n\n    \/\/hook up event handlers\n\t_remoteSystemWatcher.RemoteSystemAdded += RemoteSystemWatcherOnRemoteSystemAdded;\n\t_remoteSystemWatcher.RemoteSystemRemoved += RemoteSystemWatcher_RemoteSystemRemoved;\n\t_remoteSystemWatcher.RemoteSystemUpdated += RemoteSystemWatcher_RemoteSystemUpdated;\n\n    \/\/start watcher\n\t_remoteSystemWatcher.Start();\n}\n<\/pre>\n<h3>RemoteLaunchUri<\/h3>\n<p>Finally, we can connect and launch URIs using <code>LaunchUriAsync<\/code>, sending exactly the same URIs we did when commanding the application locally.<\/p>\n<pre>\nprivate async void RemoteLaunchUri(RemoteSystem remoteSystem, Uri uri)\n{\n    var request = new RemoteSystemConnectionRequest(remoteSystem);\n    var launchUriStatus = await RemoteLauncher.LaunchUriAsync(request, uri);\n}\n<\/pre>\n<p>Run the app, and ta-da! we have a remote control Android app that will remotely control media playback in our UWP application.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/romecastremote.png\" alt=\"Remote control Android app for RomeCast.\" width=\"360\" height=\"640\" class=\"aligncenter size-full wp-image-31494\" \/><\/p>\n<h2>Summary<\/h2>\n<p>In this blog post, we learned how to use Xamarin and Project Rome to build a remote control companion application. And it was easy; the concepts can be extended to any type of cross-device application and for more advanced scenarios. For example, take a look at App Services, which enable a richer messaging framework than URIs. Also, be sure to check out:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/Microsoft\/project-rome\">Project Rome on GitHub<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Microsoft\/\">Romecast sample on GitHub<\/a><\/li>\n<li><a href=\"https:\/\/msdn.microsoft.com\/windows\/uwp\/launch-resume\/connected-apps-and-devices\">MSDN Connected Apps and Devices (Project Rome)<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>This is a special guest post from the Project Rome team at Microsoft. Shawn works at Microsoft on the Project Rome team. You can find him on Twitter at @shawnhenry. Xamarin allows you to build mobile apps in C# for iOS, Android, and Windows. It&#8217;s easy to share code across these platforms with Xamarin, but [&hellip;]<\/p>\n","protected":false},"author":1936,"featured_media":31494,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4],"class_list":["post-31489","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>This is a special guest post from the Project Rome team at Microsoft. Shawn works at Microsoft on the Project Rome team. You can find him on Twitter at @shawnhenry. Xamarin allows you to build mobile apps in C# for iOS, Android, and Windows. It&#8217;s easy to share code across these platforms with Xamarin, but [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/31489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1936"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=31489"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/31489\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=31489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=31489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=31489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}