Slik annonserer du Android som en Bluetooth LE Peripheral

Selv om en relativt ny teknologi, har Bluetooth Low Energy (LE) allerede vist seg å være et allsidig og nyttig kommunikasjonsmedium. Mens det kan brukes til å koble enheter til hverandre trådløst, gjør det også enheter til å fungere som beacons og kringkastingsdata.

I denne opplæringen vil du lære om BluetoothLeAdvertiser klassen, som gjør det mulig for utviklere å slå en støttet telefon til et Bluetooth LE-spor uten behov for ekstra maskinvare. Du vil også lære å skanne etter Bluetooth LE-annonsedata, slik at du kan reagere hensiktsmessig i dine egne applikasjoner. Du kan laste ned kildefilene for denne opplæringen på GitHub.

1. Prosjektoppsett

For denne opplæringen kan du starte med å lage et grunnleggende tomt prosjekt i Android Studio. Du må angi minimum SDK-versjon til 21 i din build.gradle fil, da Bluetooth LE-annonsering ikke ble introdusert på Android før utgivelsen av Lollipop. Selv om det finnes måter å pakke inn APIene som ikke støttes før SDK 21, blir de ikke dekket i denne opplæringen. Vi skal bare fokusere på den nye teknologien ved hånden.

defaultConfig applicationId "com.tutsplus.bleadvertising" minSdkVersion 21 targetSdkVersion 23 versionCode 1 versjonName "1.0"

Deretter må du legge til tre tillatelser til prosjektets AndroidManifest.xml. De to første tillater Bluetooth-kommunikasjon og den tredje tillatelsen, ACCESS_COARSE_LOCATION, er et nytt krav for å bruke Bluetooth på Android 6.0-enheter og over.

  

Hvis du utvikler deg på en enhet som kjører Android 6.0 eller nyere, trenger appen plasseringenstillatelsen gitt av brukeren. Instruksjoner for å gjøre det finnes i Forståelse Tillatelser i Android M, som jeg skrev tidligere i år. For enkelhets skyld vil denne opplæringen bare gi tillatelse fra Android App Info-skjermbildet.

Nå som du har tillatelse til å få tilgang til alt ditt søknad trenger, er det på tide å lage layoutfilen. Åpen activity_main.xml og lag et enkelt layout med to knapper og en tekstvisning.

  

De to Knapp Objekter brukes til å starte reklame eller oppdagelse. De TextView brukes til å vise data funnet ved oppdagelse. Når du er ferdig med å fylle ut layoutfilen, kan du lukke den og åpne MainActivity.java. Det første du gjør i denne filen, er å legge til implementeringen for View.OnClickListener som brukes av knappene.

offentlig klasse MainActivity utvider AppCompatActivity implementerer View.OnClickListener @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main);  @Override public void onClick (Vis v) if (v.getId () == R.id.discover_btn) discover ();  annet hvis (v.getId () == R.id.advertise_btn) annonsere (); 

I det ovennevnte onClick (Vis v) metode, reklamere() og oppdage() defineres senere i denne opplæringen. Du kan legge til stubber for disse metodene nå for at appen din skal kompilere. Deretter må du opprette medlemsvariabler øverst i klassen for å holde oversikt over knappene og tekstvisningen.

privat tekstvisning mText; privat knapp mAdvertiseButton; privat knapp mDiscoverButton;

Når du har definert dine synspunkter, må du initialisere dem onCreate (Bundle savedInstanceState) og led hver Knapp opp til OnClickListener du definerte tidligere.

@Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); mText = (TextView) findViewById (R.id.text); mDiscoverButton = (Button) findViewById (R.id.discover_btn); mAdvertiseButton = (Button) findViewById (R.id.advertise_btn); mDiscoverButton.setOnClickListener (dette); mAdvertiseButton.setOnClickListener (dette); 

Til slutt, sørg for at enheten du eller brukerne bruker, støtter flere annonser. Mens programvarefunksjonene som er nødvendige for å annonsere som en perifer, er tilgjengelige fra Lollipop på, må produsentene også bruke et Bluetooth-brikkesett som kan støtte reklame.

Hvis Bluetooth LE-annonsering ikke støttes, bør du deaktivere de to knappene i søknaden din. Selv om denne funksjonen er kjent for å fungere på Nexus 6, 5X, 6P og 9, finnes det andre telefoner som også støtter Bluetooth LE-annonsering, og flere enheter vil fortsette å bli produsert ettersom produsenter oppretter nyere telefoner og tabletter.

hvis (! BluetoothAdapter.getDefaultAdapter () .MultipleAdvertisementSupported ()) Toast.makeText (dette, "Flere annonser støttes ikke", Toast.LENGTH_SHORT) .show (); mAdvertiseButton.setEnabled (false); mDiscoverButton.setEnabled (false); 

2. Annonsering over Bluetooth LE

For å begynne å annonsere over Bluetooth LE, må du hente BluetoothLeAdvertiser fra Android BluetoothAdapter. Du kan gjøre dette i reklamere() Metode som kalles når reklameknappen tappes.

BluetoothLeAdvertiser annonsør = BluetoothAdapter.getDefaultAdapter (). GetBluetoothLeAdvertiser ();

Når du har din BluetoothLeAdvertiser, Du definerer innstillingene som brukes når du annonserer, for eksempel mengden strøm som antennen skal bruke når kringkasting og hvor ofte enheten skal annonsere. De AdvertiseSettings.Builder klassen lar deg også definere om mobilenheten skal være tilkoblet, noe som gjør at du kan streame mye mer data på tvers av enheter.

AnnonserSettings settings = newAdvertiseSettings.Builder () .setAdvertiseMode (AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) .setTxPowerLevel (AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) .setConnectable (false) .build ();

Du vil merke at dette eksempelet annonserer med høy signalstyrke (TX-effekt) og lav ventetid. Selv om dette gjør at enheten din kan oppdages raskt, kan den også ta opp mye av batteriet, noe som er en verdifull vare når du utvikler deg i mobilrommet.

Det finnes andre alternativer for annonseringsmodusen. De ADVERTISE_MODE_LOW_POWER alternativet er standardinnstillingen for annonsering og overføring minst ofte for å spare mest mulig strøm. De ADVERTISE_MODE_BALANCED alternativet forsøker å spare strøm uten å vente for lenge mellom annonser.

TX-strøm kan settes til ultra lav, lav, middels eller høy. Hvert nivå tilsvarer hvor langt en Bluetooth LE-annonsepakke vil bli synlig, selv om eksakte områder er avhengig av maskinvareenheten.

Deretter definerer du en UUID som brukes til å identifisere pakkene dine når de annonseres. Du kan opprette en ny UUID ved å bruke uuidgen verktøy fra kommandolinjen.

➜ ~ uuidgen CDB7950D-73F1-4D4D-8E47-C090502DBD63

Selv om dette verktøyet oppretter en 128-biters UUID, bruker Android-systemet bare 16-biters UUID-er for reklame og vil automatisk justere en 128-biters UUID for å overholde. I eksemplet ovenfor vil 16-biters UUID være 950D. Deretter lagrer du 128-biters UUID som en streng strings.xml.

CDB7950D-73F1-4D4D-8E47-C090502DBD63

Når du har opprettet UUID, er det på tide å lage ParcelUuidAdvertiseData objekt, og send noen ekstra data som en ekstra tjeneste. For dette eksempelet sender du bare navnet til enheten og strengen "Data" (som må konverteres til et byte-array), da størrelsen på annonsepakkene dine er ganske begrenset.

ParcelUuid pUuid = nytt ParcelUuid (UUID.fromString (getString (R.string.ble_uuid))); AdvertiseData data = new AdvertiseData.Builder () .setIncludeDeviceName (true) .addServiceUuid (pUuid) .addServiceData (pUuid, "Data" .getBytes (Charset.forName ("UTF-8"))) .build ();

Det siste du gjør for å annonsere over Bluetooth LE med enheten din, er å lage et tilbakering som lytter etter suksess eller fiasko når du annonserer, og deretter begynne å annonsere over BluetoothLeAdvertiser.

AdvertiseCallback advertisingCallback = new AdvertiseCallback () @Override public void onStartSuccess (AnnonserSettings settingsInEffect) super.onStartSuccess (settingsInEffect);  @Override public void onStartFailure (int errorCode) Log.e ("BLE", "Annonsering onStartFailure:" + errorCode); super.onStartFailure (errorcode); ; advertiser.startAdvertising (innstillinger, data, annonseringCallback);

På dette tidspunktet bør du kunne kjøre appen og begynne å annonsere over Bluetooth LE. Det neste trinnet i denne opplæringen vil imidlertid gå over å oppdage annonser slik at du kan vise den informasjonen.

3. Oppdage Bluetooth LE-annonser

Før du begynner å oppdage Bluetooth LE-tjenester, må du legge til noen flere medlemsvariabler øverst i klassen din.

privat BluetoothLeScanner mBluetoothLeScanner; Private Handler mHandler = Ny Handler ();

mBluetoothLeScanner brukes til å skanne for Bluetooth LE-pakker og mHandler styrer en liten timer som stopper oppdagelsen etter en bestemt tidsperiode.

I tillegg til disse medlemsvariablene må du opprette en ny ScanCallback på toppen av klassen din slik at den senere kan nås i din søknad av en indre klasse. Denne tilbakeringingen mottar resultatet av en oppdaget akseptabel reklame og viser annonseringsenhetsnavnet og tilhørende data i en tekstvisning.

privat ScanCallback mScanCallback = ny ScanCallback () @Override public void onScanResult (int callbackType, ScanResult resultat) super.onScanResult (callbackType, result); hvis (resultat == null || result.getDevice () == null || TextUtils.isEmpty (result.getDevice (). getName ())) returnere; StringBuilder builder = ny StringBuilder (result.getDevice (). GetName ()); builder.append ("\ n"). append (new String (result.getScanRecord (). getServiceData (result.getScanRecord (). getServiceUuids () .få (0)), Charset.forName ("UTF-8")) ); mText.setText (builder.toString ());  @Override public void onBatchScanResults (Liste resultater) super.onBatchScanResults (results);  @Override public void onScanFailed (int errorCode) Log.e ("BLE", "Discovery onScanFailed:" + errorCode); super.onScanFailed (errorcode); ;

Neste, initialiser mBluetoothLeScanner i onCreate (Bundle savedInstanceState) som vist under.

mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter (). getBluetoothLeScanner ();

Etter at du har initialisert Bluetooth-skanneren, kan du begynne å kutte ut oppdage() metode. For denne prøveapplikasjonen oppretter du en ScanFilter objekt og legg det inn i a Liste slik at søknaden din bare reagerer på reklamepakkene du er interessert i.

ScanFilter filter = ny ScanFilter.Builder () .setServiceUuid (nytt ParcelUuid (UUID.fromString (getString (R.string.ble_uuid)))) .build (); filters.add (filter);

Du må også opprette en ScanSettings objekt, som fungerer på samme måte som AdvertiseSettings objekt som du opprettet tidligere i denne opplæringen.

ScanSettings settings = ny ScanSettings.Builder () .setScanMode (ScanSettings.SCAN_MODE_LOW_LATENCY) .build ();

Når du har filtre, innstillinger og tilbakeringinger på plass, kan du begynne å oppdage Bluetooth LE-annonser.

mBluetoothLeScanner.startScan (filtre, innstillinger, mScanCallback);

Hvis du kjører programmet nå på to enheter som begge støtter Bluetooth LE-annonser, og angir en for å annonsere og den andre skal oppdage, skal oppdagelsesenheten finne annonsøren og vise annonserte data. Følgende skjermbilde viser en Nexus 5X som oppdager en reklame Nexus 6.

Det siste du må gjøre er å opprette en ny kjørbart objekt og knytte det til mHandler. Handleren venter i ti sekunder og starter deretter kjørbart som stopper oppdagelsen. Årsaken til dette er at oppdagelsen raskt kan tømme batteriet på enheten. Du vil bare forsøke å oppdage reklamepakker i korte perioder, eller når du forventer å finne en reklameenhet.

mHandler.postDelayed (new Runnable () @Override public void run () mBluetoothLeScanner.stopScan (mScanCallback);, 10000);

Konklusjon

Selv om dette eksemplet ikke er mye å se på, har du nettopp opprettet en fullt fungerende app som annonserer over Bluetooth LE, slik at andre enheter kan oppdage den og overføre data. Selv om denne opplæringen gikk over annonsering og oppdagelse med Android, kan du like enkelt lage en lignende app for iOS for å dele data på tvers av de to plattformene eller bygge din egen Bluetooth LE-aktiverte enhet som kan samhandle med mobiltelefoner og nettbrett.

Siden denne teknologien fortsetter å vokse og bli integrert i alles lommer, vil det være uendelige muligheter for utviklere å lage virkelig interessante ting. For mer informasjon om hvordan du arbeider med ekstra Bluetooth-teknologi på Android, sjekk ut Lag en Bluetooth-skanner med Android's Bluetooth-API ved Matthew Kim.