This guide shows developers how to integrate the Android SDK using license mode to enable device management and authentication. The multi-modal SDK supports the license billing model and offers two integration modes: semi-managed and fully-managed.
1. Modes
To use the multimodal interaction development kit with the license billing model, you must integrate the License SDK. For integration instructions, see Section 4.
1.1. Semi-managed mode
Use case: You have your own cloud service to manage and authenticate your devices, and have a two-way communication channel between your cloud service and devices.
Server-side development:
Integrate cloud APIs as described in the cloud API development guide. The device metering and management service provides APIs for device registration and token acquisition.
Device-side development:
Call the
genRegisterReqAPI of the SDK to get the device registration signature.After you get the device registration signature, call your own cloud service to register the device. Your cloud service must integrate the POP SDK.
After the device is registered, call the
writeDeviceInfoAPI of the SDK to write the device information.Call the
genGetTokenReqAPI of the SDK to get the data signature for the access token.After you get the data signature, call your own cloud service to get a token. Your cloud service must integrate the POP SDK.
Call the
getTokenAPI of the SDK to get the decrypted business interaction token. You can then use the token for business interactions.
1.2. Fully-managed mode
Use case: You do not have a cloud service and cannot manage your devices. In this mode, Alibaba Cloud performs device management and authentication.
Server-side development:
None.
Device-side development:
Call the
deviceRegisterAPI of the SDK to register the device.Call the
getTokenAPI of the SDK to get the business interaction token. You can then use the token for business interactions.
2. Prerequisites
To use license mode, you must first create an application in the Model Studio console and purchase a license.
The SDK generates a unique device identifier and persists it on the device to prevent duplicate registrations. Call
DeviceUUIDUtil.getAndroid(context)to retrieve this identifier. You must either use thedeviceNamegenerated by the SDK or ensure the one you provide is unique.To specify a custom storage path for device registration information, call
DeviceUUIDUtil.getAndroidId(context, "your_absolute_storage_path"). The client is responsible for ensuring it has the necessary read and write permissions for the custom path.
3. API
3.1. Initialization
SDK initialization is required for both semi-managed and fully-managed modes.
Input parameters:
Parameter | Type | Required | Description |
appId | String | Yes | The application ID, generated when you create an application in the Model Studio console. |
appSecret | String | Yes | The application secret, generated when you create an application in the Model Studio console. |
deviceName | String | Yes | The unique device ID. Obtain this ID by calling the DeviceUUIDUtil.getAndroidId method. |
callBack | InitCallBack | Yes | The callback for SDK initialization. Refer to the InitCallBack object for details. |
InitCallBack object
Return value | Method name | Description |
void | success() | Called when the SDK is initialized. |
void | fail(ResultError error) | Called when SDK initialization fails. |
ResultError object
Parameter | Type | Required | Description |
code | int | No | The error code. |
message | String | No | The error message. |
Output parameters:
None.
Code sample
DeviceAuthClient.getInstance().initialize(new InitParams(APP_ID, APP_SECRET, mDeviceName), new InitCallBack() {
@Override
public void success() {
Log.d(TAG, "initialize success");
}
@Override
public void fail(ResultError resultError) {
Log.e(TAG, "initialize fail: " + resultError.getMessage());
}
});3.2. Semi-managed mode
3.2.1. Device registration APIs
3.2.1.1. Generate device registration parameters: genRegisterReq
Request parameters:
Parameter | Type | Required | Description |
appId | String | Yes | The app ID. This ID is generated after you create an application in the Model Studio console. |
deviceName | String | Yes | The unique device identifier. Obtain this value by calling the |
payMode | String | Yes | The billing method. Valid values: |
reqNonce | String | Yes | The request nonce. The value must be 26 characters long. |
requestTime | String | Yes | The request timestamp. |
Response parameters:
Parameter | Type | Required | Description |
success | boolean | Yes | Indicates whether the request was successful. |
code | int | No | The error code returned if the request fails. |
message | String | No | The error message returned if the request fails. |
data | String | No | The signature required to call the device registration POP API. |
Code sample:
DeviceRegisterInfo deviceRegisterInfo = new DeviceRegisterInfo();
deviceRegisterInfo.setAppId(APP_ID);
deviceRegisterInfo.setDeviceName(mDeviceName);
deviceRegisterInfo.setPayMode(PAY_MODE);
deviceRegisterInfo.setReqNonce(RandomUtil.generateRandomHexString(26));
deviceRegisterInfo.setRequestTime(String.valueOf(System.currentTimeMillis()));
Result<String> result = DeviceAuthClient.getInstance().genRegisterReq(deviceRegisterInfo);
if (result.isSuccess()) {
Log.d(TAG, "genRegisterReq: " + result.getData());
}3.2.1.2. Write device registration information: writeDeviceInfo
Pass the response from the cloud device registration POP API to the device SDK to write the device information.
Request parameters:
Parameter | Type | Required | Description |
appId | String | Yes | The app ID. This ID is generated after you create an application in the Model Studio console. |
deviceName | String | Yes | The unique device identifier. Obtain this value by calling the |
reqNonce | String | Yes | The request nonce. The value must be 26 characters long. |
rspNonce | String | Yes | The response nonce. The value must be 26 characters long. |
responseTime | String | Yes | The response timestamp. |
signature | String | Yes | The signature for the device credentials, returned by the cloud POP API. |
Response parameters:
Parameter | Type | Required | Description |
success | boolean | Yes | Indicates whether the request was successful. |
code | int | No | The error code returned if the request fails. |
message | String | No | The error message returned if the request fails. |
data | String | No | The response data, if any. |
Code sample:
DeviceRegisterRsp params = new DeviceRegisterRsp();
params.setAppId(APP_ID);
params.setDeviceName(mDeviceName);
params.setReqNonce("YOUR REQUEST NONCE");
params.setRspNonce("YOUR RESPONSE NONCE");
params.setResponseTime("YOUR RESPONSE TIME");
params.setSignature("YOUR RESPONSE SIGNATURE");
Result<String> result = DeviceAuthClient.getInstance().writeDeviceInfo(params);
if (result.isSuccess()) {
Log.d(TAG, "writeDeviceInfo success");
} else {
Log.e(TAG, "writeDeviceInfo error: " + result.getMessage());
}3.2.2. Access token APIs
3.2.2.1. Generate access token request parameters: genGetTokenReq
Request parameters:
Parameter | Type | Required | Description |
nonce | String | Yes | The request nonce. The value must be 26 characters long. |
appId | String | Yes | The app ID. This ID is generated after you create an application in the Model Studio console. |
deviceName | String | Yes | The unique device identifier. Obtain this value by calling the |
payMode | String | Yes | The billing method. Valid values: |
tokenType | String | Yes | The type of token to request. Currently, only
|
requestTime | String | Yes | The request timestamp, in milliseconds. |
Response parameters:
Parameter | Type | Required | Description |
success | boolean | Yes | Indicates whether the request was successful. |
code | int | No | The error code returned if the request fails. |
message | String | No | The error message returned if the request fails. |
data | String | No | The signature required to call the POP API to obtain an access token. |
{
"success": true,
"data": "84uoRCyy6AG/SH7LrHjJW0D7lsBp/H4RReS7gJY5L0oC517xJWAmwtmghLjYkW/Qj4ZvK6vrM7QC5yxtMl3TQLHdAGSsqQLb0bP6zKOiDzoNFwqs61+GMQ7guTPjbE9Fqaf7"
}Code sample:
GenGetTokenParams params = new GenGetTokenParams();
params.setNonce(RandomUtil.generateRandomHexString(26));
params.setAppId("YOUR APP_ID");
params.setDeviceName(mDeviceName);
params.setPayMode(PayMode.LICENSE.getPayMode());
params.setTokenType("MMI");
params.setRequestTime(String.valueOf(System.currentTimeMillis()));
Result<String> result = DeviceAuthClient.getInstance().genGetTokenReq(params);
if (result.isSuccess()) {
Log.d(TAG, "getTokenSign: " + result.getData());
}3.2.2.2. Decode access token response: getToken
Request parameters:
Parameter | Type | Required | Description |
appId | String | Yes | The app ID. This ID is generated after you create an application in the Model Studio console. |
deviceName | String | Yes | The unique device identifier. Obtain this value by calling the |
reqNonce | String | Yes | The request nonce. The value must be 26 characters long. |
rspNonce | String | Yes | The response nonce. The value must be 26 characters long. |
responseTime | String | Yes | The response timestamp. |
signature | String | Yes | The signature returned in the POP API response for the token request. |
Response parameters:
Parameter | Type | Required | Description |
success | boolean | Yes | Indicates whether the request was successful. |
code | int | No | The error code returned if the request fails. |
message | String | No | The error message returned if the request fails. |
data | String | No | The decoded multimodal interaction token, returned after successful signature verification. |
Code sample:
AnalyzeTokenSignRsp tokenSignRsp = new AnalyzeTokenSignRsp();
tokenSignRsp.setAppId(APP_ID);
tokenSignRsp.setDeviceName(mDeviceName);
tokenSignRsp.setReqNonce("YOUR REQUEST NONCE");
tokenSignRsp.setRspNonce("YOUR RESPONSE NONCE");
tokenSignRsp.setResponseTime("YOUR RESPONSE TIME");
tokenSignRsp.setSignature("YOUR RESPONSE SIGNATURE");
Result<String> result = DeviceAuthClient.getInstance().getToken(tokenSignRsp);
if (result.isSuccess()) {
Log.d(TAG, "analyzeTokenSign: " + result.getData());
}3.3. Fully-managed mode
3.3.1. Check device registration: deviceIsRegistered
Parameters:
None
Return value:
A boolean indicating whether the device is registered.
Example:
boolean deviceIsRegistered = DeviceAuthClient.getInstance().deviceIsRegistered();3.3.2. Register a device: deviceRegister
Parameters:
Parameter | Type | Required | Description |
params | Object | Yes | Parameters for device registration. See the |
callBack | DeviceRegisterCallBack | Yes | A callback invoked when device registration completes. |
DeviceRegisterParams object
Parameter | Type | Required | Description |
nonce | String | Yes | A 26-character nonce. |
appId | String | Yes | The App ID. Obtain this ID by creating an application in the Model Studio console. |
workspaceId | String | No | The workspace ID. This parameter is required only if you register the device by using a workspace quota. |
deviceName | String | Yes | The unique device identifier. Obtain this identifier by calling the |
requestTime | String | Yes | The request timestamp, in milliseconds. |
payMode | String | Yes | The billing method. Valid values: |
Return value:
None.
Example:
DeviceRegisterParams params = new DeviceRegisterParams();
params.setNonce(RandomUtil.generateRandomHexString(26));
params.setAppId("YOUR_APP_ID");
params.setWorkspaceId("YOUR_WORKSPACE_ID");
params.setDeviceName(mDeviceName);
params.setRequestTime(String.valueOf(System.currentTimeMillis()));
params.setPayMode(PayMode.LICENSE.getPayMode());
DeviceAuthClient.getInstance().deviceRegister(params, new DeviceRegisterCallBack() {
@Override
public void success() {
Log.d(TAG, "deviceRegister success");
}
@Override
public void fail(ResultError error) {
Log.e(TAG, error.getMessage());
}
});3.3.3. Get a service token: getToken
Parameters:
Parameter | Type | Default | Required | Description |
params | Object | - | Yes | Parameters for device authentication. See the |
callBack | GetTokenCallBack | - | Yes | A callback that receives the result of the token request. For details, see the |
GenGetTokenParams object
Parameter | Type | Default | Required | Description |
nonce | String | - | Yes | A 26-character nonce. |
appId | String | - | Yes | The App ID. Obtain this ID by creating an application in the Model Studio console. |
apiKey | String | - | Yes | The API key. Create it in Key Management in the Model Studio console. |
deviceName | String | - | Yes | The unique device identifier. Obtain this identifier by calling the |
requestTime | String | - | Yes | The request timestamp, in milliseconds. |
payMode | String | - | Yes | The billing method. Valid values: |
tokenType | String | - | Yes | The type of token to request. Currently, only
|
Return value:
None.
Example:
GenGetTokenParams params = new GenGetTokenParams();
params.setNonce(RandomUtil.generateRandomHexString(26));
params.setAppId("YOUR_APP_ID");
params.setDeviceName(mDeviceName);
params.setRequestTime(String.valueOf(System.currentTimeMillis()));
params.setPayMode(PayMode.LICENSE.getPayMode());
params.setTokenType("MMI");
DeviceAuthClient.getInstance().getToken(params, new GetTokenCallBack() {
@Override
public void success(String tokenInfo) {
Log.d(TAG, "getToken success: " + tokenInfo);
}
@Override
public void fail(ResultError error) {
Log.e(TAG, error.getMessage());
}
});3.4. Get license signature
Input parameters:
Parameter | Type | Default | Required | Description |
params | Object | - | Yes | The parameter object for device authentication. See |
The LicenseSignatureParams object
Parameter | Type | Default | Required | Description |
appId | String | - | Yes | This ID is generated when you create an application in the Model Studio console. |
deviceName | String | - | Yes | The unique device identifier. To obtain this identifier, call the |
taskId | String | - | Yes | A unique identifier for the current connection, generated by the client to track task execution in the engineering pipeline. The recommended format is a 36-character UUID string, for example, |
Output parameters:
Parameter | Type | Default | Description |
timestamp | String | - | The current timestamp, in milliseconds. |
license_info | String | - | The generated signature for license information. |
device_info | String | - | The generated signature for device information. |
Code sample:
/// Get the license signature
String taskId = UUID.randomUUID().toString().replace("-", "");
LicenseSignatureParams params = new LicenseSignatureParams(authParams.getAppid(), deviceName, taskId);
JSONObject licenseInfoSignature = DeviceAuthClient.getInstance().getLicenseSignature(params);
// Returns a JSON object containing the timestamp, license_info, and device_info.
3.5. Device reset: deviceReset
Tip: After resetting a device in the Model Studio console, call the deviceReset API. You can then register the device again.
Parameters:
None.
Return value:
A boolean: true if the device was reset successfully, or false otherwise.
Code sample:
boolean result = DeviceAuthClient.getInstance().deviceReset();
if (!result) {
showToast("Failed to reset the device.");
} else {
showToast("Device reset successful. You can now register it again.");
}4. Integrate dependency library
Reference the multimodal_dialog_tongyimetathings-1.0.5.aar file from the latest Android SDK.
5. Multimodal SDK integration
Before you start a session, initialize the tongyimetathings SDK and check if the device is registered. If not, register the device. For more information, see the sample integration project.
After device registration is complete, obtain a multimodal session token. For more information, see the APIs in sections 2.1 and 2.3. Set the apiKey to the dashToken returned by the getToken API. For more information, see the sample project.
multimodalParams.setApiKey(jsonObject.getString("dashToken"));When you create a session, pass the license billing identifier. For example:
private MultiModalRequestParam buildRequestParams() {
MultiModalRequestParam.UpStream.ReplaceWord replaceWord = new MultiModalRequestParam.UpStream.ReplaceWord();
replaceWord.setTarget("one plus one");
replaceWord.setSource("1 plus 1");
replaceWord.setMatchMode("partial");
String deviceName = DeviceUUIDUtil.getAndroidId(this); // Note: This uses the default SDK path for storage. The commented-out line shows how to specify a custom path.
//String deviceName = DeviceUUIDUtil.getAndroidId(this,"your_custom_absolute_path")
taskId = UUID.randomUUID().toString().replace("-", "");
// Build the license billing identifier
LicenseSignatureParams params = new LicenseSignatureParams(authParams.getAppid(), deviceName, taskId);
JSONObject licenseInfoSignature = DeviceAuthClient.getInstance().getLicenseSignature(params);
Map<String, Object> map = new HashMap<>();
map.put("signature", licenseInfoSignature);
return MultiModalRequestParam.builder()
.clientInfo(MultiModalRequestParam.ClientInfo.builder()
.device(MultiModalRequestParam.ClientInfo.Device.builder()
.uuid(deviceName).build()) // Set this to your device UUID
.userId("123") // The userId must be unique for each user and is used to track conversation history. We recommend using the device UUID.
.passThroughParams(map) // Pass the license billing identifier
.build())
.upStream(MultiModalRequestParam.UpStream.builder()
.mode(authParams.getDialogMode().getValue())
.type("AudioAndVideo")
.asrPostProcessing(Collections.singletonList(replaceWord))
.build())
.downStream(MultiModalRequestParam.DownStream.builder()
.voice(mVoiceType) // The voice specified here must match the voice model configured in the console. For example, longxiaochun_v2 corresponds to cosyvoice_v2.
.sampleRate(48000)
.intermediateText(textStreamFeedback ? "dialog" : "transcript")
.build())
.build();
}