.NET MAUI:如何确保 Android 平台特定代码仅在支持的 Android 版本上执行?

Jul*_*ian 7 c# android conditional-compilation android-api-levels maui

我有各种实现来partial class DeviceServices为 Android、iOS 等提供某些设备或操作系统特定功能的平台特定实现。我的应用程序的目标 API 级别为 33.0,最低版本为 API 级别 21.0。

某些 API 特定于某些 Android 版本及更高版本,因此我想确保仅在受支持的版本上调用它们。但是,我总是收到以下警告(以及类似的警告,具体取决于所使用的 API):

警告 CA1416:可在“Android”21.0 及更高版本上访问此调用站点。“WindowInsets.Type.SystemBars()”仅支持:“android”30.0 及更高版本。

以下隐藏和显示系统栏的代码适用于我迄今为止尝试过的所有设备和模拟器,但我担心早期的 Android 版本。尽管检查了正确的目标 API 版本,我仍然收到上面的警告:

static partial class DeviceServices
{
    private static Activity _activity;

    public static void SetActivity(Activity activity)
    {
        _activity = activity;
    }

    public static partial void HideSystemControls()
    {
#if ANDROID30_0_OR_GREATER
       if (Build.VERSION.SdkInt >= BuildVersionCodes.R) //R == API level 30.0
       {
            _activity?.Window?.InsetsController?.Hide(WindowInsets.Type.SystemBars());
       }
#endif
    }

    public static partial void ShowSystemControls()
    {
#if ANDROID30_0_OR_GREATER
       if (Build.VERSION.SdkInt >= BuildVersionCodes.R) //R == API level 30.0
       {
            _activity?.Window?.InsetsController?.Show(WindowInsets.Type.SystemBars());
       }
#endif
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,这样做的正确方法是什么?我不知道如何继续。我已经多次使用特定于平台的 API,以前从未遇到过任何问题,但这个警告让我感到担忧。我也已经看过有关此警告的支持文章,但我发现它不是很有帮助:https ://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules /ca1416。我也不想压制警告。也许我在这里遗漏了一些东西,或者我可以在这种情况下忽略警告吗?

更新:

我正在使用 Visual Studio 2022 17.4 Preview 2.1 和 .NET 7.0 RC1。

我还尝试直接从 内部调用 API MainActivity,但在重建后继续收到相同的警告。

更新2:

这是一个示例存储库,可以在其中重现问题,只需在MainActivity.cs文件中取消注释以下代码块即可:

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        
//#if ANDROID30_0_OR_GREATER
//        if (Build.VERSION.SdkInt >= BuildVersionCodes.R) //R == API level 30.0
//        {
//            Window?.InsetsController?.Hide(WindowInsets.Type.SystemBars());
//        }
//#endif
    }
Run Code Online (Sandbox Code Playgroud)

PEK*_*PEK 12

使用OperatingSystem.IsAndroidVersionAtLeast, 代替Build.VERSION.SdkInt. 像这样:

if (OperatingSystem.IsAndroidVersionAtLeast(30))
{
    _activity?.Window?.InsetsController?.Hide(WindowInsets.Type.SystemBars());
}
Run Code Online (Sandbox Code Playgroud)

此后您应该不会收到任何警告。

更多文档位于: https: //learn.microsoft.com/en-us/dotnet/api/system.operatingsystem.isandroidversionatleast


Jul*_*ian 0

我现在已经使用不同的 Android 模拟器和 API 版本进行了测试,到目前为止,尽管有警告,但没有实际问题。看起来它们是错误标志,可能是因为编译器不评估运行时检查。由于我不想明确禁用这些警告,因此我现在只能忽略它们。

更新

我已删除SetActivity()并切换为使用Microsoft.Maui.ApplicationModel.Platform.CurrentActivity,现在警告消失了:

using AndroidPlatform = Microsoft.Maui.ApplicationModel.Platform;

static partial class DeviceServices
{
    public static partial void HideSystemControls()
    {
       if (Build.VERSION.SdkInt >= BuildVersionCodes.R) //R == API level 30.0
       {
            AndroidPlatform.CurrentActivity?.Window?.InsetsController?.Hide(WindowInsets.Type.SystemBars());
       }
    }
}
Run Code Online (Sandbox Code Playgroud)