Skip to content

Using the Windows URI Scheme

TMM registers a custom URI scheme, trimblemobilemanager, with the Windows operating system, which allows other applications to:

  • Launch TMM.
  • Show TMM UI.
  • Use TMM workflows, and get workflow results.
  • Query information from TMM.

Some TMM requests pass a response back to your application, using your application’s custom URI scheme.

  1. Configure your application to Handle URI activation.
  2. For any TMM request that requires a callback, pass a URI that uses your custom URI scheme. Example:
    trimblemobilemanager://{request}?callback=my-custom-scheme%3A%2F%2Fhandle-tmm-response
  3. TMM will then format the response to your request using callback. Example:
    my-custom-scheme://handle-tmm-response?param1=value%201&param2=value%202

TMM registers a custom URI scheme with Windows for handling requests from client applications. The calling application supplies a callback URI, which TMM will launch when it has finished processing the request.

Use the tmmRegister request to register your client application with TMM to use TMM API.

First, register your own custom URI scheme with Windows so that you can receive the response from TMM. Do this by adding a windows.protocol extension to your Application in Package.appxmanifest file.

<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<Extensions>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="myapp">
<uap:DisplayName>My TMM Client App</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
</Application>

Use the Windows URI launcher to send the tmmRegister request. Windows will route the URI to an instance of TMM.

public async Task RegisterWithTMMAsync()
{
// Your Application ID GUID, assigned by Trimble
string applicationId = "your_app_id_guid_here";
// A callback URI that TMM will invoke to send the response
// back to your application.
string callbackUri = Uri.EscapeDataString("myapp://response/tmmRegister");
// Format the URI request
string requestString = $"trimbleMobileManager://request/tmmRegister?applicationId={applicationId}&callback={callbackUri}";
Uri requestUri = new Uri(requestString);
// Launch the URI
if (await Launcher.Default.CanOpenAsync(requestUri))
{
bool result = await Launcher.Default.OpenAsync(requestUri);
}
}

To get a response back from the TMM request URI scheme, you must register your own app’s URI scheme, and then handle the incoming URI from your app. Below we show how to do this in a .NET MAUI Windows app, but the procedure is similar for any Windows app.

public partial class App : MauiWinUIApplication
{
public App()
{
InitializeComponent();
// Windows will launch a new instance of TMM with every URI activation. We only want the
// 'main' instance to handle the URI activation.
var mainInstance = AppInstance.FindOrRegisterForKey("a unique identifier for my app");
if (mainInstance.IsCurrent)
{
// This is the 'main' instance handle the URI
AppInstance.GetCurrent().Activated += OnActivated;
var args = AppInstance.GetCurrent().GetActivatedEventArgs();
HandleProtocolActivation(args);
}
else
{
// This is not the 'main' instance. Redirect the URI to the 'main'
// instance, end kill this instance.
await mainInstance.RedirectActivationToAsync(AppInstance.GetCurrent().GetActivatedEventArgs());
Process.GetCurrentProcess().Kill();
}
}
private void OnActivated(object sender, AppActivationArguments args)
{
HandleProtocolActivation(args);
}
private void HandleProtocolActivation(AppActivationArguments args)
{
if (args.Kind == ExtendedActivationKind.Protocol && args.Data is ProtocolActivatedEventArgs protocolArgs)
{
Uri uri = protocolArgs.Uri;
if (uri.AbsolutePath.StartsWith("myapp://response/tmmRegister"))
{
// this is the callbackUri you sent to TMM earlier
NameValueCollection queryDictionary = HttpUtility.ParseQueryString(uri.Query);
string id = queryDictionary["id"]; // "tmmRegister"
string status = queryDictionary["status"]; // “success” or “error”
string message = queryDictionary["message "]; // Additional information
string registrationResult = queryDictionary["registrationResult"]; // “OK”, “NoNetwork”, or “Unauthorized”
int.TryParse(queryDictionary["apiPort"], out var apiPort); // The REST API is at $"WS://localhost:{apiPort}"
}
}
}
}