06 out 2015
blog-digital-transformation

Utilizando Beacons com Android

Recentemente tive o prazer de trabalhar em uma prova de conceito utilizando os beacons, em conjunto com o Android, para o controle de fluxo de pessoas dentro de uma grande corporação com um resultado bastante positivo.

A tecnologia dos beacons é uma velha conhecida da maioria das pessoas pois se baseia no protocolo Bluetooh 4.0, também conhecida como Bluetooh Low Energy – BLE, porém só ganhou destaque no lançamento do sistema operacional iOS 7 embarcado nos dispositivos móveis da Apple. O iBeacon, como foi chamado pela Apple, trata-se de um sistema de proximidade em ambientes fechados que podem interagir com os usuários através de um aplicativo instalado no smartfone.

Apesar da maioria dos fabricantes de Beacons manterem SDK para utilização em ambas as plataformas, iOS e Android, o protocolo criado para os Beacons apresentava bastante instabilidade quando estavam sendo utilizados em dispositivos Android, dificultando a utilização do sistema na plataforma, porém em julho de 2015 a Google lançou um novo protocolo de código aberto chamado Eddystone que veio suprimir essa deficiência e pode ser utilizado em qualquer plataforma.

A seguir vamos criar um projeto para demonstrar como utilizar os Beacons em seu aplicativo Android com os dispositivos produzidos pela Estimote, que já implementa o novo protocolo da Google.

download

O projeto

Primeiramente vamos criar um projeto android com versão mínima do SDK 4.3, versões anteriores não tem suporte ao BLE, e adicionar no arquivo ‘build.gradle’ da aplicação o SDK da estimote como dependência de nosso projeto.

1
2
3
4
5
dependencies {
    fileTree(dir: 'libs', include: ['*.jar'])
    'com.android.support:appcompat-v7:23.0.1'
    'com.estimote:sdk:+@aar'
}

No arquivo ‘AndroidManifest.xml’ devemos inserir as permissões necessárias para acesso ao hardware do bluetooth e para acesso a internet, caso seja necessário contactar um servidor para acessar o conteúdo a ser apresentado ou para acessar a rede da estimote.

Para garantir que tenhamos sempre o monitoramento dos beacons quando a aplicação abrir, vamos criar uma classe que extende de Application para controle do beacon e do bluetooth.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class BeaconApplication extends Application {

    private BeaconManager beaconManager = null;

    @Override
    public void onCreate() {
        super.onCreate();

        if(!getBluetoothState()) {
                setBluetooth(true);
        }

        EstimoteSDK.enableDebugLogging(true);

        setBeaconManager(new BeaconManager(this));
        startService(new Intent(getApplicationContext(), BeaconsMonitoringService.class));
    }

    public BeaconManager getBeaconManager() {
        if (beaconManager == null) {
            beaconManager = new BeaconManager(this);
        }
        return beaconManager;
    }

    public void setBeaconManager(BeaconManager beaconManager) {
        this.beaconManager = beaconManager;
    }

    public boolean setBluetooth(boolean enable) {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        boolean isEnabled = bluetoothAdapter.isEnabled();
        if (enable && !isEnabled) {
            return bluetoothAdapter.enable();
        }
        else if(!enable && isEnabled) {
            return bluetoothAdapter.disable();
        }
        return true;
    }

    public boolean getBluetoothState() {
        BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        return bluetoothAdapter.isEnabled();
    }
}

O controle do bluetooth se faz necessário pois o mesmo poderá estar desativado no momento em que a aplicação for iniciada impedindo o funcionamento do sistema.

Em seguida vamos criar um serviço de irá monitorar os beacons em background:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class BeaconsMonitoringService extends Service {

    private BeaconManager beaconManager;
    private String beaconEddystoneScanId;

    @Override
    public void onDestroy() {
        beaconManager.stopEddystoneScanning(beaconEddystoneScanId);
        beaconManager.disconnect();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        BeaconApplication app = (BeaconApplication)getApplication();
        beaconManager = app.getBeaconManager();

        setEddystoneListener();

        beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
            @Override public void onServiceReady() {
                beaconEddystoneScanId = beaconManager.startEddystoneScanning();
        });

        return START_STICKY;
    }

    private void setEddystoneListener() {
        beaconManager.setEddystoneListener(new BeaconManager.EddystoneListener() {
            @Override public void onEddystonesFound(List<Eddystone> eddystones) {
                if(eddystones.size() > 0) {
                    for (Eddystone eddystone : eddystones) {
                        beaconEddystoneFound(eddystone);
                    }
                }
                else {
                    Log.d(TAG, "Eddystone not found");
                }
            }
        });
    }

    private void beaconEddystoneFound(Eddystone eddystone) {
        //Implementar sua lógica
    }
}

O serviço criado irá monitorar todos os beacons que foram encontrados na proximidade do usuário sendo que nesse momento você poderá realizar o que precisa de acordo com sua lógica de negócio como guardar os dados em um banco de dados para traçar a rota o usuário posteriormente, ver a distância entre o usuário e o beacon afim de entregar um promoção específica e para isso o próprio SDK fornece funções que determinam a distancia:

1
2
3
4
5
Utils.Proximity proximity = Utils.computeProximity(eddystone);

// Utils.Proximity.IMMEDIATE
// Utils.Proximity.NEAR
// Utils.Proximity.FAR

Ou poderá buscar o conteúdo referente aquele beacon na WEB através do mac addres único de cada dispositivo: ‘eddystone.macAddress’

Vale lembrar que os beacons não carregam ou fornecem dados, eles apenas enviam um sinal com um endereço único e toda lógica e conteúdo deverá ser embarcado diretamente na aplicação ou implementado em um serviço externo para consulta, conforme ilustração.

beacons_fluxo

Para finalizar, é sempre bom ter em mente que quando trabalhamos com sinais podemos ter ruídos e interferências, e com os beacons não é diferente, sendo comum você estar próximo a um dispositivo e mesmo assim o aplicativo não detecta-lo ou mesmo ter a detecção intermitente e cabe a cada desenvolvedor implementar a melhor regra para contornar os problemas de acordo com seu negócio.

Leave a Comment