Beacons on Android

Bluetooth is one of the most well-known wireless technologies standards nowadays and it is used in a great range of situations where data exchanging is needed.

A variation of this technology is BLE or Bluetooth Low Energy, which differs from common Bluetooth basically in the low power consumption and it’s a good option for applications that only need to exchange small amounts of data from time to time.

In this post, I’m going to talk about a class of devices called beacons which make use of BLE and after that, I will introduce a basic Android example to detect them.

What is exactly a beacon?

A beacon is a hardware transmitter that broadcasts a packet information, enabling smartphones, tablets and other electronic devices to perform specific actions when they are close to it.

The broadcasted information includes a universally unique identifier (UID) and several bytes that can be used to determine the device’s physical location.

All the beacons have the next configurable characteristics regardless the manufacturer or the protocol used:

  • Tx power: is the power with which the beacons transmit a signal that travels through the air and decreases with the distance. Logically, the greater is the tx power, the more battery consumes the beacon.
  • Advertising interval: this value defines the frequency in which the beacon emits the signal. Unlike the tx power, the lower advertising interval, the more battery consumes the beacon, but it’s important to think a bit before setting this interval value too high since the receiver device would find it more difficult to detect the beacon in this case.

Beacons protocols

  • iBeacon: created by Apple, was the protocol that introduced BLE technology worldwide and defines 3 params:
    • UUID: identify a group.
    • Major: identify a beacons subgroup in a bigger group.
    • Minor: identify a specific beacon.

iBeacons Example

Beacons en Android. Beacons on Android

  • Eddystone: it’s an open source project developed by Google. Unlike iBeacon, it has official support for iOS and Android. A beacon configured with this protocol can emit one of the next packet types:
    • Eddystone-UID: contains an identifier of a beacon.
    • Eddystone-URL: contains an URL
    • Eddystone-TLM: is emitted with the previous packets and contains the beacon health, for example, the battery life.
    • Eddystone-EID: contains an encrypted identifier that changes periodically at a rate determined during the initial registration with a web service.
  • AltBeacon: protocol developed by Radius Networks. It was created as an alternative to the closed protocol iBeacon, offering the same functionalities but being able to deliver more data in each message.

Practical uses

  • (GEO) Marketing: an app can show offers and recommendations depending on the client location predicted by beacons.
  • Museums: a beacon can be installed near each artwork or in each room so that visitors get relevant information when they get closer.
  • Healthcare: monitor movements and activities of in-home patients.
  • Prevention: in dangerous activities, it’s possible to ensure that workers wear the appropriate equipments, meeting the safety standards.

Detecting beacons on Android

Although there are many libraries to detect beacons on Android, we are going to use android-beacon-library, developed by the same people that created the opened AltBeacon protocol. This library may be easily configured to detect a wide variety of beacons, including the most popular beacon types on the market.

Link: https://github.com/AltBeacon/android-beacon-library

*Important: before starting with the Android app, we need to configure the beacons to use. Some manufacturers provide an app to set the different params such as the emission mode (iBeacon, Eddystone…) and scanning period. For this example, we will use Eddystone protocol and a scanning period of 1 second, so it’s important to adjust the beacon emission period according to it.

Once explained what we need, let’s start adding the android-beacon-library dependency in build.gradle file and compiling the project.

compile 'org.altbeacon:android-beacon-library:${altbeacon.version}'

Next, we will create an activity named RangingActivity which implements BeaconConsumer  and uses BeaconManager to set up interaction with beacons .

public class RangingActivity extends Activity implements BeaconConsumer, RangeNotifier {
    protected static final String TAG = "RangingActivity";
    private BeaconManager mBeaconManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ranging);

        mBeaconManager = BeaconManager.getInstanceForApplication(this);

        // In this example, we will use Eddystone protocol, so we have to define it here
        mBeaconManager.getBeaconParsers().add(new BeaconParser().
                setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));

        // Binds this activity to the BeaconService
        mBeaconManager.bind(this);
    }
}

The above bind method calling makes a callback (onBeaconServiceConnect()), where we can start ranging close beacons and receiving information about them by using RangeNotifier. Let’s complete this callback method.

@Override
public void onBeaconServiceConnect() {
    // Encapsulates a beacon identifier of arbitrary byte length
    ArrayList<Identifier> identifiers = new ArrayList<>();
    
    // Set null to indicate that we want to match beacons with any value
    identifiers.add(null);

    // Represents a criteria of fields used to match beacon
    Region region = new Region("AllBeaconsRegion"), identifiers);

    try {
        // Tells the BeaconService to start looking for beacons that match the passed Region object
        mBeaconManager.startRangingBeaconsInRegion(region);
    } catch (RemoteException e) {
        e.printStackTrace();
    }
    // Specifies a class that should be called each time the BeaconService gets ranging data, once per second by default
    mBeaconManager.addRangeNotifier(this);
}

Now, we will implement the method that is called once per configurable scan period to give information about visible beacons.

@Override 
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
    if (beacons.size() > 0) {
        Log.i(TAG, "The first beacon I see is about "+beacons.iterator().next().getDistance()+" meters away.");        
    }
}

In the method above, we obtain relevant data from each Beacon detected like the distance and we can implement different behaviors depending on this data, such as opening an URL if the beacon is 1 meter away.

Summarizing

We have seen a first approach to beacons devices, what they are, what protocols they use and how can be detected on a simple Android app.

There are a lot of details that have not been explained in this post. For more details, I recommend you to read more documentation about the specific protocol you are interested to use in your app.

Hope you liked it, if you have any question, feel free for asking 😉

Related links

OCR on Android


Android services from Scratch

Share on LinkedInTweet about this on TwitterShare on FacebookShare on Google+Buffer this page

Leave a Comment

By completing the form you agree to the Privacy Policy