-
-
Notifications
You must be signed in to change notification settings - Fork 82.1k
Android node: support location.enabledMode: always (background location via foreground service) #68581
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivityMarked as stale due to inactivity
Description
Activity
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.ClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.ClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.ClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.ClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.Security boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivityMarked as stale due to inactivity
Type
Fields
Priority
None yet
Summary
On the Android node app,
nodes location getcurrently only works when the OpenClaw app is in the foreground. Any background call fails withLOCATION_BACKGROUND_UNAVAILABLE. The Location Command docs already speclocation.enabledMode: alwaysand describe the intended Android behavior under a "Background behavior (future)" heading, but the Android app only exposesOff / While Usingin Settings today.This issue is a request to ship that future behavior: let users opt into Always mode on Android, backed by a foreground service, so an agent can fetch location on a schedule (cron, heartbeat, activity tracker, etc.) without having to keep the app visible.
Motivation / real use case
I'm running a 30-minute activity-tracker cron on my Gateway that logs where I am + what I'm doing. Today:
openclaw nodes location get --node "Jeremie's MacBook Air"returns GPS fine. ✅LOCATION_BACKGROUND_UNAVAILABLEunless I manually foreground the app. ❌So when I'm out of the house with only my phone, the tracker falls back to heuristics (agenda, last known location) instead of real GPS. Across a user base this is a common pattern — any scheduled agent that wants mobile location will hit this.
Current state (as of 2026.4.15)
CLI side (works):
Returns a clean payload with
lat,lon,accuracyMeters,isPrecise,timestamp. Error codes are already stable (LOCATION_DISABLED,LOCATION_PERMISSION_REQUIRED,LOCATION_BACKGROUND_UNAVAILABLE,LOCATION_TIMEOUT,LOCATION_UNAVAILABLE).Android app side (partial):
Off / While Usingonly (noAlways).location.getwhile backgrounded returnsLOCATION_BACKGROUND_UNAVAILABLE.Proposed change
Ship the "Background behavior (future)" section from the current spec:
Alwaysto the Android Settings selector, with the same tri-state UX already documented for iOS/macOS:Off / While Using / Always.ACCESS_BACKGROUND_LOCATIONwhen user picksAlways. Android 11+ sends the user into system Settings for that grant — follow that flow and gracefully revert towhileUsingif denied, as the spec prescribes ("If OS denies requested level, revert to the highest granted level and show status").Alwaysis active, declared withforegroundServiceType="location"(required on Android 14+). Show a small persistent notification while the service is active — Android requires visibility anyway.location.getinvoke while backgrounded, if mode isalways+ grant is present → start a short-lived location request via that service, return the fix, stop. No need for continuous tracking: episodic wake-and-fix is enough for the scheduled-cron use case.LOCATION_BACKGROUND_UNAVAILABLEwhen mode isalwaysand background grant is present. (Keep the code, because it still applies when mode iswhileUsing+ backgrounded.)Manifest bits (sketch)
If the app doesn't already declare them (can't easily check from outside):
Where this likely lives in the codebase
Based on the OpenClaw-Book TOC, the Android node app is under:
apps/android/(Kotlin) in theopenclaw/openclawmonorepo, or a sibling repo if split.Files worth touching (names inferred from Android conventions + existing capabilities):
AndroidManifest.xml→ permissions + service declaration above.location.getRPC from the Gateway (look for the stringLOCATION_BACKGROUND_UNAVAILABLE— there should be exactly one emitter).location.enabledModeis stored (currentlyoff | whileUsing).LocationForegroundServiceclass handling start/stop + single-shot fix viaFusedLocationProviderClient.getCurrentLocation(...).If the
LOCATION_BACKGROUND_UNAVAILABLEemitter is a singlewhenbranch gating onisAppForeground, the real fix is probably small: replace that branch with "if mode isalwaysand we have background permission, start the foreground service and fulfill the request; otherwise emit the existing error."Alternatives considered
Alwayspermission is the cleaner, user-visible path.whileUsing+ launching the app from ADB/automation: not a real-user solution.Privacy / UX considerations
Alwaysmust remain opt-in with an explicit OS-level prompt. The docs already propose the UX copy: "Allow background location. Requires system permission."Acceptance criteria
Off / While Using / Always.Alwaystriggers theACCESS_BACKGROUND_LOCATIONflow.Alwaysgranted,openclaw nodes location get --node <pixel>returns a valid fix while the app is backgrounded.whileUsinggranted and app backgrounded,LOCATION_BACKGROUND_UNAVAILABLEis still returned (existing behavior preserved).Context
Tested on:
location.enabledMode = whileUsing, precise enabled.openclaw nodes location get --node "Pixel de <name>" --json.Happy to test a pre-release build against my setup if useful.