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

如何在Android14上用C# MVVM MAUI(.NET8)实现悬浮窗应用?

.NET MAUI Android14 全屏+悬浮窗切换实现指引

一、全屏模式实现

MAUI需针对Android平台做专属处理,核心在MainActivity中配置系统UI:

  • 打开Platforms/Android/MainActivity.cs,修改OnCreate方法,通过WindowInsetsController实现Android14适配的全屏:
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        // 移除布局限制,隐藏系统状态栏、刘海区域
        Window.SetFlags(WindowManagerFlags.LayoutNoLimits, WindowManagerFlags.LayoutNoLimits);
        Window.InsetsController?.Hide(WindowInsets.Type.SystemBars() | WindowInsets.Type.DisplayCutout());
        // 设置点击屏幕时隐藏系统UI(可选)
        Window.InsetsController?.SystemBarsBehavior = WindowInsetsControllerBehavior.HideWhenTapped;
    }
    
  • 同步在Platforms/Android/AndroidManifest.xml的theme中添加全屏配置:
    <style name="Maui.SplashTheme" parent="Theme.Maui.Splash">
        <!-- 其他配置 -->
        <item name="android:windowFullscreen">true</item>
    </style>
    

二、悬浮窗模式实现(Android14适配)

Android14对悬浮窗权限管控更严格,按以下步骤推进:

  1. 权限配置与申请
    • 在AndroidManifest.xml中添加必要权限:
      <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
      <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <!-- Android13+必需 -->
      
    • 运行时引导用户开启悬浮窗权限(该权限无法通过普通动态申请流程):
      // 在Android平台代码中调用
      if (!Android.Provider.Settings.CanDrawOverlays(this))
      {
          Intent intent = new Intent(Android.Provider.Settings.ActionManageOverlayPermission,
              Android.Net.Uri.Parse("package:" + PackageName));
          StartActivityForResult(intent, 1001);
      }
      
  2. 创建悬浮窗View
    • 使用Application上下文创建悬浮窗,避免依赖Activity生命周期:
      var windowManager = GetSystemService(Context.WindowService) as WindowManager;
      var layoutParams = new WindowManager.LayoutParams
      {
          Width = WindowManagerLayoutParams.WrapContent,
          Height = WindowManagerLayoutParams.WrapContent,
          Type = WindowManagerLayoutParams.TypeApplicationOverlay, // Android8.0+标准类型
          Flags = WindowManagerLayoutParams.FlagNotFocusable | WindowManagerLayoutParams.FlagLayoutInScreen,
          Format = Android.Graphics.Format.Translucent,
          Gravity = GravityFlags.Top | GravityFlags.Start
      };
      // 加载自定义悬浮窗布局(可提前在Resources/layout下创建FloatWindow.axml)
      var floatView = LayoutInflater.From(this).Inflate(Resource.Layout.FloatWindow, null);
      windowManager.AddView(floatView, layoutParams);
      
    • 若要复用MAUI的MVVM页面,可通过MauiContext将MAUI View转为Android原生View,减少重复代码。

三、上滑Home键触发切换逻辑

Android无直接监听上滑Home手势的API,结合HyperOS特性,采用以下方案:

  • 监听应用进入后台事件:在MAUI项目中订阅Application.Current.WillSleep事件,触发悬浮窗显示:
    Application.Current.WillSleep += (s, e) =>
    {
        MainThread.BeginInvokeOnMainThread(() =>
        {
            if (Android.Provider.Settings.CanDrawOverlays(Android.App.Application.Context))
            {
                ShowFloatWindow(); // 调用自定义的悬浮窗显示方法
                CurrentActivity?.MoveTaskToBack(true); // 将当前Activity移至后台
            }
        });
    };
    
  • 切换双向逻辑:全屏转悬浮窗时隐藏Activity、显示悬浮窗;悬浮窗转全屏时移除悬浮窗、重新唤起Activity并恢复全屏状态。

四、MVVM架构适配

结合你熟悉的MVVM模式,统一状态管理:

  • 创建全局AppStateViewModel,包含IsFullScreen、IsFloatWindowActive两个可绑定属性;
  • 在Android平台代码中订阅ViewModel的属性变化,自动触发对应UI操作(如设置全屏、显示/隐藏悬浮窗);
  • 悬浮窗的交互事件(如点击返回全屏)可通过Command绑定到ViewModel,保持MVVM架构一致性。

五、HyperOS与Android14特殊适配

  • 小米HyperOS可能需额外开启应用的「显示在其他应用上层」权限,可在代码中引导用户前往应用设置页开启;
  • Android14中TYPE_APPLICATION_OVERLAY窗口无法覆盖部分系统UI,需调整LayoutParams的Gravity和尺寸适配;
  • 测试时重点验证悬浮窗在后台的保活逻辑,HyperOS可能对后台窗口有额外管控。

内容的提问来源于stack exchange,提问作者Hưng Nguyễn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:30:27