I need to distinguish between Android and Unix at runtime in a .NetStandard 2.0 library. The library must compile for .Net Standard so an #if ANDROID
solution is not suitable.
Environment.OSVersion returns Unix 3.18.14.12365438
on Android.
Other solutions like https://www.nuget.org/packages/Xam.Plugin.DeviceInfo/ wont work on Android because then the Mono Profile is missing at runtime and are only possible if the library is compiled for multiple targets.
Is there a way to detect this at runtime ?
You need something environmental.
Without getting into native shared libraries (.so
) and the permission issues, API differences, etc.. DLLImport
externs are not a great option.
An OS file existent can be troublesome due to sandboxing so File.Exists
should be avoided.
But Android does have a cmd getprop
that is available to any user (i.e. non-root), is always in the shell path and thus if it executes and returns a value you are on Android. Cheap but it works...
public static class AndroidTest
{
static bool? isAndroid;
public static bool Check()
{
if (isAndroid != null) return (bool)isAndroid;
using (var process = new System.Diagnostics.Process())
{
process.StartInfo.FileName = "getprop";
process.StartInfo.Arguments = "ro.build.user";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
try
{
process.Start();
var output = process.StandardOutput.ReadToEnd();
isAndroid = string.IsNullOrEmpty(output) ? (bool?)false : (bool?)true;
}
catch
{
isAndroid = false;
}
return (bool)isAndroid;
}
}
}
Note: Of course someone could spoof a getprop
cmd and its return value to fool this, or any other environmental check, but unless you have access to Android native APIs and have a desire to stay 100% portable, I do not see a way around it...