This tutorial will take you through building a realtime pizza delivery tracking system for both Android and the web. At the end of this tutorial, we'll have a web interface where we can view our pizza deliveries in realtime and an Android application to provide these updates. We won't be covering Android specifics here or initialising our map in the browser, so take a look at our GitHub repository for this project and dive into the code.
Create a free account and get your API key
Realtime updates via Android application
The first thing we'll do is create the Android side of the application to provide the realtime updates. We'll be creating a new Android application with a LoginActivity
template, you can find more information on this here. We can then include the Java client SDK in our build.gradle
file as follows.
compile 'io.deepstream:deepstream.io-client-java:2.0.4'
With the Java SDK, there are a few different ways of instantiating the client. Because the same client will need to be passed between activities, we'll be using the DeepstreamFactory
. Instantiating a client with this is as simple as:
DeepstreamFactory deepstreamFactory = DeepstreamFactory.getInstance();
DeepstreamClient client = deepstreamFactory.getClient("<Your app url>");
Using the UserLoginTask
already included in the LoginActivity
, we can login the user using the details they provide. You'll need to ensure that email auth has been enabled and that any user trying to login has been added to the application.
LoginResult result;
DeepstreamClient client;
try {
client = deepstreamFactory.getClient("<Your app url>");
} catch (URISyntaxException e) {
return false;
}
JsonObject authData = new JsonObject();
authData.addProperty("type", "email");
authData.addProperty("email", mEmail);
authData.addProperty("password", mPassword);
LoginResult result = client.login(authData);
return result.loggedIn();
From here we just proceed to our TrackingActivity
via an intent.
Once in the new activity, we can get a reference to our client via DeepstreamFactory.getClient()
. This will get the last created client from the factory.
Next we need to get the list of users in our pizza tracker app and, if they're not already there, add the user.
List users = client.record.getList( "pizza-tracker/users" );
if( !Arrays.asList( users.getEntries() ).contains( state.getEmail() )) {
users.addEntry( state.getEmail() );
}
The last thing we need to do from the Android side is create a LocationManager
that updates our Record
with the current coordinates when we move. To initialise our location record we just call client.record.getRecord
as follows. We pass in the email we logged in with, so that the Record
name corresponds with our entry in the List
.
Record locationRecord = client.record.getRecord(mEmail);
Our LocationListener
just looks as follows, updating the Record
whenever our location changes:
private final LocationListener locationListenerGPS = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
double longitudeNetwork = location.getLongitude();
double latitudeNetwork = location.getLatitude();
JsonObject coords = new JsonObject();
coords.addProperty( "lat", latitudeNetwork );
coords.addProperty( "lng", longitudeNetwork );
coords.addProperty( "online", true );
locationRecord.set( coords );
};
which we then pass into a LocationManager
and request updates.
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 2 * 60 * 1000, 10, locationListenerGPS
);
Receive updates via JavaScript
Now that we have an Android application providing location updates on our pizza deliveries, we need a web interface to display these on.
Similar to the Android side of things, we need to login with our deepstreamHub client and then get the list of pizza deliverers.
client = deepstream('Your app URL')
client.login({}, function(success) {
var list = client.record.getList('pizza-tracker/users')
list.whenReady(renderList)
});
Our renderList
function just loops through every entry in the list and adds them to our map. It also subscribes to the List
events entry-added
and entry-removed
.
function renderList(list) {
list.getEntries().forEach(addDeliveryTracking)
list.on('entry-added', addDeliveryTracking)
list.on('entry-removed', removeDeliveryTracking)
}
The meat and potatoes of our front end is in the addDeliveryTracking
method. First we need to create a marker for our map.
var record = client.record.getRecord(trackingId)
var marker = new google.maps.Marker({
map: map,
title: `Location of delivery person: ${trackingId}`,
icon: pizzaIcon
})
Then we need to set the location of our marker to the position that the Record
provides us.
record.whenReady((record) => {
marker.setPosition(record.get())
})
and subscribe to updates, updating the marker on each update.
record.subscribe(function(data) {
marker.setPosition(data);
})
After all this, we should have an application that looks as follows:
Thanks for staying with us, to get a deeper look into deepstreamHub, take a look at our other example apps or our various integrations.