About
Trilateral is a reference app that demonstrates all features of the Flare API. It has several views that show different aspects of the current environment, the current zone, the device itself, and any thing that is near the device.
There is also a version for iOS.
Download
You can check out the Trilateral app souce code on GitHub as part of the Java sample code. You can also download a package to install on your device.
Build
You can open the sample code in Android Studio to build and run the app on a connected Android device. Make sure to read through the notes on the developing with Java page, as there are some dependencies you'll have to install.
Install
If you have downloaded the .apk package, you can use that to install the app on your mobile device. You can either run the following command from the command line: adb install Trilateral-release.apk Or download the .apk package from your mobile device directly.
Settings
To connect to the Flare server, you'll need enter the server address. Tap the three dots in the upper-right corner and choose Settings. Enter the server address and port number, and then tap the back button to return to the app.
There are also switches for controlling the hardware sensors:
- Use GPS: selects an environment whose geofence contains the device's current geographic location
- Use Beacons: determines the position of the device using nearby beacons and sends the position to the server
- Use CMX: receives the position of the device from the server
- Use Compass: determines the azimuth of the device and sends the angle to the server
Features
It has five tabs that show info about the device, a compass, a map, a list, and info about a nearby thing. You can change tabs using the tab bar at the top of the screen, or by swiping from side to side.
Trilateral has four tabs that show info about the device, a compass, a map, and info about a nearby thing. You can change tabs using the tab bar at the bottom of the screen.
Device
The device view shows the name and description of the current environment, the current zone, the device itself, and any nearby thing. It also shows the compass angle of the device.
Compass
The compass tab shows a ring with "fins" that indicate the direction towards things in the current zone, similar to the watch interface. The size of each fin indicates the relative distance, and a thicker fin indicates a nearby thing.
Map
The map tab shows a map of the current environment, including all zones and things, and the device itself. The dot for any nearby thing is highlighted.
List
The list tab shows a table with nearby things, sorted by distance from the device.
Thing
The thing tab shows information about a nearby thing, including its name and description and some data values. There are buttons that perform actions to change the color and brightness.
In Depth
Controller
A controller acts as a client to the Flare API, and manages the state of the Flare objects in the client app. In the model-view-controller (MVC) paradigm, it acts as the glue between the data model (on the server) and the views (each of the four tabs). In the Android app, the controller is the MainActivity class.
The controller defines an abstract superclass that each of the views can implement. It has variables for the current environment, current zone, device and nearby thing, as well as a function for notifying the view when the data has changed. The controller keeps a link to the current view, and when each view comes to the foreground it sets the view on the controller. When the current environment etc. changes, the controller updates the equivalent variable of the view.
Loading Data
The app has settings for server and port, as well as flags for whether to use certain sensors: GPS, beacons, and compass.
If GPS is turned on, when the app launches it gets the current location coordinates and searches for environments whose geofence contains those coordinates. If it finds one, it uses that environment. If it doesn't find one, or the GPS is turned off, then it will use the first environment found by default. (There is no environment picker because this is supposed to be automatic.)
After the environment is selected, the app tries to load the device object. First it checks if there is a saved device ID from the previous session. If so, it tries to load the device with that ID from the server. If there was no saved device ID, it was not found on the server, or the device with that ID is not in the current environment, then it creates a new device object on the server using default values. The name of the device is either the device's name or a name derived from the user's first name (e.g. "Andrew's iPhone"). The description contains the kind of device and the operating system version (e.g. "iPhone, iOS 9.2"). The mac data value is set to the MAC address of the device's Wi-Fi interface.
Once the device is loaded, the controller loads the current zone and the nearby thing (if any), based on the device's last known position. To get the current zone it searches zones in the environment using the API to filter by the device's position (although it could also look at the 'zone' value of the device object). To get the nearby thing it just looks at the 'nearest' value of the device object.
If beacons are turned on, when the beacons manager notifies the controller that the device position has changed, it sends the new device position to the Flare server.
If the compass is turned on, when a new compass heading is detected, it rounds the value to the nearest 5°. If the value has changed and it has been more than a second since the last time the value was reported, it updates the device's data.angle value on the server.
Changing Data
When the controller receives a position change notification from the server, it updates the position of the device and animates the change.
When the controller receives a data change notification for the angle, it updates the angle of the device and animates the change.
When the controller receives an enter/exit notification, it sets the current zone and updates the view.
When the controller receives a near/far notification, it sets the nearby thing and updates the view. It also subscribes to be notified of changes to the nearby thing.
When the controller receives a data change notification for the nearby thing, it updates the data and displays the change.
When the user changes a data value for the nearby thing, the new data value is sent to the server.
When the color is changed, the compass and map also update to show the new color.