如何使用Xamarin(Android)将VCard添加到手机通讯录?
安卓平台最新添加联系人/导入VCard实现方案
旧代码的过时点说明
Forms.Context已在Xamarin.Forms 2.5及后续版本标记为过时,MAUI中已完全移除,需要使用平台API获取当前活跃Activity- 原有实现将网址存入备注字段属于临时兼容方案,安卓通讯录提供了专门的网站字段可直接映射
- 直接导入VCard的场景原有逻辑没有覆盖,需要单独调用系统VCard解析入口
方案1:手动构造联系人信息(含正确网址字段)插入通讯录
注:本方案调用系统通讯录应用完成操作,应用本身不需要申请
WRITE_CONTACTS权限
Xamarin.Forms 最新实现
依赖Xamarin.Essentials获取当前活跃Activity,代码如下:
using Android.Content; using Android.Provider; using Xamarin.Essentials; using Toast = Android.Widget.Toast; using ToastLength = Android.Widget.ToastLength; public void SaveContact(string name, string number, string email, string company, string jobTitle, string postal, string website) { var intent = new Intent(Intent.ActionInsert); intent.SetType(ContactsContract.Contacts.ContentType); // 写入基础联系人字段 intent.PutExtra(ContactsContract.Intents.Insert.Name, name); intent.PutExtra(ContactsContract.Intents.Insert.Phone, number); intent.PutExtra(ContactsContract.Intents.Insert.Email, email); intent.PutExtra(ContactsContract.Intents.Insert.Company, company); intent.PutExtra(ContactsContract.Intents.Insert.JobTitle, jobTitle); intent.PutExtra(ContactsContract.Intents.Insert.Postal, postal); // 写入专属网址字段,不再存入备注 if (!string.IsNullOrEmpty(website)) { intent.PutExtra(ContactsContract.Intents.Insert.Data, website); intent.PutExtra(ContactsContract.Intents.Insert.DataMimetype, ContactsContract.CommonDataKinds.Website.ContentItemType); } // 启动系统通讯录添加页 var currentActivity = Platform.CurrentActivity; currentActivity.StartActivity(intent); Toast.MakeText(currentActivity, "联系人已保存", ToastLength.Short).Show(); }
MAUI 实现
MAUI中直接使用MAUI Essentials提供的上下文接口即可:
using Android.Content; using Android.Provider; using Android.Widget; using Microsoft.Maui.ApplicationModel; public void SaveContact(string name, string number, string email, string company, string jobTitle, string postal, string website) { var intent = new Intent(Intent.ActionInsert); intent.SetType(ContactsContract.Contacts.ContentType); intent.PutExtra(ContactsContract.Intents.Insert.Name, name); intent.PutExtra(ContactsContract.Intents.Insert.Phone, number); intent.PutExtra(ContactsContract.Intents.Insert.Email, email); intent.PutExtra(ContactsContract.Intents.Insert.Company, company); intent.PutExtra(ContactsContract.Intents.Insert.JobTitle, jobTitle); intent.PutExtra(ContactsContract.Intents.Insert.Postal, postal); if (!string.IsNullOrEmpty(website)) { intent.PutExtra(ContactsContract.Intents.Insert.Data, website); intent.PutExtra(ContactsContract.Intents.Insert.DataMimetype, ContactsContract.CommonDataKinds.Website.ContentItemType); } var currentActivity = Platform.CurrentActivity; currentActivity.StartActivity(intent); Toast.MakeText(currentActivity, "联系人已保存", ToastLength.Short).Show(); }
方案2:直接导入VCard(.vcf)文件到通讯录
如果已经有生成好的VCard文件,可以直接调用系统的VCard解析导入逻辑,不需要手动拆分字段:
/// <param name="vcfFilePath">本地VCard文件的绝对路径</param> public void ImportVCard(string vcfFilePath) { Android.Net.Uri vcfUri; // 安卓7.0+需要用FileProvider生成文件Uri,避免FileUriExposedException if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N) { vcfUri = Android.Support.V4.Content.FileProvider.GetUriForFile( Platform.CurrentActivity, $"{Platform.CurrentActivity.PackageName}.fileprovider", new Java.IO.File(vcfFilePath) ); } else { vcfUri = Android.Net.Uri.FromFile(new Java.IO.File(vcfFilePath)); } var intent = new Intent(Intent.ActionView); intent.SetDataAndType(vcfUri, "text/x-vcard"); intent.AddFlags(ActivityFlags.GrantReadUriPermission); intent.SetFlags(ActivityFlags.NewTask); Platform.CurrentActivity.StartActivity(intent); }
注:本方案需要申请对应版本的文件读取权限,安卓13+需要申请
READ_MEDIA_IMAGES权限,更低版本需要申请READ_EXTERNAL_STORAGE权限
内容的提问来源于stack exchange,提问作者KarsaOrlong1981
相关产品推荐
相关产品推荐

