Announcing Project Rome Android SDK

Project Rome Overview

Project Rome is a platform for creating experiences that transcend a single device and driving up user engagement – empowering a developer to create human-centric scenarios that move with the user and blur the lines between their devices regardless of form factor or platform.

We first shipped Project Rome capabilities for Remote Launch and Remote App Services in Windows 10 Anniversary Update.

Project Rome Android SDK

Today we are excited to announce the release of the Android version of the Project Rome SDK.  This Android SDK works both with Java and with Xamarin.

You can download the Project Rome SDK for Android here.

Capabilities exposed through the Project Rome Android SDK

Let’s take an example of an app that might need this capability. In the last blog post, we had talked about Paul and his Contoso Music App. In that scenario, Paul had his UWP app which was a music player, and he wanted to make sure that his users had a way to communicate between his app as they moved between devices.

If we take that example further, we can imagine that Paul has a Contoso Music App for Android as well. Paul notices that most of his users use his app on Windows, and on Android. These are the same users logged in with the same MSA. Paul wants to make sure that his users’ experience translates well when they move between their Android and Windows devices. Paul also notices that many of his Windows users run his UWP app on their Xbox at home.

With the Project Rome Android SDK Paul can use:

  1. The Remote Systems API to discover other Windows devices that the user owns. The Remote Systems APIs will allow the Contoso Music app to discover these devices on the same network, and through the cloud.
  2. Once discovered, the Remote Launch API will launch his app on another Windows device.
  3. Once his app is launched on the other device, Paul can use remote app services to control his app running on Windows from his Android device. This functionality is now available. Learn more here.

Thus, using the Project Rome Android SDK, Paul can bridge the experience gap that exists as his users move between their Android and Windows devices.

Capability Walkthrough

We will briefly walk through both a Java and Xamarin example.  We have full examples of UWP here: https://github.com/Microsoft/Windows-universal-samples/tree/dev/Samples/RemoteSystems and Android here: https://github.com/Microsoft/project-rome/tree/master/Android

Click on the image below to see the Android Sample app in action:

Using Java

Here are snippets in Java from our sample of how you’d use the Project Rome Android SDK.  The first step to get going with the Android SDK is to initialize the platform, where you’ll handle authentication.



Platform.initialize(getApplicationContext(), new IAuthCodeProvider() {
    @Override
    public void fetchAuthCodeAsync(String oauthUrl, Platform.IAuthCodeHandler authCodeHandler) {
        performOAuthFlow(oauthUrl, authCodeHandler);            
    }
}


Using OAuth you’ll retrieve an auth_code via a WebView:



public performOAuthFlow (String oauthUrl, Platform.IAuthCodeHandler authCodeHandler) {

    WebView web;
    web = (WebView) _authDialog.findViewById(R.id.webv);
    web.setWebChromeClient(new WebChromeClient());
    web.getSettings().setJavaScriptEnabled(true);
    web.getSettings().setDomStorageEnabled(true);

    // Get auth_code
    web.loadUrl(oauthUrl);

    WebViewClient webViewClient = new WebViewClient() {
        boolean authComplete = false;
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);

            if (url.startsWith(REDIRECT_URI)) {
                Uri uri = Uri.parse(url);
                String code = uri.getQueryParameter("code");
                String error = uri.getQueryParameter("error");
                if (code != null && !authComplete) {
                authComplete = true;
                authCodeHandler.onAuthCodeFetched(code);
                } else if (error != null) {
                  // Handle error case                                    }
            }
         }
    };

    _web.setWebViewClient(webViewClient);
}


Now, discover devices:



RemoteSystemDiscovery.Builder discoveryBuilder;
discoveryBuilder = new RemoteSystemDiscovery.Builder().setListener(new IRemoteSystemDiscoveryListener() {
    @Override
    public void onRemoteSystemAdded(RemoteSystem remoteSystem) {
        Log.d(TAG, "RemoveSystemAdded = " + remoteSystem.getDisplayName());
        devices.add(new Device(remoteSystem));
        // Sort devices
        Collections.sort(devices, new Comparator<Device>() {
            @Override
            public int compare(Device d1, Device d2)
            {
                return d1.getName().compareTo(d2.getName());
            }
        });
       }
});
startDiscovery();


Remote launch a URI to your device:



new RemoteSystemConnectionRequest(remoteSystem)
String url = "http://msn.com"

new RemoteLauncher().LaunchUriAsync(connectionRequest,
        url,
        new IRemoteLauncherListener() {
            @Override
            public void onCompleted(RemoteLaunchUriStatus status) {

            …
            }
        };


Using Xamarin

Similarly, here are snippets in Xamarin.

You will first initialize the Connected Devices Platform:



Platform.FetchAuthCode += Platform_FetchAuthCode;
var result = await Platform.InitializeAsync(this.ApplicationContext, CLIENT_ID);


Using OAuth you’ll retrieve an auth_code:



private async void Platform_FetchAuthCode(string oauthUrl)
{
    var authCode = await AuthenticateWithOAuth(oauthUrl);
    Platform.SetAuthCode(token);
}


Now, discover devices:



private RemoteSystemWatcher _remoteSystemWatcher;
private void DiscoverDevices()
{
    _remoteSystemWatcher = RemoteSystem.CreateWatcher();
    _remoteSystemWatcher.RemoteSystemAdded += (sender, args) =>
    {
        Console.WriteLine("Discovered Device: " + args.P0.DisplayName);
    };
    _remoteSystemWatcher.Start();
}


Finally, connect and launch URIs using LaunchUriAsync:



private async void RemoteLaunchUri(RemoteSystem remoteSystem, Uri uri)
{
    var launchUriStatus = await RemoteLauncher.LaunchUriAsync(new RemoteSystemConnectionRequest(remoteSystem), uri);
}


If you want to see the Xamarin code, please head over to https://github.com/Microsoft/project-rome/tree/master/Xamarin

Wrapping Up

Project Rome breaks down barriers across all Windows devices and creates experiences that are no longer constrained to a single device. With today’s announcement, we are bringing this capability to Android devices as well. The Remote Systems API available in Windows 10 is a key piece of Project Rome that provides exposure of the device graph and the ability to connect and command – this is fundamental for driving user engagement and productivity for applications across all devices.

To learn more and browse sample code, including the snippets shown above, please check out the following articles and blog posts:

The Windows team would love to hear your feedback.  Please keep the feedback coming using our Windows Developer UserVoice site. If you have a direct bug, please use the Windows Feedback tool built directly into Windows 10.

Updated August 30, 2017 2:20 pm