package com.tutsplus.bleadvertising; import android.bluetooth.BluetoothAdapter; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertiseSettings; import android.bluetooth.le.BluetoothLeAdvertiser; import android.bluetooth.le.BluetoothLeScanner; import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanFilter; import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanSettings; import android.os.Bundle; import android.os.Handler; import android.os.ParcelUuid; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView mText; private Button mAdvertiseButton; private Button mDiscoverButton; private BluetoothLeScanner mBluetoothLeScanner; private Handler mHandler = new Handler(); private ScanCallback mScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); if( result == null || result.getDevice() == null || TextUtils.isEmpty(result.getDevice().getName()) ) return; StringBuilder builder = new StringBuilder( result.getDevice().getName() ); builder.append("\n").append(new String(result.getScanRecord().getServiceData(result.getScanRecord().getServiceUuids().get(0)), Charset.forName("UTF-8"))); mText.setText(builder.toString()); } @Override public void onBatchScanResults(List<ScanResult> results) { super.onBatchScanResults(results); } @Override public void onScanFailed(int errorCode) { Log.e( "BLE", "Discovery onScanFailed: " + errorCode ); super.onScanFailed(errorCode); } }; @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( this ); mAdvertiseButton.setOnClickListener( this ); mBluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner(); if( !BluetoothAdapter.getDefaultAdapter().isMultipleAdvertisementSupported() ) { Toast.makeText( this, "Multiple advertisement not supported", Toast.LENGTH_SHORT ).show(); mAdvertiseButton.setEnabled( false ); mDiscoverButton.setEnabled( false ); } } private void discover() { List<ScanFilter> filters = new ArrayList<ScanFilter>(); ScanFilter filter = new ScanFilter.Builder() .setServiceUuid( new ParcelUuid(UUID.fromString( getString(R.string.ble_uuid ) ) ) ) .build(); filters.add( filter ); ScanSettings settings = new ScanSettings.Builder() .setScanMode( ScanSettings.SCAN_MODE_LOW_LATENCY ) .build(); mBluetoothLeScanner.startScan(filters, settings, mScanCallback); mHandler.postDelayed(new Runnable() { @Override public void run() { mBluetoothLeScanner.stopScan(mScanCallback); } }, 10000); } private void advertise() { BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser(); AdvertiseSettings settings = new AdvertiseSettings.Builder() .setAdvertiseMode( AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY ) .setTxPowerLevel( AdvertiseSettings.ADVERTISE_TX_POWER_HIGH ) .setConnectable(false) .build(); ParcelUuid pUuid = new 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(); AdvertiseCallback advertisingCallback = new AdvertiseCallback() { @Override public void onStartSuccess(AdvertiseSettings settingsInEffect) { super.onStartSuccess(settingsInEffect); } @Override public void onStartFailure(int errorCode) { Log.e( "BLE", "Advertising onStartFailure: " + errorCode ); super.onStartFailure(errorCode); } }; advertiser.startAdvertising( settings, data, advertisingCallback ); } @Override public void onClick(View v) { if( v.getId() == R.id.discover_btn ) { discover(); } else if( v.getId() == R.id.advertise_btn ) { advertise(); } } }