Loading...
NO SDK NEEDED WORKS OFFLINE

Location Links

Show a place on DMD2's map or start navigation to it from your own Android app, with one standard VIEW intent — dmdloc:, geo: or google.navigation:.

Package (DMD2)
com.thorkracing.dmd2launcher
Package (DMD2 beta)
com.thorkracing.dmdplayground

Overview

DMD2 registers for three location URI schemes. Any app on the device can hand it a place with a plain Intent.ACTION_VIEW — no library, no permission, no account.

  • Show a pin — DMD2 comes to the front, centres the map on the point, drops a pin and opens the Location Info panel (the same panel a rider gets from a long press, with Navigate To, Save Location and Share). The rider decides what to do next.
  • Start navigation — DMD2 comes to the front and starts turn-by-turn guidance to the point, with no pin step in between.

The Three Schemes

URIWhat DMD2 doesName / label
dmdloc://41.1579,-8.6291
dmdloc:41.1579;-8.6291
Pin + Location InfoNo
geo:41.1579,-8.6291Pin + Location InfoNo
geo:0,0?q=41.1579,-8.6291(Ribeira)Pin + Location InfoYes — the text in brackets
google.navigation:q=41.1579,-8.6291Starts navigationNo
  • dmdloc: is DMD's own scheme. Only DMD2 handles it, so Android never shows a chooser of other map apps.
  • geo: is the standard Android place scheme (RFC 5870 plus Android's q= form). Other map apps also handle it, so set the package (see Targeting DMD2) if you want DMD2 specifically. RFC 5870 parameters such as ;u=35 and a zoom such as ?z=17 are accepted and ignored.
  • google.navigation: is the de-facto “guide me there” scheme. Extra parameters such as &mode=d are accepted and ignored; DMD2 routes with the rider's own route types.

Show a Pin

With a name (recommended when you have one):

// Kotlin
val name = Uri.encode("Ribeira")
val uri  = Uri.parse("geo:0,0?q=41.1579,-8.6291($name)")
startActivity(Intent(Intent.ACTION_VIEW, uri).setPackage("com.thorkracing.dmd2launcher"))

Coordinates only, DMD's own scheme:

// Java
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("dmdloc://41.1579,-8.6291"));
startActivity(i);
// Kotlin
val uri = Uri.parse("google.navigation:q=41.1579,-8.6291")
startActivity(Intent(Intent.ACTION_VIEW, uri).setPackage("com.thorkracing.dmd2launcher"))

What the rider sees:

  • DMD2 switches to the map and routes to the point, asking for a route type first if the rider's setup asks for one.
  • With no GPS fix yet, DMD2 shows “acquiring GPS” and starts as soon as it has one.
  • With navigation already running, DMD2 asks whether to start a new route or add the point to the current one.

Targeting DMD2

Without a package, Android shows a chooser when more than one app handles the URI (always the case for geo: and google.navigation:). To send straight to DMD2, set the package:

AppPackage
DMD2com.thorkracing.dmd2launcher
DMD2 betacom.thorkracing.dmdplayground

A rider may have either one, or both. Pick the one that is installed and fall back to a plain intent:

// Kotlin
fun openInDmd(context: Context, uri: Uri) {
    val packages = listOf("com.thorkracing.dmd2launcher", "com.thorkracing.dmdplayground")
    for (pkg in packages) {
        val intent = Intent(Intent.ACTION_VIEW, uri).setPackage(pkg)
        try {
            context.startActivity(intent)
            return
        } catch (e: ActivityNotFoundException) {
            // not installed: try the next one
        }
    }
    context.startActivity(Intent(Intent.ACTION_VIEW, uri))   // let Android choose
}

On Android 11 and newer, if you check for DMD2 with PackageManager before sending (rather than catching the exception as above), declare it in your manifest:

<queries>
    <package android:name="com.thorkracing.dmd2launcher" />
    <package android:name="com.thorkracing.dmdplayground" />
</queries>

From a service or another non-activity context, add Intent.FLAG_ACTIVITY_NEW_TASK. DMD2 runs as a single task, so the intent reaches the running map rather than opening a second copy.

Testing with adb

# pin, DMD's own scheme
adb shell am start -a android.intent.action.VIEW -d 'dmdloc://41.1579,-8.6291'

# pin with a name
adb shell am start -a android.intent.action.VIEW -p com.thorkracing.dmd2launcher \
    -d 'geo:0,0?q=41.1579,-8.6291(Ribeira)'

# start navigation
adb shell am start -a android.intent.action.VIEW -p com.thorkracing.dmd2launcher \
    -d 'google.navigation:q=41.1579,-8.6291'

For the beta app, use -p com.thorkracing.dmdplayground.

Rules & Limits

  • Coordinates: decimal degrees, a dot as the decimal separator, latitude then longitude. geo:0,0 on its own (no q=) is treated as “no place”.
  • Addresses are not supported. geo:0,0?q=Rua das Flores, Porto or google.navigation:q=<address> would need geocoding, and DMD2 will usually answer “No location found”. Geocode in your own app and send coordinates.
  • Names: only the geo: q=lat,lon(Name) form carries one. URL-encode it. dmdloc: and google.navigation: take coordinates only.
  • No result comes back. These are fire-and-forget; use startActivity, not startActivityForResult.
  • Plain text works too. Sharing text (ACTION_SEND, text/plain) that contains coordinates or a map link (Google Maps, Apple Maps, Waze, OpenStreetMap, OsmAnd…) also shows a pin — see Open With DMD. The URI schemes above are the reliable choice for apps.
Top