145 lines
2.9 KiB
Markdown
145 lines
2.9 KiB
Markdown
# 联系人 JSON 数据组装说明
|
|||
|
|
|
||
|
|
## JSON 结构
|
||
|
|
|
||
|
|
最终组装为一个根对象,根对象下只有 `contact` 数组:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"contact": [
|
||
|
|
{
|
||
|
|
"name": "张三",
|
||
|
|
"number": "13800138000"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "李四",
|
||
|
|
"number": "+8613900139000"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
空联系人时返回:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"contact": []
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## 组装规则
|
||
|
|
|
||
|
|
1. 每个联系人 item 只包含两个字段:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"name": "联系人姓名",
|
||
|
|
"number": "联系人号码"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
2. 优先使用 `number_detail` 字段。
|
||
|
|
|
||
|
|
`number_detail` 是 JSON 数组字符串,用于表示同一个联系人下的多个号码,例如:
|
||
|
|
|
||
|
|
```json
|
||
|
|
["13800138000", "13900139000"]
|
||
|
|
```
|
||
|
|
|
||
|
|
3. 如果 `number_detail` 不为空,则解析其中每一个号码,并分别展开成独立联系人 item。
|
||
|
|
|
||
|
|
例如:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"name": "张三",
|
||
|
|
"number_detail": ["13800138000", "13900139000"]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
会组装为:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"contact": [
|
||
|
|
{
|
||
|
|
"name": "张三",
|
||
|
|
"number": "13800138000"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "张三",
|
||
|
|
"number": "13900139000"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
4. 如果 `number_detail` 为空,或者解析失败,则使用 `number` 字段兜底。
|
||
|
|
|
||
|
|
5. 号码为空时不加入数组。
|
||
|
|
|
||
|
|
6. 号码会做格式清洗,只去除以下字符:
|
||
|
|
|
||
|
|
```text
|
||
|
|
- 空格 ( )
|
||
|
|
```
|
||
|
|
|
||
|
|
保留数字和 `+`。
|
||
|
|
|
||
|
|
例如:
|
||
|
|
|
||
|
|
```text
|
||
|
|
+86 138-0013-8000 -> +8613800138000
|
||
|
|
138 0013 8000 -> 13800138000
|
||
|
|
```
|
||
|
|
|
||
|
|
7. 会按 `name + "|" + number` 去重,同一姓名同一号码只保留一条。
|
||
|
|
|
||
|
|
## 核心组装代码
|
||
|
|
|
||
|
|
```java
|
||
|
|
JSONArray contactArray = new JSONArray();
|
||
|
|
Set<String> uniqueKeys = new HashSet<>();
|
||
|
|
|
||
|
|
while (cursor.moveToNext()) {
|
||
|
|
String name = cursor.getString(idxName);
|
||
|
|
String number = cursor.getString(idxNumber);
|
||
|
|
String numberDetail = cursor.getString(idxNumberDetail);
|
||
|
|
|
||
|
|
if (!TextUtils.isEmpty(numberDetail)) {
|
||
|
|
try {
|
||
|
|
JSONArray numbers = new JSONArray(numberDetail);
|
||
|
|
for (int i = 0; i < numbers.length(); i++) {
|
||
|
|
addContactItem(contactArray, uniqueKeys, name, numbers.optString(i, ""));
|
||
|
|
}
|
||
|
|
} catch (Exception e) {
|
||
|
|
addContactItem(contactArray, uniqueKeys, name, number);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
addContactItem(contactArray, uniqueKeys, name, number);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
JSONObject root = new JSONObject();
|
||
|
|
root.put("contact", contactArray);
|
||
|
|
return root.toString();
|
||
|
|
```
|
||
|
|
|
||
|
|
```java
|
||
|
|
private void addContactItem(JSONArray contactArray, Set<String> uniqueKeys,
|
||
|
|
String name, String number) {
|
||
|
|
if (TextUtils.isEmpty(number)) return;
|
||
|
|
|
||
|
|
String formattedNumber = number.replaceAll("[-\\s()]", "");
|
||
|
|
if (TextUtils.isEmpty(formattedNumber)) return;
|
||
|
|
|
||
|
|
String key = (name == null ? "" : name) + "|" + formattedNumber;
|
||
|
|
if (uniqueKeys.contains(key)) return;
|
||
|
|
uniqueKeys.add(key);
|
||
|
|
|
||
|
|
JSONObject item = new JSONObject();
|
||
|
|
item.put("name", name);
|
||
|
|
item.put("number", formattedNumber);
|
||
|
|
contactArray.put(item);
|
||
|
|
}
|
||
|
|
```
|