如何在.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
相关产品推荐
相关产品推荐

