An Introduction to FLAMINGO & the FLAMINGO Software Development Kit for Android and IoT Devices

On a typical smartphone device, the location accuracies that can be achieved are rarely better than a few meters. Imagine the applications that could be enabled with decimetre accuracy. Pedestrian path navigation for the visually impaired, laneway positioning for car mobility, immersive augmented reality experiences using accurate geolocation data. FLAMINGO will enable these apps in Android smartphones and IoT devices.

FLAMINGO is a new API library for Android and IoT developers. The API is designed for the conventional developer and leaves the accurate location servicing to the positioning experts. FLAMINGO will use specially supporting server and deployed infrastructure in smart cities to enable better location precision and accuracy than the existing Android location service.

Please note that the FLAMINGO SDK is coming soon and is therefore not currently available for use. 

Tested Devices

FLAMINGO will only work on Android 7+ smartphone devices. The service is designed to work on all supported devices, which are listed here, but the following list of smartphones are confirmed to work with FLAMINGO.


Android Version

Code Signal

Carrier Signal

Dual Frequency

Supported Systems

Huawei P10 7.0 Yes Yes No GPS



Samsung S8 with Exynos chipset 7.0 Yes Yes No GPS



Xiaomi Mi 8 8.1 Yes Yes Yes GPS



Targeted Applications

FLAMINGO targets new applications in the location service market. To assist with optimising the best solution for you, an application type must be specified as part of FLAMINGO registration.

Application Type


Fitness For applications targeted at the athlete. The application will typically have the location device moving erratically and following some designated path.
Tracking For applications targeted at monitoring. Movements are unknown and typically the application will be operating in the background.
Vehicle Navigation For applications targeted at vehicle-based positioning. The device will generally be moving, typically at faster speeds, and controlled device motions.
Pedestrian Navigation For applications targeted at pedestrian-based positioning. The device will generally be moving, typically at slower speeds, and slightly controlled device motions.
Augmented Reality For applications targeted at augmented reality. The device will generally be static or only slowly moving, with random device motions.
Surveying For applications targeted at the surveyor. The device will be held static with no or very little movement.

Registering for FLAMINGO

When an application developer registers for FLAMINGO, they will be provided with a company ID code. This code will be used by the SDK to access FLAMINGO services. The user will also need to declare the application being developed. For each application, an application ID and password will be allocated, which will also need to be used by the SDK.

These identification codes will provide specialised access to the FLAMINGO server, which supports secure positioning operations. The allocation of codes will ensure all positions calculated are anonymous and only known by the user. FLAMINGO will not share the positions calculated to third-parties.


The following examples are used to illustrate how FLAMINGO will interface to your device. Extended sample code will be provided through GitHub soon.


Using FLAMINGO location is nearly identical to the conventional Android Location API. Using the following sequence of functions in your Android application, you can activate FLAMINGO location services. The below code demonstrates the simple calls needed to register for and use FLAMINGO location services:

public class MainActivity {

FlamingoManager  mFlamingoManager = new FlamingoManager(new ArrayList());

mFlamingoManager.registerFlamingoService(applicationId, password, companyId,  context, mFlamingoCallback); …


It is necessary to create a FLAMINGO callback class for your application. This will be called whenever a FLAMINGO-enabled location has been returned. Here is some sample code on how to enable your location callback:

public class FlamingoCallback implements FlamingoLocationCallback {


public void onFlamingoLocationReceived (FlamingoLocation flamingoLocation) {
this.longitude = flamingoLocation.getLongitude();

this.latitude = flamingoLocation.getLatitude();




The IoT version of FLAMINGO requires only a bit of complexity due to the varying nature of Global Navigation Satellite System (GNSS) receivers in use. FLAMINGO requires the developer to create a structure containing all necessary parameters for FLAMINGO positioning. This sample code considers the use case of a surveying application. The user simply registers for the FLAMINGO service:

applicationcontext_t applicationcontext = APPLICATION_CONTEXT_SURVEYING;

char *pchApplicationId = “fSF^&FS*(FHfd”;

char *pchInstallationId = “HFUJSHYAFI*yVLODH:ASV”;

char *pchnmeaGns =”$GNGNS,014035.00,4332.69262,S,17235.48549, E,RR,13,0.9,25.63,11.24,,*70″;

registerFlamingoService(applicationContext, pchApplicationId,

pchInstallationId, pchNmeaGns, &callback);

When a user registers for FLAMINGO, they will be given an application ID and installation ID. These will be provided to API when the registerFlamingoService method is called. FLAMINGO is also dependent on the application context, which defines the type of application being targeted. The application contexts are listed above and describe the applications FLAMINGO will deliver on.

To send GNSS measurements from the API, the raw data must be processed and allocated to the observation_t and observation_t structures (located here). An allocation for a single GPS satellite observation is given:

#include flamingo.h

double  l1freq = 1575420000;

double  l2freq = 1227600000;

const double time[6] = {2019, 2, 15, 10, 35, 58};

gtime_t gt = epoch2time(time);

observationd_t   observation_gps1;

observation_gps1.svid = 5;

observation_gps1.fcn = 0;

observation_gps1.constellation = CONSTELLATION_GPS;

observation_gps1.code[0] = CODE_GPS_L1C;

observation_gps1.code[1] = CODE_GPS_L2W;

observation_gps1.ncodes = 2;

observation_gps1.pseudorange[0] = 20746334.853;

observation_gps1.pseudorange[1] = 20746339.867;

observation_gps1.doppler[0] = -1501.796;

observation_gps1.doppler[1] = -1501.796*l2freq/l1freq;

observation_gps1.carrier[0] = 109022241.172;

observation_gps1.carrier[1] = 84952394.739;

observation_gps1.snr[0] = 50.25;

observation_gps1.snr[1] = 44.25;

observation_gps1.lockIndicator[0] = 0;

observation_gps1.lockIndicator[1] = 0;

observation_t   observations;

observations.epochTime.time = gt.time;

observations.epochTime.sec = gt.sec;

observations.nsat = 1;

observations.observationData = malloc(sizeof(observationd_t)*observations.nsat) ;

observations.observationData[0] = observation_gps1;

When the observation class is ready, it is sent to the server by:


The FLAMINGO operations can be stopped by simply calling:


The return of location will be provided by a server tool and web API. More details of this server and web API will be provided soon.

Get In Touch

Please provide your details here to get in touch and learn more about the FLAMINGO platform.