MAUI通过条件编译保存联系人至设备遇异常求助
解决MAUI中保存联系人到本地的异常问题
Android平台空引用异常修复
问题根源
Android.App.Application.Context as Activity转换失败——Application级别的Context并非Activity实例,导致activity变量为null,调用StartActivity时触发空引用异常。
修复代码
替换原Android平台代码,使用MAUI提供的Platform.CurrentActivity获取当前活跃Activity,同时处理Activity为空的边界情况:
#if ANDROID using Microsoft.Maui.ApplicationModel.Platform; using Android.OS; // ... var activity = Platform.CurrentActivity; if (activity == null) { // 延迟获取主线程的Activity new Handler(Looper.MainLooper).Post(() => { var currentActivity = Platform.CurrentActivity; currentActivity?.RunOnUiThread(() => LaunchContactIntent(currentActivity, Name, Number, Email)); }); return; } activity.RunOnUiThread(() => LaunchContactIntent(activity, Name, Number, Email)); // 提取独立方法处理Intent启动 private void LaunchContactIntent(Activity activity, string name, string number, string email) { var intent = new Intent(Intent.ActionInsert) .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); activity.StartActivity(intent); } #endif
iOS平台权限与API过时异常修复
问题根源
- 权限未申请:
ABAddressBookErrorDomain error 1表示通讯录权限未授权或未申请,iOS要求明确获取用户授权才能访问通讯录。 - API废弃:
AddressBook框架在iOS 9之后已被官方废弃,推荐使用新版Contacts框架。
修复步骤
- 添加权限描述:在iOS项目的
Info.plist中添加权限说明:
<key>NSContactsUsageDescription</key> <string>需要访问通讯录以保存联系人信息</string>
- 替换为Contacts框架实现:
#if IOS using Contacts; using Foundation; using System.Threading.Tasks; // ... var store = new CNContactStore(); var status = CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts); // 首次请求权限 if (status == CNAuthorizationStatus.NotDetermined) { var tcs = new TaskCompletionSource<CNAuthorizationStatus>(); store.RequestAccess(CNEntityType.Contacts, (granted, error) => { tcs.SetResult(granted ? CNAuthorizationStatus.Authorized : CNAuthorizationStatus.Denied); }); status = await tcs.Task; } // 权限未授权时直接返回 if (status != CNAuthorizationStatus.Authorized) { // 可添加提示用户去设置开启权限的逻辑 return; } // 创建并保存联系人 var contact = new CNMutableContact(); contact.GivenName = Name; // 添加手机号 var phoneNumber = new CNPhoneNumber(Number); contact.PhoneNumbers = new CNLabeledValue<CNPhoneNumber>[] { new CNLabeledValue<CNPhoneNumber>(CNLabelPhoneNumberKey.Mobile, phoneNumber) }; // 添加邮箱(可选) if (!string.IsNullOrEmpty(Email)) { contact.EmailAddresses = new CNLabeledValue<NSString>[] { new CNLabeledValue<NSString>(CNLabelHome, new NSString(Email)) }; } var saveRequest = new CNSaveRequest(); saveRequest.AddContact(contact, store.DefaultContainerIdentifier); try { await store.ExecuteSaveRequestAsync(saveRequest); } catch (NSErrorException) { // 处理保存失败的异常 } #endif
完整修正后的SaveContact类
using System.Threading.Tasks; #if ANDROID using Android.App; using Android.Content; using Android.OS; using Android.Provider; using Microsoft.Maui.ApplicationModel.Platform; #elif IOS using Contacts; using Foundation; #endif namespace MyApp.Renderers { public class SaveContact { public async Task SaveContactToPhoneBook(string Name, string Number, string Email) { #if ANDROID var activity = Platform.CurrentActivity; if (activity == null) { new Handler(Looper.MainLooper).Post(() => { var currentActivity = Platform.CurrentActivity; currentActivity?.RunOnUiThread(() => LaunchContactIntent(currentActivity, Name, Number, Email)); }); return; } activity.RunOnUiThread(() => LaunchContactIntent(activity, Name, Number, Email)); #elif IOS var store = new CNContactStore(); var status = CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts); if (status == CNAuthorizationStatus.NotDetermined) { var tcs = new TaskCompletionSource<CNAuthorizationStatus>(); store.RequestAccess(CNEntityType.Contacts, (granted, error) => { tcs.SetResult(granted ? CNAuthorizationStatus.Authorized : CNAuthorizationStatus.Denied); }); status = await tcs.Task; } if (status != CNAuthorizationStatus.Authorized) { // 提示用户开启权限的逻辑可在此添加 return; } var contact = new CNMutableContact(); contact.GivenName = Name; var phoneNumber = new CNPhoneNumber(Number); contact.PhoneNumbers = new CNLabeledValue<CNPhoneNumber>[] { new CNLabeledValue<CNPhoneNumber>(CNLabelPhoneNumberKey.Mobile, phoneNumber) }; if (!string.IsNullOrEmpty(Email)) { contact.EmailAddresses = new CNLabeledValue<NSString>[] { new CNLabeledValue<NSString>(CNLabelHome, new NSString(Email)) }; } var saveRequest = new CNSaveRequest(); saveRequest.AddContact(contact, store.DefaultContainerIdentifier); try { await store.ExecuteSaveRequestAsync(saveRequest); } catch (NSErrorException) { // 处理保存异常 } #endif } #if ANDROID private void LaunchContactIntent(Activity activity, string name, string number, string email) { var intent = new Intent(Intent.ActionInsert) .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); activity.StartActivity(intent); } #endif } }
调用方式调整(适配异步方法)
SaveContact saveContact = new SaveContact(); await saveContact.SaveContactToPhoneBook("", phone, "");
内容的提问来源于stack exchange,提问作者Matthew Pans
相关产品推荐
相关产品推荐

