Skip to main content

Locating

Locating your device is arguably the most important feature of FMD.

Unfortunately, this is notoriously messy: from Android being restrictive of userspace apps accessing the location in the background (to prevent tracking by abusive apps), to computing the location itself being non-trivial.

This page goes into more details about locating to help you understand it a bit better.

The locate command

fmd locate sends the coordinates of the phone.

The following options are available:

  • locate, locate all: Responds with both the OS-based and cell-based location
  • locate gps: Responds with an location resolved by the OS, usually GPS/GNSS
  • locate cell: Responds with the cell-based location
  • locate last: Responds with the last known location known to FMD or to the Android operating system. This does not cause a cell or GPS lookup.

Location services need to be on

The first requirement for locating to work is that location services are enabled in the system settings of your device. Otherwise the Android system does not allow apps to make any location-related calls.

If you grant FMD the WRITE_SECURE_SETTINGS permission, FMD can turn location services on temporarily, and later turn them off again.

How can locations be computed?

A computer program cannot magically guess your location. The program needs to take some inputs, do some computation, and eventually produces an output. Ideally, this output are the coordinates of your device, possibly alongside a measure of perceived accuracy.

But what inputs does the algorithm take? What is this algorithm? Who writes and maintains this algorithm?

Inputs: Locating is inherently physical. Common inputs are: GNSS (GPS) signals, neighbouring cell towers, Wi-Fi networks, and Bluetooth beacons.

Algorithm: Designing an algorithm to compute the location from the input signals is a science in itself. You need to take into account things like signal strength, angles, etc.

info

We believe that the best place to solve the locating problem is the operating system.

It does not make sense for every app to re-implement this complex logic. This needs to be implemented once, in a central place, for apps to query.

GNSS/GPS-based

GNSS signals are relatively weak, and the satellites are not geo-stationary.

For this reason, GNSS works best if you are outdoors without any clouds. If you are indoors, away from any window, or in a tunnel, GNSS is not going to get a fix.

Even under good conditions, getting a GNSS fix can take time in the order of minutes. Assisted GNSS (A-GNSS) can speed this up, but it needs to be supported by your CustomROM. A-GNSS also comes with its own privacy challenges.

When you are in a new location, it can take long (in the order of minutes to tens of minutes) to get a fix (even with A-GNSS, depending on the situation). Afterwards, subsequent location requests in the same area, even if they are hours or days later, are able to obtain a GNSS fix much faster (in the order of seconds to minutes).

Such is the nature of GNSS. Unfortunately, this makes testing things reproducibly very cumbersome.

You can use GPSTest to easily see if your device can get a GNSS fix.

Cell-based

FMD can use the OpenCelliD database to map cell towers to locations. The database consists of a list of cell towers and their known location (which is crowd-sourced). FMD sends the current cell tower ID to OpenCelliD, which returns the location.

This has inherent problems:

  1. It's imprecise. Cell towers can cover large areas.
  2. It's incomplete. Not all cell towers are contained in the database. You can use Tower Collector to contribute data.
  3. It's a privacy issue, since OpenCelliD learns your lookup. This issue tracks the possibility of downloading the database for offline use.

Still, it's better than no location.

"Cell not found" means that your device seems to be connected to a cell that is not listed in OpenCelliD.

FMD always exposes you the cell parameters "MCC, MNC, LAC, CID" (Wikipedia). With these parameters, FMD queries the database. If the database returns no response ("Cell not found"), you can use these parameters for debugging. You can manually query OpenCelliD with these parameters.

When you have two phones with FMD and one gets a cell location and the other one does not, you can try comparing the cell ID. Are they connected to the same tower? Different mobile carriers will use different cell towers (unless they are reselling/piggybacking on another carrier's infra). And even within the same carrier, two phones in the same location could connect to different cell towers, because tower coverage can overlap.

If the cell tower is not in the database, there is nothing that FMD can do about it.

Wi-Fi based

Wi-Fi based location is similar to cell-based location. A database of Wi-Fi network SSIDs and their known, crowd-sourced locations is used to look up the Wi-Fi networks that are in range of the device.

In practice, Wi-Fi based location it is much faster than GNSS, and much more precise than OpenCelliD. It is usually "good enough". Many operating systems use the Wi-Fi based approach, such as Apple iOS and Android with Play Services.

FMD does not currently implement Wi-Fi based locating itself.

Network location on GrapheneOS

On GrapheneOS, the operating system implements network location. As of May 2025 it uses Apple's Wi-Fi database, and may be extended to with a cell-based approach.

We recommend enabling it. You can find this setting under "Location -> Location Services -> Network location".

Note that this requires either Wi-Fi or Wi-Fi scanning to be enabled.

info

This is how it should be: the OS should implement a reliable location service in a central place.

Screenshot of the network location settings in GrapheneOS

Note that this is different to fmd locate cell, which is the FMD app doing a lookup to OpenCelliD.

Instead, GrapheneOS's network location works on an operating system level, complementing GNSS. When you run fmd locate gps, FMD asks the OS "please give me the device location". The operating system can implement multiple ways on how to resolve that request. Network location on GrapheneOS is one such way.

From the perspective of FMD, the command is still fmd locate gps. If the answer comes from GrapheneOS's network location service, the response will be labelled as "network" instead of as "gps".

What FMD does

  • locate gps: This relays the location query to the OS and simply waits for the OS to give FMD a response.
  • locate cell: This uses FMD's built-in code to query OpenCelliD. It is a simple lookup, no complex transformation.
warning

For historical reasons, the option is called "gps", even though "os" would be a better fit.

FMD also returns a location source. For example, this can be "OpenCelliD", "gps", "network", or "last known location".

FMD currently has no way to to request a certain level of location accuracy, nor does it return the accuracy of a location. Both are planned.