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

如何在.NET Standard多平台中获取设备名,Android无需引用Xamarin包

解决Android环境下.NET Standard库获取设备名称的问题

好问题!我之前在开发跨平台.NET库的时候也遇到过一模一样的困扰——不想引入Xamarin依赖,但又要在Android上拿到真实的设备名称而不是默认的"localhost"。这里有个靠谱的方案,完全不需要引用任何Xamarin相关包:

利用反射调用Android原生API

Android运行时本身就提供了获取设备信息的系统类,我们可以通过反射在运行时访问这些类,不用提前引用Xamarin的NuGet包(毕竟你的库在Android环境运行时,CLR已经能访问这些Android原生类型了)。

下面是完整的实现代码,包含异常处理和降级方案:

public static string GetDeviceName()
{
    // 先判断当前是否在Android环境运行
    var osDescription = System.Runtime.InteropServices.RuntimeInformation.OSDescription;
    if (!osDescription.Contains("Android"))
    {
        // 非Android平台直接用Environment.MachineName
        return Environment.MachineName;
    }

    try
    {
        // 优先尝试获取用户设置的设备名称(Settings.Secure.DEVICE_NAME)
        var settingsType = Type.GetType("Android.Provider.Settings, Mono.Android");
        var secureNestedType = settingsType?.GetNestedType("Secure");
        if (secureNestedType != null)
        {
            // 获取Application的Context实例
            var appType = Type.GetType("Android.App.Application, Mono.Android");
            var contextProp = appType?.GetProperty("Context");
            var context = contextProp?.GetValue(null);

            if (context != null)
            {
                var deviceNameField = secureNestedType.GetField("DEVICE_NAME");
                var getStringMethod = secureNestedType.GetMethod("GetString", 
                    new[] { Type.GetType("Android.Content.ContentResolver, Mono.Android"), typeof(string) });

                if (deviceNameField != null && getStringMethod != null)
                {
                    var deviceName = getStringMethod.Invoke(null, 
                        new[] { context, deviceNameField.GetValue(null) }) as string;
                    
                    if (!string.IsNullOrEmpty(deviceName))
                    {
                        return deviceName;
                    }
                }
            }
        }

        // 如果获取不到用户设置的名称,降级返回设备型号(Build.MODEL)
        var buildType = Type.GetType("Android.OS.Build, Mono.Android");
        var modelField = buildType?.GetField("MODEL");
        return modelField?.GetValue(null) as string ?? "localhost";
    }
    catch
    {
        // 所有异常情况都 fallback 到默认值
        return "localhost";
    }
}

为什么这个方案可行?

  • 完全不需要引用Xamarin.Android包:所有Android相关类型都是通过反射在运行时查找的,只有在Android环境下这些类型才会存在,其他平台不会执行这段逻辑。
  • 有降级机制:如果Android版本不支持DEVICE_NAME(比如旧版本系统),会自动返回设备型号,避免空值或异常。
  • 兼容你的多平台需求:非Android平台还是沿用Environment.MachineName,不影响.NET Framework 4等其他目标平台的行为。

注意事项

  • 反射调用要做好异常捕获:不同Android版本的API可能有细微差异,捕获异常能保证你的库在各种设备上都能稳定运行。
  • RuntimeInformation.OSDescription的判断是简单匹配,如果你需要更严谨的平台检测,可以结合RuntimeInformation.IsOSPlatform(不过对于Android,这个方法需要.NET Standard 2.1及以上支持,如果你要兼容.NET Framework 4,还是用字符串匹配更稳妥)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:54:26