FeasyBeacon SDK Android Interface Guide
Corresponding SDK version |
Document Version |
Compilation Date |
Author |
|---|---|---|---|
3.3.6.0 |
2024-11-19 |
Chang JiGang |
SDK Overview
Android Integration
Integrating this SDK into an Android application enables quick implementation of the following features:
Scanning and stopping scanning of the Beacon module
Connecting and disconnecting from the Beacon module
Information query and parameter modification of the Beacon module
Over-the-air upgrade of the Beacon module
Understanding Instance Objects
BluetoothDeviceWrapper class wraps Bluetooth device information and is used to represent scanned Bluetooth devices.
// BluetoothDeviceWrapper class wraps Bluetooth device information and is used to represent scanned Bluetooth devices.
public class BluetoothDeviceWrapper implements Serializable {
// Beacon type constants
public static final int EDDYSTONE_TYPE = 0x16;
public static final int ALTBEACON_TYPE = 0xFF;
public static final int COMPLETE_LOCAL_NAME = 0x09;
private String address; // Bluetooth device address
private String name; // Bluetooth device name
private Integer rssi; // Signal strength
private long timestampNanos = 0; // Timestamp in nanoseconds
// Beacon objects
private IBeacon iBeacon = null;
private EddystoneBeacon eddystoneBeacon = null;
private AltBeacon altBeacon = null;
private FeasyBeacon feasyBeacon = null;
private String completeLocalName = null; // Complete local name
// Listener object
private Monitor monitor = null;
// Constructor
public BluetoothDeviceWrapper(String address) {
this.address = address;
}
// Constructor
public BluetoothDeviceWrapper(String address, String name, int rssi) {
this.address = address;
this.name = name;
this.rssi = rssi;
}
// Constructor
public BluetoothDeviceWrapper(String address, String name, int rssi, long timestampNanos) {
this.address = address;
this.name = name;
this.rssi = rssi;
this.timestampNanos = timestampNanos;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getRssi() {
return rssi;
}
public void setRssi(Integer rssi) {
this.rssi = rssi;
}
public long getTimestampNanos() {
return timestampNanos;
}
public void setTimestampNanos(long timestampNanos) {
this.timestampNanos = timestampNanos;
}
public IBeacon getIBeacon() {
return iBeacon;
}
public void setIBeacon(IBeacon iBeacon) {
if (iBeacon != null) {
this.iBeacon = iBeacon;
this.eddystoneBeacon = null;
this.altBeacon = null;
}
}
public EddystoneBeacon getEddystoneBeacon() {
return eddystoneBeacon;
}
public void setEddystoneBeacon(EddystoneBeacon eddystoneBeacon) {
if (eddystoneBeacon != null) {
this.eddystoneBeacon = eddystoneBeacon;
this.iBeacon = null;
this.altBeacon = null;
}
}
public AltBeacon getAltBeacon() {
return altBeacon;
}
public void setAltBeacon(AltBeacon altBeacon) {
if (altBeacon != null) {
this.altBeacon = altBeacon;
this.iBeacon = null;
this.eddystoneBeacon = null;
}
}
public FeasyBeacon getFeasyBeacon() {
return feasyBeacon;
}
public void setFeasyBeacon(FeasyBeacon feasyBeacon) {
this.feasyBeacon = feasyBeacon;
}
public String getCompleteLocalName() {
return completeLocalName;
}
public void setCompleteLocalName(String completeLocalName) {
this.completeLocalName = completeLocalName;
}
public Monitor getMonitor() {
return monitor;
}
public void setMonitor(Monitor monitor) {
this.monitor = monitor;
}
}
EddystoneBeacon class represents a Beacon following the Eddystone protocol.
// EddystoneBeacon class represents a Beacon following the Eddystone protocol
public class EddystoneBeacon extends FeasyBeacon {
private final String TAG = "FscEddystone";
private String frameTypeString; // Eddystone type (URL, UID, TLM)
private String frameTypeHex; // Eddystone type (HEX)
private int eddystoneRssiOrVersion; // Eddystone transmit power or version
private String dataValue; // Eddystone broadcast data
private String url;
private String nameSpace;
private String instance;
private String reserved;
private String batteryVoltage;
private String temperature;
private String advertisementsCount;
private String timeSincePowerUp;
public int getEddystoneRssiOrVersion() {
return eddystoneRssiOrVersion;
}
public void setEddystoneRssiOrVersion(int eddystoneRssiOrVersion) {
this.eddystoneRssiOrVersion = eddystoneRssiOrVersion;
}
public String getFrameTypeString() {
return frameTypeString;
}
public void setFrameTypeString(String frameTypeString) {
this.frameTypeString = frameTypeString;
}
public String getFrameTypeHex() {
return frameTypeHex;
}
public void setFrameTypeHex(String frameTypeHex) {
if (frameTypeHex.length() == 1) {
frameTypeHex = "0" + frameTypeHex;
}
this.frameTypeHex = frameTypeHex;
}
public String getDataValue() {
return dataValue;
}
public void setDataValue(String dataValue) {
this.dataValue = dataValue;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getNameSpace() {
return nameSpace;
}
public void setNameSpace(String nameSpace) {
this.nameSpace = nameSpace;
}
public String getInstance() {
return instance;
}
public void setInstance(String instance) {
this.instance = instance;
}
public String getReserved() {
return reserved;
}
public void setReserved(String reserved) {
this.reserved = reserved;
}
public String getBatteryVoltage() {
return batteryVoltage;
}
public void setBatteryVoltage(String batteryVoltage) {
this.batteryVoltage = batteryVoltage;
}
public String getTemperature() {
return temperature;
}
public void setTemperature(String temperature) {
this.temperature = temperature;
}
public String getAdvertisementsCount() {
return advertisementsCount;
}
public void setAdvertisementsCount(String advertisementsCount) {
this.advertisementsCount = advertisementsCount;
}
public String getTimeSincePowerUp() {
return timeSincePowerUp;
}
public void setTimeSincePowerUp(String timeSincePowerUp) {
this.timeSincePowerUp = timeSincePowerUp;
}
}
AltBeacon represents an AltBeacon-type Bluetooth beacon.
// AltBeacon class represents an AltBeacon-type Bluetooth beacon
public class AltBeacon extends FeasyBeacon {
private String reservedId; // Reserved ID
private String manufacturerId; // Manufacturer ID
private String beaconId; // Beacon ID
private int altBeaconRssi; // RSSI value of AltBeacon
private String feature; // Feature
public int getAltBeaconRssi() {
return altBeaconRssi;
}
public void setAltBeaconRssi(int altBeaconRssi) {
this.altBeaconRssi = altBeaconRssi;
}
public String getBeaconId() {
return beaconId;
}
public void setBeaconId(String beaconId) {
this.beaconId = beaconId;
}
public String getManufacturerId() {
return manufacturerId;
}
public void setManufacturerId(String manufacturerId) {
this.manufacturerId = manufacturerId;
}
public String getReservedId() {
return reservedId;
}
public void setReservedId(String reservedId) {
this.reservedId = reservedId;
}
public String getFeature() {
return feature;
}
public void setFeature(String feature) {
this.feature = feature;
}
}
IBeacon class represents a beacon device following the iBeacon protocol.
// IBeacon class represents a beacon device following the iBeacon protocol
public class IBeacon extends FeasyBeacon {
private String company; // Company identifier
private String type; // Beacon type
private String dataLength; // Data length
private int major; // Major value, used to distinguish beacons
private int minor; // Minor value, used to distinguish beacons
private String uuid; // UUID, used to uniquely identify the beacon
private int rssi; // Received Signal Strength Indicator (RSSI)
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getDataLength() {
return dataLength;
}
public void setDataLength(String dataLength) {
this.dataLength = dataLength;
}
public int getMajor() {
return major;
}
public void setMajor(int major) {
this.major = major;
}
public int getMinor() {
return minor;
}
public void setMinor(int minor) {
this.minor = minor;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public int getRssi() {
return rssi;
}
public void setRssi(int rssi) {
this.rssi = rssi;
}
}
Monitor class represents a monitor device, including its attributes of temperature, humidity, battery level, and name.
// Monitor class represents a monitor device, including its attributes of temperature, humidity, battery level, and name
public class Monitor extends FeasyBeacon {
private String temperature; // Temperature value
private String humidity; // Humidity value
private int battery; // Battery level
private String name; // Monitor name
public String getTemperature() {
return temperature;
}
public void setTemperature(String temperature) {
this.temperature = temperature;
}
public String getHumidity() {
return humidity;
}
public void setHumidity(String humidity) {
this.humidity = humidity;
}
@Override
public int getBattery() {
return battery;
}
@Override
public void setBattery(int battery) {
this.battery = battery;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
BeaconBean class is used to represent the attribute information of Bluetooth beacons (including iBeacon, eddystone_url, eddystone_uid, and altBeacon).
// BeaconBean class is used to represent the attribute information of Bluetooth beacons
public class BeaconBean implements Serializable {
private String index; // Index
private String beaconType; // Beacon type(iBeacon, Eddystone_url, Eddystone_uid)
//iBeacon
private String uuid; // UUID of iBeacon
private String major; // Major value of iBeacon
private String minor;// Minor value of iBeacon
//eddystone_url
private String url; // URL of Eddystone_url
//eddystone_uid
private String nameSpace; // Namespace of Eddystone_uid
private String instance; // Instance of Eddystone_uid
private String reserved; // Reserved field of Eddystone
//altBeacon
private String id1; // ID1 of AltBeacon
private String id2; // ID2 of AltBeacon
private String id3; // ID3 of AltBeacon
private String manufacturerId; // Manufacturer ID
private String manufacturerReserved; // Manufacturer reserved field
private String power; // Beacon TX power
private boolean connectable; // Whether connectable
private boolean enable; // Whether broadcasting is enabled
private String version;// Firmware version
private int interval = 1000; // Beacon interval, default value is 1000ms
private String parentName; // Parent node name
private String txpower = "2"; // Beacon TX power, default value is 2
private String phy = "0"; // Physical layer, default value is 0
public BeaconBean() {
}
public BeaconBean(String index, String beaconType) {
this.index = index;
this.beaconType = beaconType;
}
public String getIndex() {
return index;
}
public void setIndex(String index) {
this.index = index;
}
public String getBeaconType() {
return beaconType;
}
public void setBeaconType(String beaconType) {
this.beaconType = beaconType;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getMajor() {
return major;
}
public void setMajor(String major) {
this.major = major;
}
public String getMinor() {
return minor;
}
public void setMinor(String minor) {
this.minor = minor;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getNameSpace() {
return nameSpace;
}
public void setNameSpace(String nameSpace) {
this.nameSpace = nameSpace;
}
public String getInstance() {
return instance;
}
public void setInstance(String instance) {
this.instance = instance;
}
public String getReserved() {
return reserved;
}
public void setReserved(String reserved) {
this.reserved = reserved;
}
public String getId1() {
return id1;
}
public void setId1(String id1) {
this.id1 = id1;
}
public String getId2() {
return id2;
}
public void setId2(String id2) {
this.id2 = id2;
}
public String getId3() {
return id3;
}
public void setId3(String id3) {
this.id3 = id3;
}
public String getManufacturerId() {
return manufacturerId;
}
public void setManufacturerId(String manufacturerId) {
this.manufacturerId = manufacturerId;
}
public String getManufacturerReserved() {
return manufacturerReserved;
}
public void setManufacturerReserved(String manufacturerReserved) {
this.manufacturerReserved = manufacturerReserved;
}
public String getPower() {
return power;
}
public void setPower(String power) {
this.power = power;
}
public boolean isConnectable() {
return connectable;
}
public void setConnectable(boolean connectable) {
this.connectable = connectable;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public String getParentName() {
return parentName;
}
public void setParentName(String parentName) {
this.parentName = parentName;
}
public String getTxpower() {
return txpower;
}
public void setTxpower(String txpower) {
this.txpower = txpower;
}
public String getPhy() {
return phy;
}
public void setPhy(String phy) {
this.phy = phy;
}
}
Quick Integration (Android)
Integrate the SDK
If you haven’t installed Android Studio yet, please visit the Android Studio
Create an Android Project
Create a new project in Android Studio.
Place FeasyBeaconLibrary-release.aar, suotalib-release.aar, and so libraries in the project’s libs directory
![]()
Config build.gradle
dependencies {
implementation fileTree(include: ['*.jar','*.aar'], dir: 'libs')
}
Config AndroidManifest.xml
In your application, you need to grant permissions in the
AndroidManifest.xml. Please add the following code in your application’s manifest file.<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.feasycom.feasybeacon"> <!-- Network and Location Permissions --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- Bluetooth Permissions --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- Add Bluetooth Permission Declaration --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- External Storage Permission --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Read and Write Privilege Permissions --> <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <application android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.FeasyBeacon1"> <!-- Service --> <service android:name="com.feasycom.service.AtCommandService" android:enabled="true" android:exported="false" /> <service android:name="com.feasycom.service.OTABLEService" android:enabled="true" android:exported="false" /> </application> </manifest>
Interface Usage Example
SUOTA SDK Upgrade
class SuotaActivity : BaseActivity<ActivitySuotaBinding>(),
DeviceInfoFragment.OnDeviceInfoFragmentInteractionListener,
AvailableFirmwareFragment.OnAvailableFirmwareFragmentInteractionListener,
UpdateFirmwareFragment.OnUpdateFirmwareFragmentInteractionListener,
BaseSuotaFragment.OnBaseSuotaFragmentInteractionListener {
private lateinit var suotaFile: SuotaFile
private lateinit var suotaManager: SuotaManager
// Establish GATT connection
override fun connect() {
// Initialize SuotaManager
suotaManager = SuotaManager(lifecycle, this, bluetoothDevice, SuotaCallback(this)).apply {
setUiContext(this@SuotaActivity)
connect()
}
}
// Set upgrade file
override fun onFirmwareSelected(suotaFile: SuotaFile?) {
suotaManager.suotaFile = suotaFile
suotaManager.initializeSuota(240, 3, 0, 1, 4, 2)
}
// Start firmware upgrade
override fun startSuotaProtocol() {
suotaManager.startUpdate()
}
}
// A callback class for handling SUOTA (Secure Over-the-Air) firmware update events.
class SuotaCallback(@NonNull private val suotaActivityRef: SuotaActivity) : SuotaManagerCallback() {
// Called when the connection state changes.
override fun onConnectionStateChange(newStatus: SuotaProfile.SuotaManagerStatus) {
}
// Called when the service is discovered.
override fun onServiceDiscovered() {
}
// Called when the characteristic value is read.
override fun onCharacteristicRead(characteristicGroup: SuotaProfile.CharacteristicGroup, characteristic: BluetoothGattCharacteristic) {
}
// Called when device information reading is completed.
override fun onDeviceInfoReadCompleted(status: SuotaProfile.DeviceInfoReadStatus) {
}
// Called when the device is ready for SUOTA.
override fun onDeviceReady() {
}
// Record SUOTA status and additional information.
override fun onSuotaLog(state: SuotaProfile.SuotaProtocolState, type: ISuotaManagerCallback.SuotaLogType, log: String) {
}
// Called during chunked data transmission.
override fun onChunkSend(chunkCount: Int, totalChunks: Int, chunk: Int, block: Int, blockChunks: Int, totalBlocks: Int) {
}
// Update the progress bar when the upload progress changes.
override fun onUploadProgress(percent: Float) {
}
// Called when the SUOTA process is successfully completed.
override fun onSuccess(totalElapsedSeconds: Double, imageUploadElapsedSeconds: Double) {
}
// Called when the SUOTA process fails.
override fun onFailure(errorCode: Int) {
}
// Called when the reboot command is sent.
override fun onRebootSent() {
}
// Update speed statistics during upload.
override fun updateSpeedStatistics(current: Double, max: Double, min: Double, avg: Double) {
}
// Update current speed during upload.
override fun updateCurrentSpeed(currentSpeed: Double) {
}
// Handle displaying the pending reboot dialog.
override fun pendingRebootDialog(rebootDialog: SupportCustomDialogFragment) {
}
}