You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

安卓端导出联系人为VCF文件方法及扩展字段设置方案

我来帮你解决这两个关于安卓联系人导出VCF的问题:

一、安卓系统自带导出所有联系人到VCF的方法

如果你不需要自定义导出字段,直接用系统自带功能最方便:

  • 打开安卓设备上的「联系人」应用
  • 点击右上角的菜单按钮(通常是三个垂直点)
  • 在弹出的菜单中选择「导出/导入」选项(部分机型可能在「设置」子菜单里)
  • 选择「导出到存储设备」,确认保存路径后,系统会自动生成包含所有联系人完整信息的VCF文件
二、修改代码补充缺失的VCF字段

你的现有代码已经实现了基础字段的导出,下面我会根据VCF 3.0规范,帮你添加图片、生日、亲属关系等缺失字段,同时处理空值避免报错:

首先,需要添加一个工具方法将联系人图片转成Base64(VCF的PHOTO字段要求二进制数据用Base64编码):

private String getBase64FromBitmap(Bitmap bitmap) {
    if (bitmap == null) return null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, baos);
    byte[] imageBytes = baos.toByteArray();
    return Base64.encodeToString(imageBytes, Base64.DEFAULT);
}

然后修改你的导出代码,补充所有缺失字段:

Person p = getPerson();
File vcfFile = new File(this.getExternalFilesDir(null), "generated.vcf");
FileWriter fw = new FileWriter(vcfFile);
fw.write("BEGIN:VCARD\r\n");
fw.write("VERSION:3.0\r\n");
fw.write("N:" + p.getSurname() + ";" + p.getFirstName() + "\r\n");
fw.write("FN:" + p.getFirstName() + " " + p.getSurname() + "\r\n");
fw.write("ORG:" + p.getCompanyName() + "\r\n");
fw.write("TITLE:" + p.getTitle() + "\r\n");
fw.write("TEL;TYPE=WORK,VOICE:" + p.getWorkPhone() + "\r\n");
fw.write("TEL;TYPE=HOME,VOICE:" + p.getHomePhone() + "\r\n");
fw.write("ADR;TYPE=WORK:;;" + p.getStreet() + ";" + p.getCity() + ";" + p.getState() + ";" + p.getPostcode() + ";" + p.getCountry() + "\r\n");
fw.write("EMAIL;TYPE=PREF,INTERNET:" + p.getEmailAddress() + "\r\n");

// 1. 添加联系人图片(需确保Person类有获取头像Bitmap的方法,比如getAvatar())
String photoBase64 = getBase64FromBitmap(p.getAvatar());
if (photoBase64 != null) {
    fw.write("PHOTO;ENCODING=b;TYPE=JPEG:" + photoBase64 + "\r\n");
}

// 2. 添加生日(需确保Person类有获取生日的方法,这里假设返回Date类型,转成YYYY-MM-DD格式)
if (p.getBirthday() != null) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
    String birthdayStr = sdf.format(p.getBirthday());
    fw.write("BDAY:" + birthdayStr + "\r\n");
}

// 3. 添加亲属关系(示例为父亲、配偶,可根据需求扩展其他亲属类型)
if (p.getFatherName() != null && !p.getFatherName().isEmpty()) {
    fw.write("RELATED;TYPE=father:" + p.getFatherName() + "\r\n");
}
if (p.getSpouseName() != null && !p.getSpouseName().isEmpty()) {
    fw.write("RELATED;TYPE=spouse:" + p.getSpouseName() + "\r\n");
}

// 4. 添加助理信息(姓名用X-ASSISTANT,电话用TEL;TYPE=ASSISTANT)
if (p.getAssistantName() != null && !p.getAssistantName().isEmpty()) {
    fw.write("X-ASSISTANT:" + p.getAssistantName() + "\r\n");
}
if (p.getAssistantPhone() != null && !p.getAssistantPhone().isEmpty()) {
    fw.write("TEL;TYPE=ASSISTANT,VOICE:" + p.getAssistantPhone() + "\r\n");
}

// 5. 添加备注(替换换行符避免破坏VCF格式)
if (p.getNote() != null && !p.getNote().isEmpty()) {
    fw.write("NOTE:" + p.getNote().replace("\n", "\\n") + "\r\n");
}

// 6. 添加标签(多个标签用逗号分隔)
if (p.getCategories() != null && !p.getCategories().isEmpty()) {
    fw.write("CATEGORIES:" + String.join(",", p.getCategories()) + "\r\n");
}

// 7. 添加网站信息
if (p.getWebsite() != null && !p.getWebsite().isEmpty()) {
    fw.write("URL;TYPE=WORK:" + p.getWebsite() + "\r\n");
}

fw.write("END:VCARD\r\n");
fw.close();

Intent i = new Intent();
i.setAction(android.content.Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(vcfFile), "text/x-vcard");
startActivity(i);

注意事项:

  • 请确保你的Person类对应有获取这些字段的方法(比如getAvatar()getBirthday()等),如果字段名不同请自行调整
  • VCF字段对格式要求严格,比如生日必须是YYYY-MM-DD格式,备注里的换行符要替换成\n避免破坏VCF结构
  • 自定义字段(比如X-ASSISTANT)大部分通讯录应用都能识别,若需更标准的字段可参考VCF官方规范调整

内容的提问来源于stack exchange,提问作者Manoj Kumar

火山引擎 最新活动