Skip to main content
Access the user’s GPS coordinates to build location-aware apps on MentraOS using the LocationManager.

Quick Start

Subscribe to Location Stream

Get continuous location updates as the user moves:
protected async onSession(session: AppSession, sessionId: string, userId: string) {
  // Subscribe to continuous location updates
  const unsubscribe = session.location.subscribeToStream(
    { accuracy: "standard" },
    (data) => {
      const { latitude, longitude, accuracy } = data;
      
      session.logger.info(`Location: ${latitude}, ${longitude}, accuracy: ${accuracy}m`);
    }
  );
  
  // Cleanup when done
  // unsubscribe();
}

Get Latest Location (One-Time Poll)

Request a single location fix without subscribing to a stream:
protected async onSession(session: AppSession, sessionId: string, userId: string) {
  try {
    const location = await session.location.getLatestLocation({
      accuracy: "high"
    });
    
    session.logger.info(`Got location: ${location.latitude}, ${location.longitude}`);
  } catch (error) {
    session.logger.error("Failed to get location:", error);
  }
}

LocationManager API

The SDK provides session.location with three main methods:
MethodParametersReturnsDescription
subscribeToStream(options, handler){ accuracy: string }, (data: LocationUpdate) => void() => void (cleanup function)Subscribe to continuous location updates
unsubscribeFromStream()NonevoidUnsubscribe from the location stream
getLatestLocation(options){ accuracy: string }Promise<LocationUpdate>One-time location poll (15 second timeout)

Accuracy Tiers

Choose the accuracy tier based on your app’s needs. Higher accuracy tiers provide more precise location data but drain more battery.
Accuracy TierDescriptionUpdate FrequencyBattery ImpactUse Case
"realtime"Highest precision, fastest updatesVery HighHighNavigation, real-time tracking
"high"High precision GPSHighMedium-HighPrecise location features
"tenMeters"~10m accuracyMediumMediumLocal place detection
"standard"Default accuracy (balanced)MediumLow-MediumGeneral location features
"hundredMeters"~100m accuracyLowLowCity-level features
"kilometer"~1km accuracyVery LowVery LowRegional features
"threeKilometers"~3km accuracyVery LowVery LowWide-area features
"reduced"Battery-saving modeMinimalMinimalBackground location
Example:
// High accuracy for precise features
session.location.subscribeToStream(
  { accuracy: "high" },
  handler
);

// Lower accuracy for battery efficiency
session.location.subscribeToStream(
  { accuracy: "hundredMeters" },
  handler
);

LocationUpdate Data Structure

The LocationUpdate interface contains location data:
FieldTypeRequiredDescription
latitudenumberLatitude in decimal degrees
longitudenumberLongitude in decimal degrees
accuracynumberAccuracy in meters
altitudenumberElevation in meters above sea level
timestampDateWhen the location was captured
correlationIdstringUsed for tracking poll requests
TypeScript Interface:
interface LocationUpdate {
  latitude: number;
  longitude: number;
  accuracy: number;
  altitude?: number;
  timestamp: Date;
  correlationId?: string;
}

Usage Examples

Display Location on Dashboard

protected async onSession(session: AppSession, sessionId: string, userId: string) {
  session.location.subscribeToStream(
    { accuracy: "standard" },
    (data) => {
      session.dashboard.content.writeToMain(
        `Lat: ${data.latitude.toFixed(4)}\n` +
        `Lon: ${data.longitude.toFixed(4)}\n` +
        `Accuracy: ${data.accuracy}m`
      );
    }
  );
}

Show Location on Voice Command

protected async onToolCall(toolCall: ToolCall): Promise<string | undefined> {
  if (toolCall.toolId === "show_location") {
    const session = this.getSessionByUserId(toolCall.userId);
    
    try {
      const location = await session.location.getLatestLocation({
        accuracy: "high"
      });
      
      return `Your current location is ${location.latitude.toFixed(4)}, ${location.longitude.toFixed(4)} with ${location.accuracy}m accuracy`;
    } catch (error) {
      return "Could not get your current location";
    }
  }
}

Cleanup Subscriptions

protected async onSession(session: AppSession, sessionId: string, userId: string) {
  const unsubscribe = session.location.subscribeToStream(
    { accuracy: "standard" },
    (data) => {
      // Handle location updates
    }
  );
  
  // Clean up when session ends
  session.events.on('disconnect', () => {
    unsubscribe();
  });
}

Permissions

Location access requires the location permission in your app manifest. Configure this in the Developer Console at console.mentra.glass.
Users must grant location permission for your app to access GPS data. Always handle cases where location data is unavailable.

Best Practices

Choose appropriate accuracy:
// Good - Use lowest accuracy needed
session.location.subscribeToStream(
  { accuracy: "hundredMeters" }, // Fine for city-level features
  handler
);

// Avoid - Don't use highest accuracy unless needed
session.location.subscribeToStream(
  { accuracy: "realtime" }, // Drains battery quickly
  handler
);
Always unsubscribe when done:
protected async onSession(session: AppSession, sessionId: string, userId: string) {
  const unsubscribe = session.location.subscribeToStream(
    { accuracy: "standard" },
    handler
  );
  
  // Important: Clean up to stop location updates
  session.events.on('disconnect', () => {
    unsubscribe();
  });
}
Handle poll timeouts:
try {
  const location = await session.location.getLatestLocation({ accuracy: "high" });
  // Use location
} catch (error) {
  // Handle timeout (after 15 seconds)
  session.logger.error("Location poll timed out");
}
Check accuracy in handler:
session.location.subscribeToStream(
  { accuracy: "standard" },
  (data) => {
    if (data.accuracy > 100) {
      session.logger.warn(`Low accuracy: ${data.accuracy}m`);
    }
    
    // Use location data
  }
);

Error Handling

Handling Stream Errors

protected async onSession(session: AppSession, sessionId: string, userId: string) {
  try {
    const unsubscribe = session.location.subscribeToStream(
      { accuracy: "standard" },
      (data) => {
        if (data.accuracy > 100) {
          session.logger.warn(`Low accuracy: ${data.accuracy}m`);
        }
      }
    );
  } catch (error) {
    session.logger.error("Failed to subscribe to location stream:", error);
  }
}

Handling Poll Timeouts

try {
  const location = await session.location.getLatestLocation({ accuracy: "high" });
  session.logger.info(`Location: ${location.latitude}, ${location.longitude}`);
} catch (error) {
  session.logger.error("Location request failed:", error);
  // Provide fallback or notify user
}

Next Steps