# OTA
# 检查更新
HTTP Method:POST
请求地址:https://otav2.hivoice.cn/rest/v1/data/check_update
注意:所有参数的值都应进行URLEncode(UTF-8),参数值是数字或字母的可以不进行URLEncode。
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
appKey | String | Y | 应用KEY |
osType | String | Y | 应用所在操作系统类型,包括:Android、iOS、Linux、Windows等,比如当前开发的是Android的SDK,则osType=Android |
version | Integer | Y | 当前版本号 |
targetVersion | Integer | N | 目标版本号 |
timestamp | String | Y | 访问时间戳,Unix时间戳 |
udid | String | N | 设备唯一标识 |
channelCode | String | N | 渠道编号 |
pkgName | String | N | 包名 |
hardwareType | String | N | 硬件类型 |
gps | String | N | GPS数据,数据格式:经度,纬度,如:116.41667,39.91667 |
signature | String | Y | 数据签名 |
返回值
参数 | 类型 | 必填 | 描述 |
---|---|---|---|
returnCode | String | Y | 响应code,具体见错误码定义 |
message | String | Y | 响应描述 |
costTime | Integer | Y | 响应时间,单位:毫秒 |
result | Object | Y | 返回的结果数据 |
└config | String | Y | 版本配置信息 |
└downloadUrl | String | Y | 新版本数据的下载URL |
└fileSize | String | Y | 文件大小,单位:byte |
└version | String | Y | 当前新版本的版本号 |
└md5 | String | Y | 当前新版本数据的MD5值 |
└releaseNote | String | Y | 版本更新日志 |
└updateType | String | Y | 更新类型,包括(0:普通更新、1:强制更新:、2:强制静默更新) |
返回结果示例:
{
"returnCode": "0001",
"message": "有新版本",
"costTime": 259,
"result": {
"config": "{\"name\": \"haha\"}",
"downloadUrl": "http://10.30.100.1/g1/M00/07/C9/Ch5kAleM0rKAdx5_AB1tRUtE7TA470.pdf",
"fileSize": 1928517,
"version": 10,
"md5": "44b8aeaea16e093a370150a4911ce4c9",
"releaseNote": "releaseNote",
"updateType": 0
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 检查更新签名规则
A)将所有请求参数的值放入List中,注意:计算sign时所有参数不应进行URLEncode;
B)将格式化后的参数以字典序升序排列,拼接在一起,注意字典序中大写字母在前,空值(null)使用空字符串代替;
C)将B形成字符串获取SHA1摘要,形成一个40位的十六进制(字母大写)字符串,即为本次请求signature(签名)的值;
public String buildOtaSignature(OtaRequestVO reqVO) {
List<String> params = new ArrayList<String>();
params.add(reqVO.getAppKey());
params.add(reqVO.getOsType());
params.add(String.valueOf(reqVO.getVersion()));
params.add(String.valueOf(reqVO.getTimestamp()));
params.add(reqVO.getUdid());
params.add(reqVO.getChannelCode());
params.add(reqVO.getPkgName());
params.add(reqVO.getHardwareType());
params.add(reqVO.getGps());
if(reqVO.getTargetVersion()>0){
params.add(String.valueOf(reqVO.getTargetVersion()));
}
String signature = buildSignature(params);
logger.debug("generated signature: " + signature);
return signature;
}
/**
* 对参数列表构造响应签名
*
* @param params
* @return
*/
public static String buildSignature(List<String> params) {
if (params == null || params.isEmpty()) {
return "";
}
// 升序排序参数值
Collections.sort(params);
StringBuilder sb = new StringBuilder();
for (String param : params) {
sb.append(param == null ? "" : param);
}
return getSHA1Digest(sb.toString());
}
/**
* 将字符串进行SHA1获取摘要,摘要为十六进制字符串
*
* @param data
* @return
* @throws Exception
*/
public static String getSHA1Digest(String data) {
String digest = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] bytes = md.digest(data.getBytes("UTF-8"));
digest = byte2hex(bytes);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return digest;
}
/**
* 二进制转十六进制字符串
*
* @param bytes
* @return
*/
private static String byte2hex(byte[] bytes) {
StringBuilder sign = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(bytes[i] & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
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
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
# 错误码定义及描述
returnCode | message | 描述 |
---|---|---|
0000 | 没有更新 | 没有找到要更新的数据包 |
0001 | 有更新 | |
1000 | 请求时间戳超出了请求有效期 | 设备端时间和当前时间的差值绝对值不能超过10分钟 |
1001 | 签名错误 | |
9999 | 其他错误 | 联系管理员 |