Launching A Mobile App Via A URI Scheme

Sometimes, users inside your app will need access to another app to complete their task. Maybe its calling someone, viewing a webpage or launching Skype. Launching another app is rather easy and is done at the OS level.

URI Scheme

When you call upon another app you need to use its URI Scheme. This scheme is what is registered with the platform, and it links it to an app that can handle the request.

For example, when Skype installs on your device, it will register the URI Scheme skype with the platform. Now when an app calls for skype://, it knows which app will accept the request.

If you want to pass information to the app you can do so via the string you send to the platform. While https:// will launch the browser, https://google.com will launch the browser and load Google. Anything after the URI Scheme is sent to the app, and can be actioned upon. The format of the data that is sent after the // however is up to the app, and they can all be very different.

If you want to learn how your app can register itself with the platform, to receive requests, have a look at Registering A URI Scheme.

Xamarin Forms

Launching an app from Xamarin Forms is easy, simply call OpenUri.

// You can remove the switch to UI Thread if you are already in the UI Thread.
Device.BeginInvokeOnMainThread(() =>
{
    Xamarin.Forms.Device.OpenUri(new Uri("skype://555-1111"));
});

While there are some caveats to iOS, which I will go through shortly, this is generally all that is needed. However, it lacks certain functionality, such as notifying you if any app did take the request.

App Handling

To extend the functionality, lets create our own, OpenUri, called LaunchApp. First create an interface to call the new method.

public interface IAppHandler
{
    Task<bool> LaunchApp(string uri);
}

You will need to use Dependency Injection, to provide this functionality to your Xamarin Forms application. Now lets create each implemention on each platform. Also note, that these methods, should be called in the UI Thread. Use BeginInvokeOnMainThread, if you are on a different thread.

iOS

First, we will implement LaunchApp for iOS.

public Task<bool> LaunchApp(string uri)
{
    var canOpen = UIApplication.SharedApplication.CanOpenUrl(new NSUrl(uri));

    if (!canOpen)
        return Task.FromResult(false);

    return Task.FromResult(UIApplication.SharedApplication.OpenUrl(new NSUrl(uri)));
}

Due to increased security requirements in iOS9, if you want to know if an app was launched you need to specify which apps you may launch from your app, in the info.plist. If you don’t the app will still open, but it will always return false, when indicating if it did open. This security requirement was added because some apps were using this functionality to determine what other apps you had installed. In your info.plist add all the Uri Schemes, you may use. Some exceptions to this rule are default apps, such as the browser, or making a call. Functions that every device has.

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>skype</string>
    <string>sip</string>
</array>

Android

For Android, we implement the following.

public Task<bool> LaunchApp(string uri)
{
    bool result = false;

    try
    {
        var aUri = Android.Net.Uri.Parse(uri.ToString());
        var intent = new Intent(Intent.ActionView, aUri);
        Xamarin.Forms.Forms.Context.StartActivity(intent);
        result = true;
    }
    catch (ActivityNotFoundException)
    {
        result = false;
    }

    return Task.FromResult(result);
}

UWP

And, for UWP, we implement this.

public async Task<bool> LaunchApp(string uri)
{
    return await Windows.System.Launcher.LaunchUriAsync(new Uri(uri));
}

Posted

in

,

by

Tags: