This page details the design changes made in the new HID® Approve™ SDK for Google® Android®.
Please refer to the code examples provided below that illustrate the code changes, as well as Add the SDK to Your App.
 Upgrade issue when migrating from versions earlier than SDK v5.1
Upgrade issue when migrating from versions earlier than SDK v5.1
                                                    When migrating from an SDK version earlier than 5.1, users might encounter an upgrade issue on some devices.
Impacted devices:
- Devices running on Android 9.0 or later while upgrading the app.
- Devices will be impacted regardless of the absence or presence of registered containers.
On affected devices, SDK initialization (DeviceFactory.getDevice(...)) can fail after app upgrade. This will provoke a new exception - SerialNumberRequiredException.
If this exception is thrown, two solutions are possible:
- The device serial number must be provided to HID Approve SDK through the appropriate parameter of the DeviceFactory.getDevice(…)in order to complete the upgrade successfully.
- If the device serial number cannot be provided, the SDK must be reset though the dedicated method DeviceFactory.reset()to complete the upgrade. All registered services will be lost. After this operation, the next SDK initialization will be successful.
What's New in Version 5.9 from 5.7.1
SDK Updates
- 
                                                        Support for Weak (Class 2) biometric authenticators 
- 
                                                        Sequential passwords are prohibited unless explicitly authorized with password policy parameters 
SDK Additions and New Features
 Package com.hidglobal.ia.service.protectionpolicy
Package com.hidglobal.ia.service.protectionpolicy
                                                    BioAuthenticationState
NEW enumeration value “INVALID_KEY”
BioPasswordPolicy
UPDATE method “setBiometricPrompt” to use FragmentActivity
NEW method accessor “getAuthorizedAuthenticator”
PasswordPolicy
NEW method accessor “isSequenceAllowed”
 Package com.hidglobal.ia.service.transaction
Package com.hidglobal.ia.service.transaction
                                                    Container
NEW method accessor “getOriginalCreationDate”
ServerAction
NEW method accessor “getPayload”
What's New in Version 5.7.1 from 5.5.1
SDK Updates
Migration to 5.7.1 from versions 3.0 and 4.0 is no longer supported.
SDK Additions and New Features
 Package com.hidglobal.ia.service.beans
Package com.hidglobal.ia.service.beans
                                                    PasswordPromptEvent
NEW event parameter constant CONTAINER_POLICY
NEW event parameter constant KEY_POLICY
NEW event parameter constant TYPE
 Package com.hidglobal.ia.service.exception
Package com.hidglobal.ia.service.exception
                                                    ErrorCode
NEW enumeration value "UnsupportedVersion" (7)
NEW enumeration value "InvalidContainer" (8)
Others
REMOVED exception class "SerialNumberRequiredException"
NEW exception class “InvalidContainerException”
 Package com.hidglobal.ia.service.otp
Package com.hidglobal.ia.service.otp
                                                    AsyncOTPGenerator
UPDATE New exception InvalidParameterException added to all methods
 Package com.hidglobal.ia.service.protectionpolicy
Package com.hidglobal.ia.service.protectionpolicy
                                                    BioPasswordPolicy
REMOVED deprecated method “enableFingerPrintManager” (use setBiometricPrompt)
REMOVED deprecated method “getCancellationSignal”
PasswordPolicy
UPDATE New exception InvalidParameterException added to all methods
 Package com.hidglobal.ia.service.transaction
Package com.hidglobal.ia.service.transaction
                                                    Container
UPDATE New exception InvalidParameterException added to all methods
NEW method “updateDeviceInfo” (moved from Device)
void updateDeviceInfo(String name, char[] value, char[] password, Parameter[] params) throws RemoteException, AuthenticationException, UnsupportedDeviceException, InternalException, LostCredentialsException, com.hidglobal.ia.service.exception.FingerprintAuthenticationRequiredException, ServerOperationFailedException, InvalidParameterException;
ContainerInitialization
REMOVED deprecated property “initialPassword” (use EventListener)
Device
UPDATE New exception InvalidParameterException added to all methods
REMOVED deprecated method “retrieveTransaction”
NEW method “retrieveActionInfo”
ServerActionInfo retrieveActionInfo(char[] actionId) throws InternalException, ServerActionContainerInvalidException, InvalidContainerException, InvalidParameterException;
REMOVED deprecated method “createContainer” (use createContainer with sessionPassword)
REMOVED deprecated method “reset” (use DeviceFactory reset)
REMOVED deprecated method “getDefaultInitializationPolicy” (use EventListener)
Key
UPDATE New exception InvalidParameterException added to all methods
Transaction
UPDATE New exception InvalidParameterException added to all methods
UPDATE Class declaration inherits from class ServerAction
Others
DEPRECATED class TransactionInfo (use retrieveActionInfo)
NEW class ServerAction
NEW class ServerActionInfo
 Package com.hidglobal.ia.service.manager
Package com.hidglobal.ia.service.manager
                                                    DeviceFactory
UPDATE New exception InvalidParameterException added to all methods
REMOVED deprecated method “getDevice” with deviceSerialNumber
SDKConstants
NEW constant “ACTION_TRANSACTION”
 Exceptions
Exceptions
                                                    To ease integration, the unchecked runtime-exception IllegalArgumentException has been replaced with InvalidParameterException to indicate any provided parameters. This new exception has been added to all methods containing parameter as mentioned above.
 Proguard rules
Proguard rules
                                                    To ease integration with Proguard/DexGuard/D8 obfuscation, a default rules file has been included in the AAR package.
What's New in Version 5.5.1 from 5.5
SDK Additions and New Features
 Exceptions
Exceptions
                                                    To ease integration, successful biometric authentications via the BioPasswordPolicy no longer return the FingerprintAuthenticationRequiredException exception. This eliminates the need for a second call to the SDK within the AuthenticationCallback delegate to complete the required operation.
What's New in Version 5.5 from 5.4
SDK Additions and New Features
 Package com.hidglobal.ia.service.manager
Package com.hidglobal.ia.service.manager
                                                    DeviceFactory
NEW method "getDevice"
public static Device getDevice(Context context, ConnectionConfiguration config) throws UnsupportedDeviceException, LostCredentialsException, UnsupportedDeviceException, InternalException;
DEPRECATED method "getDevice" (use new method)
public static Device getDevice(Context context, ConnectionConfiguration config, char[] sessionPassword) throws UnsupportedDeviceException, LostCredentialsException, UnsupportedDeviceException, InternalException;
 Exceptions
Exceptions
                                                    Documentation has been updated to specify possible exceptions on some functions and methods.
To ease integration, InvalidPasswordException password-related exceptions have been declared as InvalidPasswordException, PasswordExpiredException, and PasswordNotYetUpdatableException.
What's New in Version 5.4 from 5.1
SDK Additions and New Features
 Package com.hidglobal.ia.service.exception
Package com.hidglobal.ia.service.exception
                                                    ErrorCode
NEW enumeration value InvalidArgument (3)
NEW enumeration value KeyGenerationFailure (4)
NEW enumeration value ProtectionPolicyFailure (5)
NEW enumeration value SecureDataFailure (6)
NEW enumeration value BiometricAuthenticationNotEnabled (207)
InternalException
NEW method "getErrorReason"
public ErrorCode getErrorReason()
NEW method "setErrorReason"
public void setErrorReason(ErrorCode errorReason)
NEW method "getParameter"
public Parameter getParameter()
NEW method "setParameter"
public void setParameter(Parameter param)
NEW class "InvalidParameterException"
 Package com.hidglobal.ia.service.protectionpolicy
Package com.hidglobal.ia.service.protectionpolicy
                                                    LockPolicy.LockType
NEW enumeration value SILENT
NEW class "SilentLockPolicy"
 SDKConstants
SDKConstants
                                                    Package com.hidglobal.ia.service.manager
NEW constant "KEY_PROPERTY_USAGE_OPPRO"
What's New in Version 5.1 from 4.0
SDK Updates
 Package com.hidglobal.ia.service.transaction
Package com.hidglobal.ia.service.transaction
                                                    ContainerInitialization
DEPRECATED field "initialPassword" (use EventListener)
Device
NEW method "createContainer"
public Container createContainer(ContainerInitialization config, char[] sessionPassword, EventListener listener) throws UnsupportedDeviceException, InternalException, AuthenticationException, InvalidPasswordException, RemoteException, UnsafeDeviceException, ServerProtocolException, FingerprintAuthenticationRequiredException, FingerprintNotEnrolledException, GooglePlayServicesObsoleteException, PasswordCancelledException, ServerOperationFailedException;
DEPRECATED method "createContainer" (use new method)
public Container createContainer(ContainerInitialization config, EventListener listener) throws UnsupportedDeviceException, InternalException, AuthenticationException, InvalidPasswordException, RemoteException, UnsafeDeviceException, ServerProtocolException, FingerprintAuthenticationRequiredException, FingerprintNotEnrolledException, GooglePlayServicesObsoleteException, PasswordCancelledException, ServerOperationFailedException;
DEPRECATED method "retrieveTransaction" (use TransactionInfo.getTransaction)
public Transaction retrieveTransaction(char[] transactionId, char[] sessionPassword, Parameter[] params) throws AuthenticationException, RemoteException, UnsupportedDeviceException, PasswordExpiredException, LostCredentialsException, InternalException, InvalidPasswordException, TransactionContainerInvalidException, TransactionExpiredException, ServerOperationFailedException;
DEPRECATED method "reset" (use DeviceFactory.reset)
public boolean reset(Parameter[] params) throws InternalException;
DEPRECATED method "getDefaultInitializationPolicy" (use EventListener)
public ProtectionPolicy getDefaultInitializationPolicy() throws InternalException;
Transaction
UPDATE method "setStatus" throws new exception ServerOperationFailedException
public boolean setStatus(String status, char[] signingPassword, char[] sessionPassword, Parameter[] param) throws AuthenticationException, PasswordExpiredException, TransactionExpiredException, ServerVersionException, RemoteException, LostCredentialsException, InternalException, PasswordRequiredException, FingerprintAuthenticationRequiredException, ServerAuthenticationException, ServerOperationFailedException;
TransactionInfo
UPDATE class declaration as interface
NEW method "getTransaction"
public Transaction getTransaction( char[] sessionPassword, Parameter[] params) throws AuthenticationException, RemoteException, UnsupportedDeviceException, PasswordExpiredException, LostCredentialsException, InternalException, InvalidPasswordException, TransactionContainerInvalidException, TransactionExpiredException, ServerOperationFailedException;
 Package com.hidglobal.ia.service.beans
Package com.hidglobal.ia.service.beans
                                                    ProgressListener
REMOVED class and replaced with "EventListener"
NEW class "PasswordPromptResult"
NEW class "PasswordPromptEvent"
NEW class "EventResult"
NEW class "EventListener"
NEW class "Event"
 Package com.hidglobal.ia.service.manager
Package com.hidglobal.ia.service.manager
                                                    DeviceFactory
NEW method "getDevice"
public static Device getDevice(Context context, ConnectionConfiguration config, char[] sessionPassword) throws UnsupportedDeviceException, LostCredentialsException, UnsupportedDeviceException, InternalException;
NEW method "reset"
public static boolean reset(Context ctx) throws InternalException
DEPRECATED method "getDevice" (use new method)
public static Device getDevice(Context context, ConnectionConfiguration config) throws UnsupportedDeviceException, LostCredentialsException, UnsupportedDeviceException, InternalException;
SDK Additions and New Features
 Package com.hidglobal.ia.service.transaction
Package com.hidglobal.ia.service.transaction
                                                    Container
NEW method "getCreationDate"
public Date getCreationDate();
NEW method "getExpiryDate"
public Date getExpiryDate();
NEW method "getRenewalDate"
public Date getRenewalDate();
NEW method "isRenewable"
public Date isRenewable(char[] password);
NEW method "renew"
public void renew(ContainerRenewal config, char[] sessionPassword, EventListener eventListener) throws PasswordExpiredException , UnsupportedDeviceException, InternalException, AuthenticationException, InvalidPasswordException, RemoteException, UnsafeDeviceException, ServerProtocolException, FingerprintAuthenticationRequiredException, FingerprintNotEnrolledException, LostCredentialsException, PasswordRequiredException, CredentialsExpiredException, ServerUnsupportedOperationException, GooglePlayServicesObsoleteException, PasswordCancelledException, ServerOperationFailedException;
NEW class "ContainerRenewal"
 Package com.hidglobal.ia.service.protectionpolicy
Package com.hidglobal.ia.service.protectionpolicy
                                                    BioPasswordPolicy
DEPRECATED method "getCancellationSignal"
public Object getCancellationSignal() throws InternalException;
DEPRECATED method "enableFingerprintManager" (use setBiometricPrompt)
public void enableFingerprintManager(Object authenticationCallback, Object cancellationSignal) throws InternalException;
NEW method "setBiometricPrompt"
void setBiometricPrompt(Object object, Object authenticationCallback, Object promptInfo);
NEW method "resetBiometricPrompt"
void resetBiometricPrompt();
NEW method "disableBioAuthentication"
void disableBioAuthentication() throws UnsupportedDeviceException, FingerprintNotEnrolledException, FingerprintAuthenticationRequiredException, InternalException, LostCredentialsException, AuthenticationException, PasswordExpiredException;
 Package com.hidglobal.ia.service.exception
Package com.hidglobal.ia.service.exception
                                                    ErrorCode
NEW enumeration value "PasswordCancelled"
NEW enumeration value "GooglePlayServicesObsolete"
NEW enumeration value "ServerUnsupportedOperation"
NEW enumeration value "ServerOperationFailed"
NEW exception class "ServerUnsupportedOperationException"
NEW exception class "ServerOperationFailedException"
NEW exception class "PasswordCancelledException"
NEW exception class "GooglePlayServicesObsoleteException"
What's New in Version 4.0 from 3.0
SDK Addition
 Package com.hidglobal.ia.service.transaction
Package com.hidglobal.ia.service.transaction
                                                    Container
NEW method "IsFIPSModeEnabled" – Reserved for Future Use.
Code Examples
Transaction Retrieval
 SDK 4.0
SDK 4.0
                                                    Context ctx = this.getBaseContext();
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(ctx, connectionConfig);
// get transaction
TransactionInfo txInfo = device.retrieveTransactionInfo(myTransactionId);
Transaction tx = device.retrieveTransaction(myTransactionId, mySessionPwd, new Parameter[0]); SDK 5.1
SDK 5.1
                                                    Context ctx = this.getBaseContext();
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(ctx, connectionConfig, mySessionPwd);
// get transaction
TransactionInfo txInfo = device.retrieveTransactionInfo(myTransactionId);
Transaction tx = txInfo.getTransaction(mySessionPwd, new Parameter[0]); SDK 5.5
SDK 5.5
                                                    Context ctx = this.getBaseContext();
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(ctx, connectionConfig);
// get transaction
TransactionInfo txInfo = device.retrieveTransactionInfo(myTransactionId);
Transaction tx = txInfo.getTransaction(mySessionPwd, new Parameter[0]);Provisioning / Container Creation
 SDK 4.0
SDK 4.0
                                                    // progress listener
@Override
public void onEventReceived(ProgressEvent event) {
    Parameter[] params = event.getParameters();
    char[] message = null; char[] percent = null;
       for (int i = 0; i < params.length; i++) {
        if (SDKConstants.PARAM_SYNCEVENT_MESSAGE.equalsIgnoreCase(params[i].getId()))
            message = params[i].getValue();
        if (SDKConstants.PARAM_SYNCEVENT_PERCENT.equalsIgnoreCase(params[i].getId()))
            percent = params[i].getValue();
        }
        String text = new String(message) + " (" + new String(percent) + ")";
        Log.d(LOG_TAG, "Event Received: " + text);
}
// provisioning
public void doProvisioning() {
    // get device
    ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
    Device device = DeviceFactory.getDevice(this.getBaseContext(), connectionConfig);
    // new container
    ContainerInitialization config = new ContainerInitialization();
    config.activationCode = myActivationCode;
    config.initialPassword = myInitialPassword;
    config.pushId = myPushId;
    config.containerFriendlyName = myContainerName;
    Container container = device.createContainer(config, this);
} SDK 5.1
SDK 5.1
                                                    // progress listener
                @Override
                public EventResult onEventReceived(Event event) {
                    if (event instanceof PasswordPromptEvent) {
            // Continue: operation can continue
            // Cancel: operation is cancelled by the user.
            // Abort: operation is aborted by the app
            PasswordPromptResult result = new PasswordPromptResult(EventResult.Code.Continue);
            result.setPassword(myInitialPassword);
            return result;
        } else {// progress message
            Parameter[] params = event.getParameters();
            char[] message = null; char[] percent = null;
            for (int i = 0; i < params.length; i++) {
                if (SDKConstants.PARAM_SYNCEVENT_MESSAGE.equalsIgnoreCase(params[i].getId()))
                    message = params[i].getValue();
                if (SDKConstants.PARAM_SYNCEVENT_PERCENT.equalsIgnoreCase(params[i].getId()))
                    percent = params[i].getValue();
            }
            String text = new String(message) + " (" + new String(percent) + ")";
            Log.d(LOG_TAG, "Event Received: " + text);
        }
        return null;
    }
// provisioning
public void doProvisioning() {
    // get device
    ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
    Device device = DeviceFactory.getDevice(this.getBaseContext(), connectionConfig, mySessionPwd);
    // new container
    ContainerInitialization config = new ContainerInitialization();
    config.activationCode = myActivationCode;
    // NOTE: “config.initialPassword” is not supported; use listener
    config.pushId = myPushId;
    config.containerFriendlyName = myContainerName;
    Container container = device.createContainer(config, mySessionPwd, this);
} SDK 5.5
SDK 5.5
                                                    // progress listener
@Override
public EventResult onEventReceived(Event event) {
if (event instanceof PasswordPromptEvent) {
// Continue: operation can continue
// Cancel: operation is cancelled by the user.
// Abort: operation is aborted by the app
PasswordPromptResult result = new PasswordPromptResult(EventResult.Code.Continue);
result.setPassword(myInitialPassword);
return result;
} else {// progress message
Parameter[] params = event.getParameters();
char[] message = null; char[] percent = null;
for (int i = 0; i < params.length; i++) {
if (SDKConstants.PARAM_SYNCEVENT_MESSAGE.equalsIgnoreCase(params[i].getId()))
message = params[i].getValue();
if (SDKConstants.PARAM_SYNCEVENT_PERCENT.equalsIgnoreCase(params[i].getId()))
percent = params[i].getValue();
}
String text = new String(message) + " (" + new String(percent) + ")";
Log.d(LOG_TAG, "Event Received: " + text);
}
return null;
}
// provisioning
public void doProvisioning() {
// get device
ConnectionConfiguration connectionConfig = new ConnectionConfiguration();
Device device = DeviceFactory.getDevice(this.getBaseContext(), connectionConfig);
// new container
ContainerInitialization config = new ContainerInitialization();
config.activationCode = myActivationCode;
// NOTE: “config.initialPassword” is not supported; use listener
config.pushId = myPushId;
config.containerFriendlyName = myContainerName;
Container container = device.createContainer(config, mySessionPwd, this);
}Biometric Authentication
 SDK 4.0
SDK 4.0
                                                    // Custom AuthenticationCallback implementation that receives sensor events
class CustomAuthenticationCallback extends FingerprintManager.AuthenticationCallback {
    @Override
    public void onAuthenticationError(int errorCode, CharSequence errString) {
        // Display error
    }
    @Override
    public void onAuthenticationHelp(int helpCode, CharSequence helpString) {
        // Give feedback to user
    }
    @Override
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
        // Fingerprint matched, let’s proceed with the operation requested
        otp = otpGenerator.getOTP(null);
        // Display OTP
    }
    public void onAuthenticationFailed() {
        // Dismiss UI / display user that fingerprint didn’t match
        // A usual behavior is to prompt the user for his/her password
    }
}
 
// Method invoked when button to generate OTP is clicked
public void onGenerateOTPClick(View v) {
    // Pass an AuthenticationCallback instance and a CancellationSignal instance to the SDK
    bioPasswordPolicy.enableFingerprintManager(customAuthenticationCallback, cancellationSignal);
 
    // Perform the requested operation, for example getOTP
    try {
        otp = otpGenerator.getOTP(null);
        // Display OTP
    } catch (FingerprintAuthenticationRequiredException e) {
        // Display UI to show user that he/she must put his/her finger on sensor
    }
} SDK 5.1
SDK 5.1
                                                    // Custom BiometricPrompt.AuthenticationCallback implementation that receives sensor events
class CustomAuthenticationCallback extends BiometricPrompt.AuthenticationCallback {
    @Override
    public void onAuthenticationError(int errorCode, CharSequence errString) {
        // Display error
    }
    @Override
    public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
        // Fingerprint matched, let’s proceed with the operation requested
        otp = otpGenerator.getOTP(null);
        // Display OTP
    }
    public void onAuthenticationFailed() {
        // Dismiss UI / display user that fingerprint didn’t match
        // A usual behavior is to prompt the user for his/her password
    }
}
 
// Method invoked when button to generate OTP is clicked
public void onGenerateOTPClick(View v) {
    // Construct PromptInfo dialog
    BiometricPrompt.PromptInfo prompt =
       new BiometricPrompt.PromptInfo.Builder()
          .setTitle(activity.getString("Confirm fingerprint"))
          .setNegativeButtonText(activity.getString("Cancel"))
          .build();
    // Pass Activity/Fragment, AuthenticationCallback and PromptInfo instances to the SDK
    bioPasswordPolicy.setBiometricPrompt(getActivity(),customAuthenticationCallback,prompt);
 
    // Perform the requested operation, for example getOTP
    otp = otpGenerator.getOTP(null);
    // Display OTP
}
 SDK 5.5.1
SDK 5.5.1
                                                    ProtectionPolicy containerPolicy = pContainer.getProtectionPolicy();
if (containerPolicy.getType().equals(ProtectionPolicy.PolicyType.BIOPASSWORD.toString())
{
    BioPasswordPolicy bioPasswordPolicy = (BioPasswordPolicy)containerPolicy;
    if (bioPasswordPolicy.getBioAuthenticationState() == BioAuthenticationState.NOT_ENABLED)
    {
        // Prompt user for his/her password
        // Then enable authentication with fingerprint
         bioPasswordPolicy.enableBioAuthentication(password);
    }
}