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

MAUI依赖注入获取设备唯一ID失效及类找不到问题求助

MAUI移植后依赖注入获取设备ID为空且类型找不到问题

问题背景

Xamarin Forms项目中通过依赖注入获取设备唯一ID的代码运行正常,移植到MAUI后返回结果为空。尝试将依赖服务添加到DI容器时,又出现类型找不到的错误。

我的代码

IDevice 接口

public interface IDevice
{
    string GetIdentifier();
}

Android 实现

public class AndroidDevice : IDevice
{
    public string GetIdentifier()
    {
        return Android.Provider.Settings.Secure.GetString(Android.App.Application.Context.ContentResolver, Android.Provider.Settings.Secure.AndroidId);
    }
}

iOS 实现

public class IOSDevice : IDevice
{
    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern uint IOServiceGetMatchingService(uint masterPort, IntPtr matching);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern IntPtr IOServiceMatching(string s);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern IntPtr IORegistryEntryCreateCFProperty(uint entry, IntPtr key, IntPtr allocator, uint options);

    [DllImport("/System/Library/Frameworks/IOKit.framework/IOKit")]
    private static extern int IOObjectRelease(uint o);

    public string GetIdentifier()
    {
        string serial = string.Empty;
        uint platformExpert = IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice"));
        if (platformExpert != 0)
        {
            NSString key = (NSString)"IOPlatformSerialNumber";
            IntPtr serialNumber = IORegistryEntryCreateCFProperty(platformExpert, key.Handle, IntPtr.Zero, 0);
            if (serialNumber != IntPtr.Zero)
            {
                serial = NSString.FromHandle(serialNumber);
                //serial = UIDevice.CurrentDevice.IdentifierForVendor.ToString();
            }
            IOObjectRelease(platformExpert);
        }
        return serial;
    }
}

尝试操作及错误

我尝试在DI容器中添加服务:

.Services.AddTransient<IGetDeviceInfo, GetDeviceInfo>();

但出现错误提示:

找不到类型或命名空间名称“AndroidDevice”(是否缺少 using 指令或程序集引用?)

错误截图:
错误截图


解决方案

1. 修正DI注册的类型不匹配问题

你注册的IGetDeviceInfo、GetDeviceInfo和实际的IDevice、AndroidDevice/IOSDevice完全不对应,这是核心错误。需要按平台正确注册:

在MauiProgram.cs中用条件编译注册对应平台的实现:

var builder = MauiApp.CreateBuilder();
builder
    .UseMauiApp<App>()
    .ConfigureFonts(fonts =>
    {
        fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    });

// 按平台注册IDevice的具体实现
#if ANDROID
builder.Services.AddTransient<IDevice, AndroidDevice>();
#elif IOS
builder.Services.AddTransient<IDevice, IOSDevice>();
#endif

var app = builder.Build();
return app;

2. 调整平台代码的存放位置

MAUI不建议在共享项目中直接写平台特定代码(比如引用Android/iOS的API),建议将AndroidDevice放到Android项目中,IOSDevice放到iOS项目中,确保接口IDevice在共享项目。之后可以简化注册:

builder.Services.AddTransient<IDevice>();

MAUI会自动根据当前平台解析对应的实现。

3. 修复iOS设备ID获取逻辑

你当前通过IOKit获取序列号的方式在iOS 10+已经被苹果限制,无法正常获取,建议改用苹果官方允许的IdentifierForVendor:

public class IOSDevice : IDevice
{
    public string GetIdentifier()
    {
        return UIDevice.CurrentDevice.IdentifierForVendor?.ToString() ?? string.Empty;
    }
}

4. Android端权限检查

确保Android项目的AndroidManifest.xml中添加必要权限(Android 10+获取Android ID无需额外权限,但旧版本可能需要):

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

内容的提问来源于stack exchange,提问作者Sreejith Sree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 22:12:48