Attention! This is a very old post from 2016! It's kept for archival reasons!
We hope you enjoy this piece of content which now became a part of history. You can claim a 10% discount as a new customer by mentioning the IFOUNDAHISTORICALITEM promo code since you found this hidden gem.
Just imagine how great it could be if your mobile applications were aware of physical things nearby — personal stuff, vending machines, your car or bicycle... But how one can achieve that?
Do we need to make all those things "smart" and put an OS inside to make them a part of the Internet of Things? What if I told you there is an amazing technology that can bring online even your old sneakers just by attaching a small sticker to them? Continue reading to learn more about that technology.
This blog post contains information on approaches we used to build a PoC for the Reality Hack event held on the Tauron Arena Krakow and challenges we faced. The event was supported by the world's leading beacon devices manufacturer — Estimote.
During the hackathon (starting at 9:00 AM and finishing and 4:00 PM) participants were developing mobile applications that used the power of iBeacon/Eddystone technologies and the Estimote SDK to solve problems in the following categories:
While there was not much time (less than 6 hours if you take into account breaks to eat something), organizers ensured all the required infrastructure of beacons were set up around the Tauron Arena and provided each team with information about mapping between some particular beacon and it's exact location. So in the morning everything was ready to start hacking.
Our team consisted of two members: Dmitriy Ulanovich(FB, LinkedIn) and me — Volodymyr Rudyi(Twitter, LinkedIn).
After we carefully analyzed suggested project categories, we decided to develop something that would make the show or event not just fun, but also safe and family-friendly.
According to public data, almost 90% of all families experience losing a child in a public space. Just think about this figure. Have you ever got lost a child? I'm 90% sure about your answer.
So we thought: what if someone or something could notify us about the risk of losing a child before it happens? What if someone could tell the exact location of the child in a case if they got lost?
We made several assumptions about the solution:
Then this came to our minds:
In the end, the proposed solution would consist of:
To implement everything, we used a set of technologies and frameworks that we thought were the most suitable for the task being solved.
Because of the strict time limit, our main concern was overhead of setting up all the required infrastructure for the back-end.
We didn't want to spend time on the traditional monolithic architecture and decided to go with something really lightweight and flexible. So we used AWS Lambda to host all backend code and AWS API Gateway to map requests to corresponding AWS Lambda functions.
Since there were no complex relations between our models, key-value storage was ideal persistence solution and we chose AWS DynamoDB.
Finally, we needed something to send out SMS and push notifications. The first thought was to use the GCM(Google Clooud Messaging) directly, but since we wanted to be able to send out both SMS and GCM messages using the same code, we used AWS Simple Notifications Service to deliver SMS and push notifications to devices.
Final architecture looks like this:
So, basically, backend was completely implemented using tools, provided by the AWS. It's serverless, infinitely scalable and very easy to support.
To expose the API on the human-readable URL, API Gateway custom domains were used. Such setup requires a valid SSL certificate. The Letsencrypt service was used to obtain a certificate. Since we needed it for the API Gateway endpoint, we needed somehow to confirm that domain belongs to us. It requires to run a simple webserver on the domain that will serve the generated validation string that can be read by the Letsencrypt service.
Since we didn't want to setup a separate EC2 instance on that domain to perform a validation, we used the following approach:
It may look bit difficult, but it takes only 5 minutes to setup and doesn't require any EC2 instances
To develop applications for parents and for the wearable, we used Android Studio and the Android SDK version 23. Applications were pretty simple(all the magic happened inside the Estimote SDK) and reported their location to the backend. The login screen of the application for parrents looked like this(we called it as "Careable" because it used a combination of "nearable" and wearable devices under the hood):
To use the application parents should enter their name, email(not required, but can be used for notifications) and the "careable code". This code is the four-digit number that is automatically generated once the bracelet/watch is attached to child's hand.
Initially, we selected the Android SDK version 23 and developed the application for parents using it. But then we realized our device that was simulating a wearable has Android 5 and it means we can use API versions up to 19-th. Since both applications shared a code base, we had to port some code from API version 23 to API version 19. Significant difference was for the BLE API, since it changed a lot in 23-rd (we had some code working with Beacons written without the SDK, luckily Estimote SDK provides a good abstraction on a top of the Android API)
The actual magic happened under the hood of the Estimote SDK for Android. It allowed us to focus on the application logic development itself, instead of dealing with different API for reading BLE devices data.
Since beacons are frequently used for indoor navigation, Estimote SDK provides an easy way to search for beacons nearby and to range them according to the signal strength. Here is a snippet we used to search for the nearest device:
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
@Override
public void onBeaconsDiscovered(Region region, List<Beacon> list) {
if (!list.isEmpty()){
final Beacon beacon = list.iterator().next();
// To reliably determine the unique identifier of the location
// beacon attached to, we used a combination of three IDs:
// UUID, major and minor.
final String locationid = String.format("%s-%s-%s",
beacon.getMajor(), beacon.getMinor(), beacon.getProximityUUID());
Log.d(TAG, "Discovered beacon:" + locationid);
// Application-specific logic
new LocationReportTask().execute(locationid);
}
}
});
As you can see, the code is pretty simple, doesn't require any Android-specific API to be used, meaning the SDK can be used for any Android device starting from the Android 4.3 without any change.
As you probably know, in Android 6.0 a more flexible permissions system was introduced and declaring list of permissions in the manifest is not enough anymore. Instead of it, user should explicitly confirm they agree the application to use some specific feature, e.g. location. Here is an example of the code that performs all required requests:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(
Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage(
"Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
ActivityCompat.requestPermissions(TrackActivity.this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
It's a responsibility of the application to display all the required messages and dialogs and luckily the Estimote SDK has a set of tools, that can help developers to avoid writing a boilerplate code. Here is a code written with a help of the Estimote SDK:
SystemRequirementsChecker.checkWithDefaultDialogs(this);
As you can see, the second version is way shorter.
Another interesting thing about the SDK: initially we thought scanning will be too slow, since it involves working with the Bluetooth subsystem which can be rather slow. Once we started testing applications surrounded by dozens of beacons, we realized default settings for scanning result in too many discovery events, so you should take it into account and adjust scanning settings according to your needs.
It was a very interesting event. The Estimote team and TAURON Arena Krakow hosted an amazing hackathon in a unique place that is ideal for testing the beacons technology.
Obviously, six hours is not much time, but it's enough to showcase a very big potential of technologies involved and how they can help to solve problems efficiently.