Skip to content

Release Notes 4.5.0

Obfuscation rule change to MLProduct for unit testing

Release Notes 4.4.0

Fixes obfuscation issue in 4.3.0 preventing LockState from being serializable Bumps GSON to 2.11 and retrofit to 2.11 Bumps Kotlin to 1.9.20

Note about CoreLibaryDesugaring: AGP AAR metadata checks now enforce that the consuming app MUST USE CoreLibraryDesugaring, even if your app already has a minimum version of 26 or higher. See the Java 8 Support Docs for more details. A future release will increase the minimum SDK version to 26, and remove the CoreLibraryDesugaring dependency.

Release notes 4.3.0

  • Removes usesPermissionFlags=”neverForLocation” attestation for BLUETOOTH_SCAN permission from library manifest: (this should be declared at the app-level depending on your use case: e.g:)
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"/> 
    <!--if You don't have this additional flag, 
    scan won't work on API 31 unless you also are granted fine location permission -->
    <!--using this flag will also prevent you from receiving scan results from location beacons-->
  • Adds MLProduct methods for reading and setting IsForcedRelockEnabled on 6440 (Door Controller) with min firmware version of 1723562164
  • Deprecation of MLProduct.writePrimaryPasscode and MLProduct.writeSecondaryPasscode that take/return the code as an array of Strings, replaced with overloads that take a single string for parity with iOS

Release notes 4.1.2

  • Fixes issue on Android 13/14 where turning off Bluetooth in settings does not stop existing scan

Release notes 4.1.1

  • Firmware Update Stability Improvements

Release notes 4.0.1

  • Adds MLProduct readTime method
  • Adds @Nullable annotation to IMLockScannerDelegate productForDevice(String deviceId)

Release notes 3.0.28

  • Adds MLProduct methods for reading and setting IsDoorPositionSensorEnabled on Deadbolts with min firmware version of 1679338484
  • Additional error handling for failed firmware update downloads

Release notes 3.0.18

  • Prevent a potential crash introduced in 3.0.17 for Samsung Galaxy S9 because of unimplemented abstract members of LocationListener
  • Additional Audit Trail MLPasscodeUnlockType

Release notes 3.0.17

  • Google Play Services Location has been removed as a dependency.
  • Raised required minimum target api to 31 (This is the current Google Play Store minimum requirement)
  • Behavior change: The SDK will attempt to return an error to the MLCommandCallback to any queued command when MLCouldNotStartSession error occurs. If the queued command is an “Unlock” or “Relock” command, the LockState will also be automatically updated from the PendingUnlock/PendingRelock to the preceding state.
  • A new optional static initializer takes MLLocationProvider as a parameter. The provided MLLocationProvider replaces the default Android LocationManager implementation when creating device encounter logs.
    // use this initializer to provide your own MLLocationProvider implementation.
    MLBluetoothSDK sdk = MLBluetoothSDK.getInstance(license, myCustomLocationProvider, context);
    
  • SDK package structure has been changed to move classes not intended for library consumer use out of the base package. (THIS MAY CAUSE A BREAKING CHANGE IN XAMARIN PROJECTS. See updated XamarinSample/MLBLE.Android/Transforms/Metadata.xml)
  • Public methods and fields not intended for library consumer use have been moved out of MLBluetoothSDK and MLProduct
  • In addition to Javadoc, api documentation is now available in Github Flavored Markdown format in the gfm folder

Release notes 3.0.11

Deadbolt Support

Adds Deadbolt Support, which includes the following new MLProduct commands:

  • MLProduct.setDeadBoltIsLeftHanded()
  • MLProduct.readDeadBoltIsLeftHanded()
  • MLProduct.relock()

New MechanismState options

MechanismState has two new types:

  • PendingRelock
  • OpenLocked

MLProductBuilder

Adds an optional MLProductBuilder class useful for creating MLProducts in Java projects

Release notes 2.0.10

Fixes a synchronization issue causing connections to fail unexpectedly on some devices

Release notes 2.0.9

Bug Fix to release 2.0.7 where occasional encryption errors could occur, causing communication with lock to fail.

Release notes 2.0.7

Android 12 support: 2.0.7 fixes a critical issue for Android 12 where locks become non-discoverable after the first disconnection until the scan is stopped and restarted. This is due to a change in behavior in how the OS signals bluetooth disconnects, and can occur even if your app is not targeting API 31.

If your app does target API 31, you will need to add BLUETOOTH_SCAN and BLUETOOTH_CONNECTION permissions to your manifest and request these permissions at runtime. (See the updated README for more details.)

If you target API 30 or less, updating to 2.0.7 should be the only action that you need to make.

One additional “gotcha” that Android 12 introduces is that a user is given a choice at runtime of selecting “Precise” or “Approximate” location– And scanning will only work for API 29-30 with “Precise” location.

Release Notes 2.0.6

Improves telemetry “last encountered date” accuracy

Release Notes 2.0.4

BUGFIX: resolves a defect with the MLProduct.readBatteryLevel command introduced in v1.7.2.

Removes all JNI libraries from the SDK. This greatly reduces the SDK’s package size, and allows the sdk to work with any CPU architecture

Bumps room dependency to 2.3.0.

Release Notes 2.0.2

The 2.0.2 release is a major release that has several changes intended to simplify making your Master Lock BLE app.

This release should be fully compatible with apps made with the previous version of the SDK– The only code changes required are two new delegate methods which can be implemented as empty stubs in your IMLockScannerDelegate and IMLProductDelegate.

(See Breaking Changes below.)

New MLProduct Unlock Commands

    /** 
     * Unlocks the Primary Lock mechanism
     * @param seconds Duration before automatic re-lock in seconds
     * (if 0 is passed, device auto re-lock configuration is used)
     * @param callback the result of the unlock command
     */
    public void unlock(int seconds, MLCommandCallback<String> callback)

    /**
     * Unlocks the given Mechanism for the default automatic re-lock
     * interval set on the lock
     * @param mechanism Which mechanism to unlock Primary/Secondary
     */
    public void unlock(MechanismOptions mechanism, MLCommandCallback<String> callback)

    /**
     *
     * @param mechanism Which mechanism to unlock Primary/Secondary
     * @param seconds desired duration in seconds before automatic re-lock (minimum 4 seconds)
     * @param userCallback callback to receive the result of the unlock command
     */
    public void unlock(MechanismOptions mechanism, int seconds, MLCommandCallback<String> userCallback)

    /**
     * Number of seconds after session start time that a ble 
     * connection will be kept alive
     * if the command queue is empty and MLProduct.autoDisconnect is false
     *
     * Minimum value of 4 seconds will be used if value passed is less than 4
     */
    public void setKeepAliveIntervalSeconds(int keepAliveIntervalSeconds)

For more details, see What’s new in MLProduct 2.0.

Breaking Changes:

New Delegates

IMLProductDelegate.onLockStateChange(MLProduct product, LockState lockState) and IMLLockScannerDelegate.bluetoothDown()

onLockStateChange

This new delegate provides a more complete representation of the state of a Master Lock Device and its component locking mechanism(s).

Using this delegate in tandem with the new unlock commands can greatly simplify tracking lock state, as your app no longer needs to schedule read state commands, calculate automatic re-lock intervals, or monitor MLBroadcastState to determine if a lock is awake.

bluetoothDown()

Notifies when a bluetooth adapter is not available

(Note that your app should continue to work if you have already implemented your own state logic using MLProduct.readPrimaryLockState and MLProduct.didChangeState– you only need to implement the empty delegate stubs to resolve this breaking change)

For more details see the new demo app, and the LockState section of the user guide.

Behavior Change

IMLLockScannerDelegate.productFor(String deviceId) will now be called before IMLLockScannerDelegate.shouldConnect(String deviceId). This allows you to monitor a device through IMLProductDelegate.onLockStateChange(MLProduct product, LockState lockState) delegate before you decide if you want to connect to it.


New MLBluetoothSDK static initializer

The MLBluetoothSDK class now provides two methods for initializing and accessing a single instance of the SDK:

// first call with params to setup with your license/context
MLBluetoothSDK.getInstance(String licenseString, Context context)

// Once initialized, instance can be accessed anywhere:    
MLBluetoothSDK.getInstance()


Release Notes 1.8.7

Breaking Change New Delegate IMLProductDelegate.didReadAuditEntries

This new delegate returns audit data at the time that the data is read from
the lock.

Use didReadAuditEntries in favor of IMLProductDelegate.didUploadAuditEntries
to receive results when the device is offline.

**To use 1.8.7 you will need to implement at minimum a stub for
IMLProductDelegate.didReadAuditEntries**

(This delegate method takes the same parameters as didUploadAuditEntries)

Dependency Changes:

Retrofit has been updated to 4.9.0 and okhttp to 4.91:

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.1'

Release Notes 1.8.3

IMLProductDelegate.didChangeState Behavior Changes:

When MLProduct.autoDisconnect is true (this is the default state) The delegate will
broadcast "Awake" only once on first connection, until an "Asleep" broadcast is sent.

The "Asleep" Broadcast will only occur if no command or new session has been executed/started
for a 6 second interval for a lock that was previously "awake."

This behavior is consistent with the iOS Master Lock Bluetooth SDK.

When autoDisconnect is set to false (this mode uses the keepAlive command), 
the same behavior will apply, except that the "Awake" broadcast will repeat
every second that the lock remains connected.

It is recommended with these changes that you always read the lock state(s) when your 
IMLProductDelegate.didConnect delegate is called, and no longer rely on didChangeState.

Release Notes 1.8.2

NEW:

* Commands can now be queued immediately after you initialize your MLProduct.
Queued commands will begin to execute in the order that they are queued after didConnect().

_(This is the same behavior as the iOS SDK. Prior to this change to the Android SDK,
commands queued before the IMLProductDelegate.productFor delegate would always
return a NotAnSDKManagedProductException)_

* Firmware Update patch
* License handling patch

Breaking Changes:

* Remove deprecated MLProduct constructor with telemetryTimer parameter

Release Notes 1.7.3

* Removes excessive logging

Release Notes 1.7.2

* MLProduct.inFirmwareUpdate is deprecated; use MLProduct.inBootloaderMode. To check if
a firmware update is in progress, use MLProduct.isUpdatingFirmware()
* Changes to connection priority and command execution workflow should reduce latency between
commands once a lock session has been started

Release Notes 1.7.0

  • Behavior Changes: * In prior releases, the Android SDK would send a disconnect command with the MLDisconnect.Both flag to prevent advertising after the end of a session. Now this value will be set to MLDisconnect.None, which is the same as the iOS SDK.
  • API Changes: * MLProduct.setSessionEndDisconnectType(MLDisconnectType customType) allows you to change the default end-of-session-disconnect behavior * Added MLProduct.manager.hasCommands() (adds parity to iOS sdk, shows if MLProduct has queued commands) * Add setter for MLProduct.autoDisconnect with additional documentation: * autoDisconnect determines behavior of an MLProduct session when public and private command queues are empty: if true, an MLProduct’s session will disconnect as soon as the command queues are empty; If false - The MLBluetoothSDK will continue to call the keepAlive callback for up to 30 seconds, or longer if additional commands are enqueued

Release Notes 1.6.4

Important Changes to setLockScannerDelegate and

IMLockScannerDelegate.bluetoothReady behavior:

-Calling MLBluetoothSDK.setLockScannerDelegate will now always result in a call to IMLockScannerDelegate.bluetoothReady() if the device’s Bluetooth Adapter is on. In previous releases, this call would only happen the first time, or as a result of Bluetooth Adapter state changes.

-In previous releases, calls made to setLockScannerDelgate after calling MLBluetoothSDK.stopSDK() would not result in a call bluetoothReady(), and the SDK would stop responding to Bluetooth Adapter state changes. Now if stopSDK() is called, the SDK will resume normal operation upon calling setLockScannerDelegate.

-Fixes issue where MLProduct.isConnected not updated when session terminated by lock

Release Notes 1.6.2

-SDK will no longer to pre-emptively try to stop existing ML SDK scans before starting a new one. If you try to start a scan when the SDK is already scanning, IMLockScannerDelegate will receive an onScanFailed(1) (SCAN_FAILED_ALREADY_STARTED)

-Bump Room dependency to 2.2.5 (Make change to gradle:)

implementation 'androidx.room:room-runtime:2.2.5'
annotationProcessor 'androidx.room:room-compiler:2.2.5'

Added to LocalBroadcastManagager import to docs:

implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'

Release Notes 1.5.6

-SDK will resume sending didDiscover / shouldConnect immediately in cases where the SDK is unable to start a session with a lock.

Release Notes 1.5.5

Changes in IMLProductDelegate.didChangeState() behavior:

-If you are triggering events off of IMLProductDelegate.didChangeState(), now only expect a single “asleep” state when a device disconnects from a session. Previously, this delegate would broadcast “asleep” followed by a 6 second countdown of “awake” ticks, followed by a second “asleep”.

-Also, the “awake” broadcasts will be less frequent with this release– about 1 every second.

Offline Audit Trail Improvements

-Fixed issue preventing audit trail data sometimes not being cached when phone doesn’t have network connectivity

-SDK will internally monitor network status and attempt to send any cached audit trail data when connectivity is restored; previously this only occurred when SDK was initialized or a lock was encountered

-Added method sendCachedAuditEvents() to MLBluetoothSDK that can be used to manually force the SDK to retry sending any existing cached events (Must be called after the SDK and IMLLockScannerDelegate have been initialized, or it will log an error)

Release Notes 1.5.0

Removes all Spongy Castle dependencies:

~~implementation ‘com.madgag.spongycastle:core:1.54.0.0’~~

~~implementation ‘com.madgag.spongycastle:prov:1.54.0.0’~~

~~implementation ‘com.madgag.spongycastle:pkix:1.54.0.0’~~

~~implementation ‘com.madgag.spongycastle🇵🇬1.54.0.0’~~

Updated Gson, Retrofit2, okhttp3, Room, GPS dependencies:

implementation 'com.google.code.gson:gson:2.8.6'

implementation 'com.squareup.retrofit2:retrofit:2.7.1'
implementation 'com.squareup.retrofit2:converter-gson:2.7.1'

implementation 'com.squareup.okhttp3:okhttp:4.3.1'

implementation 'androidx.room:room-runtime:2.2.3'
annotationProcessor 'androidx.room:room-compiler:2.2.3'

implementation 'com.google.android.gms:play-services-location:17.0.0'`

Release Notes 1.4.6

Fixes issue with Audit Trail delegate. Targets Android 10 (no changes to minimum API), uses androidx room/annotation libraries. Dependency version changes:

implementation 'com.google.code.gson:gson:2.8.5'
implementation 'androidx.room:room-runtime:2.0.0'
annotationProcessor 'androidx.room:room-compiler:2.0.0'

Release Notes 1.4.0

Fixes potential crashes caused by scan callbacks before Scanner service is ready, also avoids errors caused by SDK attempting to parse advertisement data from some non-Masterlock Bluetooth devices

Release Notes 1.3.9

Removes JodaTime as a library dependency

Release Notes 1.3.7

Fix support for SDK licenses with provisional regions (e.g. European Union)

Release Notes 1.3.6

SDK manifest no longer requires Bluetooth_LE to install

Release Notes 1.3.5

All of the SDKs native code libraries implement 64 bit support, conforming to Google’s Aug 2019 requirement. To ensure that your app is able to use all supported libraries, add the following to your build.gradle:

ndk {  
abiFilters "arm64-v8a","armeabi-v7a","x86\_64","x86"  
}

Also note that unlike prior releases, the app does not provide for “armeabi” or “mips” architectures, as these architecture, as there aren’t any armeabi or mips devices that meet the SDK’s minimum requirement of API 21.

Breaking Change—

IMLProductDelegate must implement a new method:

public void didUploadAuditEntries(MLProduct product, MLAuditTrailEntry[] entries)

This license-enabled feature will not emit any items unless you have an SDK license with a RecieveAuditEvents permission

Also changed in this release: If you attempt to send a direct command to an MLProduct before the product has been returned to the SDK by the LockScannerDelegate in MLProduct productFor(deviceId), the callback will return a MLNotAnSDKManagedProductException as the error property in the MLCommandCallback.

Release Notes 1.1.6

MLProduct internal/user commands are no longer cleared by the SDK when the product is disconnected. (Prevents crashing due to callbacks going to commands that have been cleared—This is the same as the iOS SDK behavior)

Release Notes 1.1.5

Changes:

Bug fixes

Size trimmed (removed unused libraries)

Additional product info for bluetooth relay

Release notes v1.1.4

Added support for additional Master Lock products

Stability improvements for all Master Lock products

Bug fix from previous SDK version 1.0.6: SDK will be able to start scanning if SDK was previously started with the device’s Bluetooth Adapter in a disabled state once the Bluetooth Adapter is turned on.

Release Notes v1.0.6

The SDK’s internal connected devices list is cleared when stopScanning() is called. This ensures that devices that were connected during stopScanning() can be reconnected on subsequent startScanning() calls.

Release Notes 1.0.4

MLBluetoothSDK.scanner.isScanning will now return “false” when the bluetooth adapter is turned off externally (e.g. when the disables bluetooth in device settings.)

Release Notes v1.0.3

Prior to this release, calling MLBluetoothSDK.stopScanning() would not stop previously started scans, and calling startScanning multiple times would create multiple instances of the bluetoothLeScanner. This has been fixed to perform the expected behavior for stopScanning, and only creating one instance of the scanner.

Release Notes v1.0.2

This release prevents crashing on devices with BT 5.0