You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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过时异常修复

问题根源

  1. 权限未申请:ABAddressBookErrorDomain error 1表示通讯录权限未授权或未申请,iOS要求明确获取用户授权才能访问通讯录。
  2. API废弃:AddressBook框架在iOS 9之后已被官方废弃,推荐使用新版Contacts框架。

修复步骤

  1. 添加权限描述:在iOS项目的Info.plist中添加权限说明:
<key>NSContactsUsageDescription</key>
<string>需要访问通讯录以保存联系人信息</string>
  1. 替换为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:33:18