FeasyBeacon SDK Android Interface Guide

[中文版]

Corresponding SDK version

Document Version

Compilation Date

Author

FeasyBeacon-SDK-Android-3.3.6.zip

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) {
    
    }

}

Appendix

Download PDF