# MinewMWC05Kit Documentation

This SDK only supports Bluetooth devices produced by Minew company.

SDK can assist developers in handling all tasks between mobile phones and Bluetooth devices, including scanning devices, broadcasting data, connecting devices, writing data to devices, receiving data from devices, etc.

At present, the SDK only supports the use of Safety Location Smart Badge devices.

# Preliminary work

Overall framework: MWC05BleManager is a device management class that remains singleton during app runtime. MWC05Model is a device instance class that generates an instance for each device, which is used after scanning and connecting. It contains device broadcast data, which is updated as the device broadcasts continuously during scanning. ``MWC05BleManager: Device management class that can scan surrounding devices, connect them, verify them, etcMWC05Model: The Safety Location Smart Badge device instance obtained during scanning, inherited from BaseBleDeviceEntity`

# Import into project

  1. development environment

    The SDK supports a minimum of Android 5.0 and corresponds to API Level 21. Set minSdkVersion to 21 or above in the build. gradle of the module:

    android {
        defaultConfig {
            applicationId "com.xxx.xxx"
            minSdkVersion 21
        }
    }
    
    1
    2
    3
    4
    5
    6
  2. Add the jar package to the libs folder of the moduleand add the following statement in the build. gradle of the module (directly add dependencies):

    implementation files('libs/lib_ble_base.jar')
    implementation files('libs/lib_ble_mwc05.jar')
    implementation files('libs/lib_ble_nl.jar')
    api 'org.lucee:bcprov-jdk15on:1.52.0'
    api 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.16.0'
    api 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
    
    1
    2
    3
    4
    5
    6

Alternatively, right-click on the jar file and select Add as Library to add it to the current module.

Add the. so library file and add the following configuration to build. gradle in the App directory:

   android {
       defaultConfig {
           ndk {
               abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
           }
       }
       sourceSets {
           main {
               jniLibs.srcDirs = ['libs']
           }
       }
   }
1
2
3
4
5
6
7
8
9
10
11
12
  1. The following permissions are required in AndroidManifest. xml If targetSdkVersion is greater than 23, permission management needs to be done to obtain the permissions:

        <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" tools:node="replace" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" tools:node="replace" />
        <uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:remove="android:usesPermissionFlags" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" tools:remove="android:usesPermissionFlags" />
        <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:remove="android:usesPermissionFlags" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
        <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
        <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
        <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

# USE

SDK is divided into three stages: scanning, connection, and read-write.

For Android 6.0 and above systems, when performing BLE scanning, it is necessary to first apply for Bluetooth permission and turn on the location switch before proceeding.

# Start Scan

For Android 6.0 and above systems, when performing BLE scanning, it is necessary to first apply for Bluetooth permission and turn on the location switch before proceeding.

To enable Bluetooth scanning, you need to first turn on Bluetooth. If you scan without turning on Bluetooth, the app will flash back. BLETool. checkBluetooth (this) can be used to determine if Bluetooth is turned on. If it's not turned on, you can turn on Bluetooth first.

MWC05BleManager mBleManager = MWC05BleManager.getInstance();

switch (BLETool.checkBluetooth(this)){
    case BLE_NOT_SUPPORT:
        Toast.makeText(this, "Not Support BLE", Toast.LENGTH_SHORT).show();
        break;
    case BLUETOOTH_ON:
		//Set the scanning time to 5 minutes, the SDK defaults to a scanning time of 5 minutes
		mBleManager.startScan(this, 5 * 60 * 1000, new OnScanDevicesResultListener<MWC05Model>() {
            @Override
            public void onScanResult(List<MWC05Model> list) {
            }

            @Override
            public void onStopScan(List<MWC05Model> list) {
            }
        });
        break;
    case BLUETOOTH_OFF:
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableIntent, 4);
        break;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

During the scanning process, the APP can obtain a portion of the current device data through the SDK. Obtain device data through the MWC05Model as shown below, which is saved in the broadcast frame object.

The SDK providesBaseBleDeviceEntity as the base class for MWC05Model to store public data of devices, as shown in the following table:

field type description
macAddress String mac
name String device name
rssi int blue strength

BaseBleDeviceEntity also stores a BaseNanoLinkFrame, which is used internally to store the device broadcast data frames obtained during scanning. It can be retrieved in the following ways:

MWC05Model module;
MWC05AdvFrame MWC05AdvFrame = (MWC05AdvFrame) module.getNanoLinkFrame();
if (MWC05AdvFrame != null) {
    //mac
    String macAddress = MWC05AdvFrame.getMac();
    //deviceName
    String deviceName = MWC05AdvFrame.getDeviceName();
    //firmwareVersion
    String firmwareVersion = MWC05AdvFrame.getFirmwareVersion();
    //battery Battery percentage,default:Integer.MIN_VALUE Indicates that battery information is not available
    int battery = MWC05AdvFrame.getBattery();
    //frequencyBand frequency
    int frequencyBand = MWC05AdvFrame.getFrequencyBand();
    enum FrequencyPlan{
            EU868(1,"EU868"),
    		US915(2,"US915"),
    		AU915(5,"AU915"),
    		CN470(6,"CN470"),
    		AS923_1(7,"AS923-1"),
    		AS923_2(8,"AS923-2"),
    		KR920(10,"KR920");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Safety Location Smart Badge have 1 types of broadcast frames available。

  1. MWC05AdvFrame

    • MWC05AdvFrame

      field type description
      mac String mac
      deviceName String device Name
      firmwareVersion String firmware Version
      battery int Battery percentage,default:Integer.MIN_VALUE Indicates that battery information is not available
      frequencyBand int enum FrequencyPlan{
      EU868(1,"EU868"),
      US915(2,"US915"),
      AU915(5,"AU915"),
      CN470(6,"CN470"),
      AS923_1(7,"AS923-1"),
      AS923_2(8,"AS923-2"),
      KR920(10,"KR920");
      }

# Connect

Before connecting, it is generally necessary to stop scanning. The SDK provides methods for connecting and disconnecting.

MWC05BleManager mBleManager = MWC05BleManager.getInstance();
//stop
mBleManager.stopScan(context);
//Connection: The module is the device to be connected to
MWC05Model module;
mBleManager.connect(context,module);
//Disconnect: macAddress is the device's MAC address
mBleManager.disConnect(macAddress);
1
2
3
4
5
6
7
8

Attention: Before connecting the device, please confirm if the device is scanned. If the device broadcast is not scanned, calling the connection method will result in a connection failure.

After calling 'connect()', the SDK will monitor the status of the connection process.

//Set up listener
mBleManager.setOnConnStateListener(new OnConnStateListener() {
    /*
     * State callback during connection process
     * @param macAddress      mac
     * @param BleConnectionState connectionState
     */
    @Override
    public void onUpdateConnState(String address, BleConnectionState state) {
        switch (state) {
            case Connecting:
				//After calling connect(), the state will be called back
                break;
            case Connected:
                //The initial connection was successful, but as a transitional stage, it was not truly successful at this time
                break;
            case Bond_None:
				//device pairing callback, this is an invalid pairing state
                break;
            case Bond_Bonding:
				//device pairing callback, this is in the pairing state
                break;
            case Bond_Bonded:
				//device pairing callback, here is the pairing completion status
                //devices must be paired before they can be operated using the methods provided in MWC05BleManager
                break;
            case ConnectComplete:
				//devices must be connected before they can be operated using the methods provided in MWC05BleManager
                break;
            case Disconnect:
				//Connection failure or device disconnection will trigger a callback, while active disconnection will not trigger this status
                break;
            default:
                break;
        }
    }
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

During the connection process, the SDK will return multiple connection states to the app, and the app needs to handle them properly.

  • BleConnectionState.ConnectingBleConnectionState.Connected: In the connected device, do not perform time-consuming operations in this state, as the device discovers services and sends authentication data.
  • BleConnectionState.Bond_None: device pairing is invalid.
  • BleConnectionState.Bond_Bonding: device is currently in pairing mode.
  • BleConnectionState.Bond_Bonded: device pairing status is complete. Only after the device pairing is completed can device be operated using the methods provided in MWC05BleManager .
  • BleConnectionState.ConnectComplete: device has been successfully connected and can perform read and write operations, such as configuring broadcast parameters and reading historical data.
  • BleConnectionState.Disconnect: Connection failure or device disconnection will result in a callback.

# Device configuration read and write operations

The API for device configuration read and write operations is as follows, which can be called using the MWC05BleManager mBleManager=MWC05BleManager. getInstance() object:

    /**
     * Clear the list of scanning devices
     */
     void clearScanResult();

    /**
     * Set default scanning duration
     *
     * @param scanTime Scanning duration, in milliseconds
     */
     void setDefaultScanTime(int scanTime);

    /**
     * Start scanning device
     *
     * @param context context
     * @param listener OnScanDevicesResultListener
     */
     void startScan(Context context, OnScanDevicesResultListener listener) ;

    /**
     * Start scanning device
     *
     * @param context context
     * @param scanTime Scanning duration, in milliseconds
     * @param listener OnScanDevicesResultListener
     */
     void startScan(Context context, int scanTime, OnScanDevicesResultListener listener) ;

    /**
     * Stop scanning device
     *
     * @param context context
     */
     void stopScan(Context context) ;

    /**
     * Determine if scanning is in progress
     *
     */
     boolean isScanning() ;

    /**
     * Restore factory settings
     *
     * @param macAddress mac
     * @param listener OnModifyConfigurationListener
     */
     void reset(String macAddress, OnModifyConfigurationListener listener);

    /**
     * Shutdown
     *
     * @param macAddress mac
     * @param listener OnModifyConfigurationListener
     */
     void powerOff(String macAddress, OnModifyConfigurationListener listener);

    /**
     * Restart
     *
     * @param macAddress mac
     * @param listener OnModifyConfigurationListener
     */
     void reboot(String macAddress, OnModifyConfigurationListener listener);

    /**
     * Connected Device
     *
     * @param context context
     * @param macAddress mac
     */
	 void connect(Context context, String macAddress);

    /**
     * Connected Device
     *
     * @param context context
     * @param module MWC03Model
     */
	 void void connect(Context context, MWC03Model module);

    /**
     * Disconnect
     *
     * @param macAddress mac
     */
	 void void disConnect(String macAddress);

    /**
     * Set up device connection listener
     *
     * @param listener OnConnStateListener
     */
	void setOnConnStateListener(OnConnStateListener listener)

    /**
     * device firmware upgrade
     *
     * @param macAddress  mac
     * @param isLinkUpgrade :true -> upgrade by url,false -> upgrade by file。Default value false, does not support URL upgrade method
     * @param filePath OTA file path, it can be null when upgrading by URL
     * @param upgradeData OTA file data bytes, it can be null when upgrading by URL
     
     * @param fileUpgradeTarget : Upgrade firmware target, OTA data, default fileUpgradeTarget="main", link upgrade method does not need to be modified, only file upgrade method needs to be filled in
     
     * @param linkUpgradeTarget : Upgrade firmware target, OTA data, default linkUpgradeTarget="app", file upgrade method does not need to be modified, only link upgrade method needs to be filled in
     
     * @param listener OnFirmwareUpgradeListener : Upgrade firmware callback
     */
     void firmwareUpgrade(Context context, String macAddress, boolean isLinkUpgrade, String filePath, byte[] upgradeData, String fileUpgradeTarget,String linkUpgradeTarget, OnFirmwareUpgradeListener listener) ;

    /**
     * Query firmware version
     *
     * @param macAddress mac
     * @param listener OnQueryResultListener
     */
	void getFirmwareVersion(String macAddress, OnQueryResultListener<FirmwareVersionModel> listener);

    //Brief content about the FirmwareVersionsModel class
	public class FirmwareVersionModel {
        List<VersionInfo> versionInfoList;
    }

    //About the brief content of the VersionsInfo class
	public class VersionInfo {
        // Firmware Name
        private String firmwareName;
        // Firmware type
        private int firmwareType;
        // Firmware version
        private String firmwareVersion;
        // Firmware slot
        private String slot;
        // methods :Upgrade methods corresponding to firmware types: 'img' supports image file upgrade, 'hl' supports link upgrade, 'file' supports file upgrade
        private ArrayList<String> methods;
    }

    /**
     * get DeviceName
     * @param macAddress MAC Address
     * @param listener OnQueryResultListener
     */
    void getDeviceName(String macAddress, OnQueryResultListener<DeviceName> listener);

    /**
     * set DeviceName
     * @param macAddress MAC Address
     * @param name Device Name(Up to 7 bytes)——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener set Device Name Listener
     */
    void setDeviceName(String macAddress, String name, OnModifyConfigurationListener listener);

    /**
     * Exit Mode 5
     * @param macAddress MAC Address
     * @param listener Exit Mode 5 Listener
     */
    void setExitMode5(String macAddress, OnModifyConfigurationListener listener);

    /**
     * get Indicator Status
     * @param macAddress MAC Address
     * @param listener get Indicator Status Listener
     */
    void getIndicator(String macAddress, OnQueryResultListener<Indicator> listener);

    public class Indicator {
		// Master switch: only when set to true does bz, led, and vm take effect; if set to false, all are off
        private boolean en;
        // Whether to enable the buzzer, the default null is true
        private Boolean bz;
        // Whether to enable lighting effects, null defaults to true
        private Boolean led;
        // Whether to enable vibration, the default null is true
        private Boolean vm;
    }

    /**
     * Set Indicator Status
     * @param macAddress MAC Address
     * @param indicator indicator Parameters——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set up the listener for indicating the status of indicators
     */
    void setIndicator(String macAddress, Indicator indicator, OnModifyConfigurationListener listener);

    /**
     * get Location Method
     * @param macAddress MAC Address
     * @param listener Obtain the location method of the listener
     */
    void getLocationMethod(String macAddress, OnQueryResultListener<LocationMethod> listener);

    public class LocationMethod {
		// This field is an array used to specify the device’s default location methods. Users can configure multiple methods at once and define their order of precedence. If the device fails to obtain a location fix with the current method, it will automatically switch to the next; if all configured methods are attempted and none succeeds, the positioning attempt is considered failed.
        //0	Bluetooth LE Scan
		//1	Wi-Fi Scan  Wi-Fi Scan
		//2	GNSS
        private Integer[] meth;
        // This field is an array used to indicate which location methods are supported by the current device. The values in this field use the same definitions as the Meth table above.
        private Integer[] meth_cap;
        // This field is an array type. The first element indicates whether, during Bluetooth Low Energy (LE) scanning, the device determines location based on a device’s MAC address or on iBeacon Major & Minor values.A value of 0 selects the device MAC address; a value of 1 selects the iBeacon Major & Minor.
        private Integer[] le;
    }

    /**
     * Set the positioning method
     * @param macAddress MAC Address
     * @param locationMethod location Method——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set the location method result listener
     */
    void setLocationMethod(String macAddress, LocationMethod locationMethod, OnModifyConfigurationListener listener);

    /**
     * Obtaining Button mode definitions
     * @param macAddress MAC Address
     * @param listener Get the Button mode to define the listener
     */
    void getModeEntryButtons(String macAddress, OnQueryResultListener<ModeEntryButtons> listener);

    public class ModeEntryButtons {
		//This field is an array. Its first element specifies the button action used to enter Mode 4; the only valid value is 2, which indicates a double press. The array may be left empty to indicate that entering Mode 4 via button is disabled.
        private Integer[] m4;
        //This field is an array used to specify the button action(s) for entering Mode 5. Valid values are 1, 2, 3, 4, 5 and 11, representing a single click, a double click, a triple click, a quadruple click, a quintuple click and a long press, respectively. The user must specify at least one action, and up to five actions may be specified simultaneously.
        private Integer[] m5;
    }

    /**
     * Set the Button mode definition
     * @param macAddress MAC Address
     * @param modeEntryButtons Button mode definitions——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set the button mode and define the result listener.
     */
    void setModeEntryButtons(String macAddress, ModeEntryButtons modeEntryButtons, OnModifyConfigurationListener listener);

    /**
     * Obtain the Location mode
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for the Location mode
     */
    void getLocationMode(String macAddress, OnQueryResultListener<LocationMode> listener);

    public class LocationMode {
		// The device supports 3 basic operating modes and 2 auxiliary modes. Users can configure the device to operate in any one of the 3 basic modes, and then enter either of the 2 auxiliary modes by sending a designated command or pressing a designated button. The 5 modes are briefly described below. Note that, in this document, they will be referred to by numeric identifiers rather than by specific mode names.
        //Basic modes:
        //Mode 1: The device performs periodic location fixes.
        //Mode 2: The device performs a location fix when transitioning from stationary to moving, or vice versa.
        //Mode 3: The device performs periodic location fixes; after a transition from stationary to moving, it changes the location interval.
        //Auxiliary modes:
        //Mode 4: Upon receiving the designated command or the user pressing the designated button, the device performs a single location fix.
        //Mode 5: After the user presses the designated button, the device performs location fixes at a specified interval a finite number of times, then exits automatically.
        
        // This field is an array. The 1st element specifies the location interval after the device enters Mode 5; the 2nd element specifies the number of location fixes to perform in Mode 5.The 3rd element selects the basic operating mode; valid values are 1 , 2 and 3, representing Mode 1 to Mode 3, respectively.
        //When Mode 1 is selected, the 4th element is optional and specifies the location interval. If not provided, a default value will be used.
        //When Mode 3 is selected, the 4th and 5th elements are optional. The 4th element specifies the location interval in the stationary state and the 5th element specifies the location interval in the moving state.The unit of the location interval in seconds. If not provided, default values will be used.
        private Integer[] it;
    }

    /**
     * Set the Location mode.
     * @param macAddress MAC Address
     * @param locationMode Location mode——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set the location mode result listener
     */
    void setLocationMode(String macAddress, LocationMode locationMode, OnModifyConfigurationListener listener);

    /**
     * get Scan Filter
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for the Scan Filter
     */
    void getScanFilter(String macAddress, OnQueryResultListener<ScanFilter> listener);

    public class ScanFilter {
		//This field is of Array type and can contain multiple Map types as array elements. The relationship between Maps is OR, while within a Map it is AND.The key of a map object must be rssi, re_mac, re_raw
        // rssi Received signal strength indicator. range is -100 ~ 0
        // re_mac This field accepts a regular expression for filtering device MAC addresses. The input length limit is 64
        // re_raw This field accepts a regular expression for filtering advertising data. The input length limit is 192
        private LinkedList<TypeMap<String, Object>> filter;
    }

    /**
     * set Scan Filter
     * @param macAddress MAC Address
     * @param scanFilter ScanFilter——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set the Scan Filter result listener
     */
    void setScanFilter(String macAddress, ScanFilter scanFilter, OnModifyConfigurationListener listener);

    /**
     * get WIFi Scan Parameters
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for WIFi Scan Filter
     */
    void getWiFiScan(String macAddress, OnQueryResultListener<WiFiScan> listener);

    public class WiFiScan {
		//This field is used to configure the Wi-Fi scanning timeout, in seconds. Ranging from 1 - 300s.
        private Integer to;
    }

    /**
     * set WIFi Scan Parameters
     * @param macAddress MAC Address
     * @param wiFiScan WiFiScan——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set WiFi Scan Filter result listener
     */
    void setWiFiScan(String macAddress, WiFiScan wiFiScan, OnModifyConfigurationListener listener);

    /**
     * get Le Scan Parameters
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for le Scan Parameters
     */
    void getLeScan(String macAddress, OnQueryResultListener<LeScan> listener);

    public class LeScan {
		//Scan Interval is the duration of time between two consecutive times that the scanner wakes up to receive the advertising messages. The unit is milliseconds.The valid range for this field is 2.5ms to 10240ms (10.24s). Any value outside this range will be considered invalid. Note that even if the set value falls within the valid range, the Bluetooth specification also requires that the value must be a multiple of 0.625, such as 2.5, 3.125, 3.75, etc. If the input value is not a multiple of 0.625, the program will automatically convert it to a close value. For example, 2.6 and 3.0 will be converted to 2.5, and 3.2 and 3.5 will be converted to 3.125.
        private Float it;
		//Scan Window defines how long to scan at each interval. The unit is milliseconds.The valid range for this field is 2.5ms to 10240ms (10.24s). Any value outside this range will be considered invalid. Note that even if the set value falls within the valid range, the Bluetooth specification also requires that the value must be a multiple of 0.625, such as 2.5, 3.125, 3.75, etc. If the input value is not a multiple of 0.625, the program will automatically convert it to a close value. For example, 2.6 and 3.0 will be converted to 2.5, and 3.2 and 3.5 will be converted to 3.125.
        private Float wd;
		//Scan timeout defines the maximum duration a scan operation is allowed to run before it is automatically stopped. The unit is milliseconds.The valid range for this field is 500ms to 655350ms (655.35s). Any value outside this range will be considered invalid. Note that even if the set value falls within the valid range, the Bluetooth specification also requires that the value must be a multiple of 10, such as 10, 20, 30, etc. If the input value is not a multiple of 10, the program will automatically convert it to a close value. For example, 12 and 15 will be converted to 10, and 32 and 35 will be converted to 30.Under specific contexts, this may be referred to as a single Bluetooth Low Energy (BLE) scanning session.
        private Integer to;
		//Active scanner can send a scan request to request additional information from the advertiser, while a passive scanner can only receive data from advertising device.
        private boolean at;
    }

    /**
     * set Le Scan Parameters
     * @param macAddress MAC Address
     * @param leScan LeScan——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set Le Scan Parameters result listener
     */
    void setLeScan(String macAddress, LeScan leScan, OnModifyConfigurationListener listener);

    /**
     * get LoRaWAN
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for LoRaWAN
     */
    void getLoRaWAN(String macAddress, OnQueryResultListener<LoRaWAN> listener);

    public class LoRaWAN {
		//This field is used to enables LoRaWAN Adaptive Data Rate (ADR). Please note that this feature is enabled by default.
        private Boolean adr;
        //This field indicates the LoRaWAN frequency plan, see the Frequency Plan table for details.
        private Integer fq;
        //This field is an array indicating the LoRaWAN frequency plans supported by the device. See the Frequency Plan table for details.
        private Integer[] fq_cap;
    }

    /**
     * set LoRaWAN Parameters
     * @param macAddress MAC Address
     * @param loRaWAN loRaWAN——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set LoRaWAN Parameters result listener
     */
    void setLoRaWAN(String macAddress, LoRaWAN loRaWAN, OnModifyConfigurationListener listener);

    /**
     * get Notification Parameters
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for Notification
     */
    void getNotification(String macAddress, OnQueryResultListener<Notification> listener);

    public class Notification {
		//This field specifies the device’s heartbeat interval. When the device detects that the elapsed time since the last data transmission has exceeded this interval, it automatically sends a heartbeat packet —— unit second。
        private int hb;
        //This field is an array. The first element specifies the number of Bluetooth MAC addresses to be notified (range: 1–5); the second element specifies the length of each Bluetooth MAC address to be notified (range: 2–6 bytes).
        private Integer[] le;
        //This field is an array. The first element specifies the number of Wi-Fi device MAC addresses to be notified (range: 1–4).
        private Integer[] wifi;
    }

    /**
     * set Notification Parameters
     * @param macAddress MAC Address
     * @param notification notification——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set Notification Parameters result listener
     */
    void setNotification(String macAddress, Notification notification, OnModifyConfigurationListener listener);

    /**
     * get LocationActivationCondition:This command is used to configure the conditions under which the device performs locating, and it is only effective in modes 1 , 2 , and 3.
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for LocationActivationCondition
     */
    void getLocationActivationCondition(String macAddress, OnQueryResultListener<LocationActivationCondition> listener);

    public class LocationActivationCondition {
		//This field is used to enable the timer condition. When the value is True, the device can only perform locating during the time period specified by the timer.
        private boolean timer;
    }

    /**
     * set LocationActivationCondition Parameters:This command is used to configure the conditions under which the device performs locating, and it is only effective in modes 1 , 2 , and 3.
     * @param macAddress MAC Address
     * @param locationActivationCondition locationActivationCondition——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set LocationActivationCondition Parameters result listener
     */
    void setLocationActivationCondition(String macAddress, LocationActivationCondition locationActivationCondition, OnModifyConfigurationListener listener);

    /**
     * get Timer Config Parameters
     * @param macAddress  MAC Address
     * @param listener Obtaining the listener for Timer Config Parameters
     */
    void getTimer(String macAddress, OnQueryResultListener<List<Timer>> listener);

    public class Timer {
		//This field is used for the timer id; note that duplicate ids are not allowed.
        private int id = Integer.MIN_VALUE;
		//This field is used to indicate a time period. The first element in the array is the start time, and the second element is the end time. Note that the time format is CBOR Tag 1 type, and the end time must be greater than the start time.10-bit timestamp —— unit : seconds.
        private List<Long> time;
    }

    /**
     * set Timer Config Parameters
     * @param macAddress  MAC Address
     * @param timer Timer Config Parameters——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set Timer Config Parameters result listener
     */
    void setTimer(String macAddress, List<Timer> timer, OnModifyConfigurationListener listener);

    /**
     * get Sensor Parameters
     * @param macAddress  MAC Address
     * @param listener Obtaining the listener for Sensor Parameters
     */
    void getSensor(String macAddress, OnQueryResultListener<Sensor> listener);

    public class Sensor {
		//This field is used to set the motion sensitivity level. Valid values are any integer value of 1 or greater, where a higher value indicates higher sensitivity.Generally, it is 1, 2, and 3 
        private int sens;
		//This field is used to specify how long (in seconds) the device needs to remain still after detecting motion in order to determine that it is in a stationary state. The valid range is 1 to 3600 seconds.
        private int idle;
    }

    /**
     * set Sensor Parameters
     * @param macAddress  MAC Address
     * @param sensor Sensor Parameters——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set Sensor Parameters result listener
     */
    void setSensor(String macAddress, Sensor sensor, OnModifyConfigurationListener listener);

    /**
     * Clear History
     * @param macAddress  MAC Address
     * @param listener Clear History result listener
     */
    void setClearHistory(String macAddress, Boolean force, OnModifyConfigurationListener listener);

    /**
     * Get a list of supported frequency plans.
     * @param fq  Current device frequency band
     * @param listener Obtaining the listener for Frequency Plan List
     */
    void getValidateFrequencyPlanListByFrequency(int fq, OnQueryResultListener<LinkedList<FrequencyPlan>> listener);

    public enum FrequencyPlan {
        EU868(1,"EU868"),
        US915(2,"US915"),
        AU915(5,"AU915"),
        CN470(6,"CN470"),
        AS923_1(7,"AS923-1"),
        AS923_2(8,"AS923-2"),
        KR920(10,"KR920");
    }

    /**
     * get WiFi Scan Filter
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for WiFi Scan Filter
     */
    void getWiFiScanFilter(String macAddress, OnQueryResultListener<WiFiScanFilter> listener);

    public class WiFiScanFilter {
		//This field is of Array type and can contain multiple Map types as array elements. The relationship between Maps is OR, while within a Map it is AND.The key of a map object must be rssi, re_mac
        // rssi Received signal strength indicator. range is -100 ~ 0
        // re_mac This field accepts a regular expression for filtering device MAC addresses. The input length limit is 64
        private LinkedList<TypeMap<String, Object>> filter;
    }

    /**
     * set WiFi Scan Filter
     * @param macAddress MAC Address
     * @param wiFiScanFilter wiFiScanFilter——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set WiFi Scan Filter result listener
     */
    void setWiFiScanFilter(String macAddress, WiFiScanFilter wiFiScanFilter, OnModifyConfigurationListener listener);

    /**
     * get Button PowerOff Status
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for Button PowerOff Status
     */
    void getButtonPowerOff(String macAddress, OnQueryResultListener<ButtonPowerOff> listener);

    public class ButtonPowerOff {
		//Set true to allow the device to be powered off by the button, or false to disable this feature.
        private boolean en;
    }

    /**
     * set Button PowerOff Status
     * @param macAddress MAC Address
     * @param buttonPowerOff Button PowerOff Status
     * @param listener Set Button PowerOff Status result listener
     */
    void setButtonPowerOff(String macAddress, ButtonPowerOff buttonPowerOff, OnModifyConfigurationListener listener);

    /**
     * get ChannelsMask Parameters
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for ChannelsMask Parameters
     */
    void getChannelsMask(String macAddress, OnQueryResultListener<ChannelsMaskGroup> listener);

	/**
	 * First, initialize the object using the setGroupSize(int groupSize) method before using it
	 * FrequencyPlan.CN470 12 groups -> setGroupSize(12)
	 * FrequencyPlan.US915 8 groups -> setGroupSize(8)
	 * FrequencyPlan.AU915 8 groups -> setGroupSize(8)
	 */
    public class ChannelsMaskGroup {
        private int groupSize = 0;
        private boolean[] channelStates;

        public boolean isChannelGroupOpen(int channelIndex) {
            if (channelStates.length==0){
                LogUtilForCombineBase.e("channelStates is null");
                return false;
            }
            if (channelIndex >= 1 && channelIndex <= channelStates.length) {
                return channelStates[channelIndex - 1];
            }
            return false;
        }

        public void setChannelGroupOpen(int channelIndex, boolean isOpen) {
            if (channelStates.length==0){
                LogUtilForCombineBase.e("channelStates is null");
                return;
            }
            if (channelIndex >= 1 && channelIndex <= channelStates.length) {
                this.channelStates[channelIndex - 1] = isOpen;
            }
        }

        public int getGroupSize() {
            return groupSize;
        }

        public void setGroupSize(int groupSize) {
            this.groupSize = groupSize;
            this.channelStates = new boolean[groupSize];
        }

        public boolean[] getChannelStates() {
            return channelStates;
        }

        public void setChannelStates(boolean[] channelStates) {
            this.channelStates = channelStates;
        }
    }
    /**
     * set ChannelsMask Parameters
     * @param macAddress MAC Address
     * @param channelsMaskGroup ChannelsMask
     * @param listener Set ChannelsMask Parameters result listener
     */
    void setChannelsMask(String macAddress, ChannelsMaskGroup channelsMaskGroup, OnModifyConfigurationListener listener);


    /**
     * get Advertising Parameters
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for Advertising Parameters
     */
    void getAdvertising(String macAddress, OnQueryResultListener<LinkedList<Advertising>> listener);

    public class Advertising {
		//This field indicates whether the current advertising settings is enabled.
        public boolean enable;
		//This field specifies the operating mode to which this advertising settings applies, i.e., the settings is enabled when the device is in that mode. 
        public String mode;
		//This field indicates the conditions under which the current advertising settings are enabled. This field is an array, and each element is a map.
        public List<Map<String, Object>> conditions;
		//This field is used to describe information related to LE AD Structures. Refer to the definition of AD Structures for details.
        public AdvertisingAdvStructures advStructures;
		//This field indicates the advertising frame content of the current entry.
        public AdvertisingFrame frame;
		//This field indicates the advertising frame params of the current entry.
        public AdvertisingParams params;
    }

    public class AdvertisingParams {
		//This field specifies the advertising interval, in milliseconds.
        public Integer interval;
		//Advertising transmit power, Uint: dBm. If the input value is NOT directly supported by the device, the closest supported value will be used instead.
        public Integer txPower;
		//This field specifies the PHY used for advertising. The allowed values are defined in Table Advertising PHY Values.
        public Integer phy;
		//This field specifies the advertising timeout, in milliseconds, namely the duration after advertising is enabled. A value of 0, or omitted, indicates that advertising does not time out automatically.
        public Integer timeout;
    }

    /**
     * set Advertising Parameters
     * @param macAddress MAC Address
     * @param adv Advertising Parameters——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set Advertising Parameters result listener
     */
    void setAdvertising(String macAddress, LinkedList<Advertising> adv, OnModifyConfigurationListener listener);

    /**
     * get Button LED Effects
     * @param macAddress MAC Address
     * @param listener Obtaining the listener for Button LED Effects
     */
    void getMode5Effects(String macAddress, OnQueryResultListener<Mode5EffectsBusiness> listener);

    public class Mode5EffectsBusiness {
		//Button LED Effects List
        private LinkedList<Mode5EffectsLed> led;
    }

    public class Mode5EffectsLed {
        //Valid values include 1, 2, 3, 4, 5, and 11, corresponding to single click, double click, triple click, quadruple click, five-click status, and holding the button for extended periods.
        private int buttonAction;
        //Use default lighting effects
        private boolean useDefaultLedEffects;
        //The first array is Lighting Effect Color
        private LedEffectsColor ledEffectsColor;
        //The third array is the lighting effect type
        private LedEffectsType ledEffectsType = LedEffectsType.BLINK;
        //Array the second lighting effect brightness
        private Integer ledLightBrightness;
        //Light effect: Duration of the single light on state
        private Integer ledOnDuration = null;
        //Light effect: Duration of the single off-state
        private Integer ledOffDuration = null;
        //Lighting Effects Cycle Count
        private Integer ledCycleCount = null;
    }

    /**
     * set Button LED Effects
     * @param macAddress MAC Address
     * @param mode5EffectsBusiness Button LED Effects——[Note: Please try to use the objects obtained from the get method. After completing the parts you need to modify, configure the corresponding objects using the set method]
     * @param listener Set Button LED Effects result listener
     */
    void setMode5Effects(String macAddress, Mode5EffectsBusiness mode5EffectsBusiness, OnModifyConfigurationListener listener);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658

Provide additional explanations for some methods:

  1. Grant the device the current mobile phone time:

    	
    	// First, check if Bluetooth is turned on. The CurrentTimeService service on your phone can only be started when Bluetooth is on. If Bluetooth is off, attempting to start it may cause errors on some Android phones. You also need to monitor the Bluetooth status. When Bluetooth is on, the startSyncTimeServer service needs to be started; when Bluetooth is off, the closeSyncTimeServer service needs to be stopped. Note that the closeSyncTimeServer service also needs to be stopped when the activity page is executed in ondestroy.
    	MWC05BleManager mBleManager = MWC05BleManager.getInstance();
    	// Start service
    	mBleManager.startSyncTimeServer(context);
        // Close Service
        mBleManager.closeSyncTimeServer(context); 
    
    
    	// Because some phones may occasionally fail to synchronize time, it's necessary to determine if synchronization was successful. It's recommended to check 3 seconds after the device successfully connects.
    	mBleManager.isDeviceReadSyncTime(context); 
    	// If the time synchronization operation fails, then you need to actively send a time synchronization command to the device.
    	mBleManager.writeTimeToDevice(macAddress, onWriteTimeToDeviceListener);
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  2. Firmware upgrade:

    /**
     * Firmware upgrade:
     *
     * @param macAddress  mac
     * @param upgradeData Upgrade package data
     * @param listener    OnFirmwareUpgradeListener
     */
    mBleManager.firmwareUpgrade(mac,false,0, upgradeData, new OnFirmwareUpgradeListener() {
        
        /**
         * Update package data writing progress
         */
        @Override
        public void updateProgress(int progress) {
        }
    
        /**
         * Upgrade successful callback, at this point the device will actively disconnect from the phone, triggering the On State Listener callback and returning the BleeConnectionState.Disconnect status
         */
        @Override
        public void upgradeSuccess() {
        }
        
        /**
         * Upgrade failed
         */
        @Override
        public void upgradeFailed() {
        }
    });
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
  3. Search History Record

    LogUtil.e("time == ${selectedStartTimeDate.time} ms  ${selectedEndTimeDate.time} ms")
    lifecycleScope.launch(Dispatchers.IO) {
        StorageIndexRecordSearcher<StorageActualData>().getStorageIndexRecordsNeedSearchFile(
            this@MWC05HistoryDataActivity,
            mConnectViewModel.connectMacAddress,
            false,
            StorageIndexRecordCondition()
            .setStorageDataBlockType(StorageDataBlockType.Location)
            .setInstance(StorageIndexInstance.INSTANCE_DEFAULT)
            .setStartTime(when (queryAllData){
                true ->0
                    else  ->selectedStartTimeDate.time/1000
                    })
            .setEndTime(when (queryAllData){
                true ->System.currentTimeMillis()/1000
                    else  ->selectedEndTimeDate.time/1000
                    })
            //.setMaximumQuantityLimit(StorageIndexRecordCondition.QuantityLimit.LIMIT_10000)
        ) { result,exception ->
            lifecycleScope.launch (Dispatchers.Main) {
            if (
                exception == null
                && result != null
                && !result!!.isEmpty()
            ) {
                dealResult(result)
            } else {
                showNoDataDialog()
            }
            LoadingDialogUtil.dismissLoadingDialog()
        }
        }
    }
    
    private fun dealResult(storageActualDataList: List<StorageActualData>?){
        leScanEntryResultList = null
        wifiScanEntryResultList = null
        gnssResultList = null
        if (storageActualDataList!=null&&storageActualDataList.isNotEmpty()){
            leScanEntryResultList = mutableListOf()
                wifiScanEntryResultList = mutableListOf()
                gnssResultList = mutableListOf()
                for (one in storageActualDataList){
                    when(one){
                        is StorageActualDataLocationLeScanEntry->{
                            leScanEntryResultList!!.add(one)
                        }
                        is StorageActualDataLocationWiFiScanEntry -> {
                            wifiScanEntryResultList!!.add(one)
                        }
                        is StorageActualDataGNSS -> {
                            gnssResultList!!.add(one)
                        }
                    }
                }
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57

# Document update record

  • 2026/08/18 Add MWC05 device operation basic function API
Last Updated:: 8/18/2026, 9:39:15 PM