#MokoBeaconXPro Android SDK Instruction DOC(English)
1.1 Import "Module mokosupport" to root directory
1.2 Edit "settings.gradle" file
include ':app', ':mokosupport'
1.3 Edit "build.gradle" file under the APP project
dependencies {
...
implementation project(path: ':mokosupport')
}
Initialize sdk at project initialization
MokoSupport.getInstance().init(getApplicationContext());
SDK provides three main functions:
- Scan the device;
- Connect to the device;
- Send and receive data.
Start scanning
MokoSupport.getInstance().startScanDevice(callback);
End scanning
MokoSupport.getInstance().stopScanDevice();
Implement the scanning callback interface
/**
* @ClassPath com.moko.support.callback.MokoScanDeviceCallback
*/
public interface MokoScanDeviceCallback {
void onStartScan();
void onScanDevice(DeviceInfo device);
void onStopScan();
}
- Analysis
DeviceInfo
; inferredBeaconXInfo
BeaconXInfo beaconXInfo = new BeaconXInfoParseableImpl().parseDeviceInfo(device);
Device types can be distinguished by parseDeviceInfo(DeviceInfo deviceInfo)
.Refer deviceInfo.scanResult.getScanRecord().getServiceData()
we can get parcelUuid,etc.
if (parcelUuid.toString().startsWith("0000feaa")) {
isEddystone = true;
byte[] bytes = map.get(parcelUuid);
if (bytes != null) {
switch (bytes[0] & 0xff) {
case BeaconXInfo.VALID_DATA_FRAME_TYPE_UID:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_UID;
// 00ee0102030405060708090a0102030405060000
break;
case BeaconXInfo.VALID_DATA_FRAME_TYPE_URL:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_URL;
// 100c0141424344454609
break;
case BeaconXInfo.VALID_DATA_FRAME_TYPE_TLM:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_TLM;
// 20000d18158000017eb20002e754
break;
}
}
values = bytes;
} else if (parcelUuid.toString().startsWith("0000feab")) {
isBeaconXPro = true;
byte[] bytes = map.get(parcelUuid);
if (bytes != null) {
switch (bytes[0] & 0xff) {
case BeaconXInfo.VALID_DATA_FRAME_TYPE_INFO:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_INFO;
battery = MokoUtils.toInt(Arrays.copyOfRange(bytes, 3, 5));
lockState = bytes[5] & 0xff;
connectState = bytes[6] & 0xff;
// 40000a0d0d0001ff02030405063001
break;
case BeaconXInfo.VALID_DATA_FRAME_TYPE_IBEACON:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_IBEACON;
// 50ee0c0102030405060708090a0b0c0d0e0f1000010002
break;
case BeaconXInfo.VALID_DATA_FRAME_TYPE_AXIS:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_AXIS;
// 60f60e010007f600d5002e00
break;
case BeaconXInfo.VALID_DATA_FRAME_TYPE_TH:
type = BeaconXInfo.VALID_DATA_FRAME_TYPE_TH;
// 700b1000fb02f5
break;
}
}
values = bytes;
}
MokoSupport.getInstance().connDevice(context, address, mokoConnStateCallback);
When connecting to the device, context, MAC address and callback interface of connection status (MokoConnStateCallback
) should be transferred in.
public interface MokoConnStateCallback {
/**
* @Description Connecting succeeds
*/
void onConnectSuccess();
/**
* @Description Disconnect
*/
void onDisConnected();
}
"Demo Project" implements callback interface in Service. It uses EventBus
to notify activity after receiving the status, and send and receive data after connecting to the device whit broadcast
All the request data is encapsulated into TASK, and sent to the device in a QUEUE way.
SDK gets task status from task callback (MokoOrderTaskCallback
) after sending tasks successfully.
- Task
At present, all the tasks sent from the SDK can be divided into 4 types:
- READ:Readable
- WRITE:Writable
- NOTIFY:Can be listened( Need to enable the notification property of the relevant characteristic values)
- WRITE_NO_RESPONSE:After enabling the notification property, send data to the device and listen to the data returned by device.
- RESPONSE_TYPE_DISABLE_NOTIFY close the notification property.
Encapsulated tasks are as follows:
Task Class | Task Type | Function |
---|---|---|
NotifyConfigTask |
NOTIFY | Enable notification property |
NotifyAxisTask |
NOTIFY/RESPONSE_TYPE_DISABLE_NOTIFY | Enable/Disable 3-axis notification property |
NotifyHTTask |
NOTIFY/RESPONSE_TYPE_DISABLE_NOTIFY | Enable/Disable temp&humidity notification property |
NotifySavedHTTask |
NOTIFY/RESPONSE_TYPE_DISABLE_NOTIFY | Enable/Disable temp&humidity saved notification property |
Task Class | Task Type | Function |
---|---|---|
LockStateTask |
READ | Get Lock State; 0x00 stands for LOCKED and needs to be unlocked; 0x01 stands for UNLOCKED; 0x02 stands for Uulocked and automatic relock disabled. |
LockStateTask |
WRITE | Set new password; AES encryption of 16 byte new password with 16 byte old password ( To prevent the new password from being broadcast in the clear, the client shall AES-128-ECB encrypt the new password with the existing password. The BeaconX shall perform the decryption with its existing password and set that value as the new password. ). |
UnLockTask |
READ | Get a 128-bit challenge token. This token is for one-time use and cannot be replayed.To securely unlock the BeaconX, the host must write a one-time use unlock_token into the characteristic. To create the unlock_token, it first reads the randomly generated 16-byte challenge and generates it using AES-128-ECB.encrypt (key=password[16], text=challenge[16]). |
UnLockTask |
WRITE | Unlock,If the result of this calculation matches the unlock_token written to the characteristic, the beacon is unlocked. Sets the LOCK STATE to 0x01 on success. |
ManufacturerTask |
READ | Get manufacturer. |
DeviceModelTask |
READ | Get product model. |
ProductDateTask |
READ | Get production date. |
HardwareVersionTask |
READ | Get hardware version. |
FirmwareVersionTask |
READ | Get firmware version. |
SoftwareVersionTask |
READ | Get software version. |
BatteryTask |
READ | Get battery capacity. |
ConnectableTask |
READ | Get connectable. |
ConnectableTask |
WRITE | Set connectable. |
RadioTxPowerTask |
READ | Get current SLOT Tx Power. |
RadioTxPowerTask |
WRITE | Set current SLOT Tx Power(1bytes). Please take TxPowerEnum as reference |
AdvIntervalTask |
READ | Get current SLOT broadcasting Interval. |
AdvIntervalTask |
WRITE | Set current SLOT broadcasting Interval(2bytes). Range:100ms- 5000ms. Example:0x03E8=1000 (Unit:ms). |
AdvTxPowerTask |
WRITE | Set currnent SLOT advTxPower(RSSI@0m, 1bytes). Range:-127dBm—0dBm. Example:0xED=-19dBm. |
ResetDeviceTask |
WRITE | Reset |
WriteConfigTask |
WRITE_NO_RESPONSE | Write ConfigKeyEnum.GET_DEVICE_MAC ,get MAC address. |
WriteConfigTask |
WRITE_NO_RESPONSE | WriteConfigKeyEnum.SET_CLOSE ,close the device. |
WriteConfigTask |
WRITE_NO_RESPONSE | Write GET_AXIX_PARAMS ,get 3-axis params. |
WriteConfigTask |
WRITE_NO_RESPONSE | Write GET_TH_PERIOD ,get temp&humidity period. |
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetTHPriod(int period) ,set temp&humidity period. |
WriteConfigTask |
WRITE_NO_RESPONSE | Write SET_TH_EMPTY ,clear temp&humidity data. |
WriteConfigTask |
WRITE_NO_RESPONSE | Write GET_DEVICE_TIME ,get device time. |
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetDeviceTime(int year, int month, int day, int hour, int minute, int second) ,sync time. |
WriteConfigTask |
WRITE_NO_RESPONSE | Write GET_STORAGE_CONDITION ,get storage condition. |
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetStorageCondition(int storageType, String storageData) ,set torage condition. |
WriteConfigTask |
WRITE_NO_RESPONSE | Write GET_TRIGGER_DATA ,get trigger data. |
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetTriggerData(int triggerType, boolean isAbove, int params, boolean isStart) ,set trigger data. |
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetTriggerData() ,set trigger data. |
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetTriggerData(int triggerType, int params, boolean isStart) ,set trigger data. |
Task Class | Task Type | Function |
---|---|---|
WriteConfigTask |
WRITE_NO_RESPONSE | CallsetiBeaconUUID(String uuidHex) ,set iBeacon UUID(16bytes). |
AdvSlotDataTask |
READ | After switching the SLOT, get the current SLOT data |
AdvSlotDataTask |
WRITE | After switching the SLOT, set the current SLOT data |
iBeacon data composition:SLOT type(0x50) + UUID(16bytes) + Major(2bytes) + Minor(2bytes)
Task Class | Task Type | Function |
---|---|---|
AdvSlotTask |
WRITE | Switch SLOT. Please take SlotEnum as reference |
AdvSlotDataTask |
READ | After switching the SLOT, get the current SLOT data and parse the returned data according to the SLOT type. |
AdvSlotDataTask |
WRITE | After switching the SLOT, set the current SLOT data |
UID data composition:SLOT type(0x00) + Namespace(10bytes) + Instance ID(6bytes)
URL data composition:SLOT type(0x10) + URLScheme(1bytes) + URLContent(Max 17bytes)
TLM data composition:SLOT type(0x20)
NO_DATA data composition:0
Task Class | Task Type | Function |
---|---|---|
AdvSlotDataTask |
READ | After switching the SLOT, get the current SLOT data |
AdvSlotDataTask |
WRITE | After switching the SLOT, set the current SLOT data |
Device data composition:SLOT type(0x40) + DeviceName(20bytes)
Task Class | Task Type | Function |
---|---|---|
AdvSlotDataTask |
READ | After switching the SLOT, get the current SLOT data |
AdvSlotDataTask |
WRITE | After switching the SLOT, set the current SLOT data |
Axis data composition:SLOT type(0x60)
Task Class | Task Type | Function |
---|---|---|
AdvSlotDataTask |
READ | After switching the SLOT, get the current SLOT data |
AdvSlotDataTask |
WRITE | After switching the SLOT, set the current SLOT data |
TH data composition:SLOT type(0x70)
- Create tasks
The task callback (MokoOrderTaskCallback
) and task type need to be passed when creating a task. Some tasks also need corresponding parameters to be passed.
Examples of creating tasks are as follows:
/**
* @Description get LOCK STATE
*/
public OrderTask getLockState() {
LockStateTask lockStateTask = new LockStateTask(this, OrderTask.RESPONSE_TYPE_READ);
return lockStateTask;
}
...
/**
* @Description set temp&humidity period
*/
public OrderTask setTHPeriod(int period) {
WriteConfigTask writeConfigTask = new WriteConfigTask(this);
writeConfigTask.setTHPriod(period);
return writeConfigTask;
}
...
/**
* @Description Switch SLOT
*/
public OrderTask setSlot(SlotEnum slot) {
AdvSlotTask advSlotTask = new AdvSlotTask(this, OrderTask.RESPONSE_TYPE_WRITE);
advSlotTask.setData(slot);
return advSlotTask;
}
}
- Send tasks
MokoSupport.getInstance().sendOrder(OrderTask... orderTasks);
The task can be one or more.
- Task callback
/**
* @ClassPath com.moko.support.callback.OrderCallback
*/
public interface MokoOrderTaskCallback {
void onOrderResult(OrderTaskResponse response);
void onOrderTimeout(OrderTaskResponse response);
void onOrderFinish();
}
void onOrderResult(OrderTaskResponse response);
After the task is sent to the device, the data returned by the device can be obtained by using the `onOrderResult` function, and you can determine witch class the task is according to the `response.orderType` function. The `response.responseValue` is the returned data.
void onOrderTimeout(OrderTaskResponse response);
Every task has a default timeout of 3 seconds to prevent the device from failing to return data due to a fault and the fail will cause other tasks in the queue can not execute normally. After the timeout, the `onOrderTimeout` will be called back. You can determine witch class the task is according to the `response.orderType` function and then the next task continues.
void onOrderFinish();
When the task in the queue is empty, `onOrderFinish` will be called back.
- Listening task
If the task belongs to NOTIFY
and WRITE_NO_RESPONSE
task has been sent, the task is in listening state. When there is data returned from the device, the data will be sent in the form of broadcast, and the action of receiving broadcast is MokoConstants.ACTION_CURRENT_DATA
.
String action = intent.getAction();
...
if (MokoConstants.ACTION_CURRENT_DATA.equals(action)) {
OrderType orderType = (OrderType) intent.getSerializableExtra(MokoConstants.EXTRA_KEY_CURRENT_DATA_TYPE);
byte[] value = intent.getByteArrayExtra(MokoConstants.EXTRA_KEY_RESPONSE_VALUE);
...
}
Get OrderTaskResponse
from the intent of onReceive
, and the corresponding key value is MokoConstants.EXTRA_KEY_RESPONSE_ORDER_TASK
.
- AndroidManifest.xml of SDK has declared to access SD card and get Bluetooth permissions.
- The SDK comes with logging, and if you want to view the log in the SD card, please to use "LogModule". The log path is : root directory of SD card/mokoBeaconXPro/mokoBeaconXPro.txt. It only records the log of the day and the day before.
- Just connecting to the device successfully, it needs to delay 1 second before sending data, otherwise the device can not return data normally.
- We suggest that sending and receiving data should be executed in the "Service". There will be a certain delay when the device returns data, and you can broadcast data to the "Activity" after receiving in the "Service". Please refer to the "Demo Project".