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

Android Service悬浮窗交互触发WindowManager$BadTokenException问题求助

解决方案

1. 修复全局Context获取逻辑

你手动实例化MyApp()获取Context的方式完全错误:Application类由Android系统自动创建并初始化,你自己new的实例不会走onCreate生命周期,内部的context永远为空。

第一步:修改MyApp代码

class MyApp: Application() {
    companion object {
        // 全局单例实例,由系统初始化后赋值
        lateinit var instance: MyApp
    }
    lateinit var appContext: Context
    override fun onCreate() {
        super.onCreate()
        instance = this
        appContext = applicationContext
    }
}

第二步:配置AndroidManifest.xml

在<application>标签中添加属性,让系统加载你自定义的Application类:

<application
    android:name=".MyApp"
    ...其他原有配置>
    ...其他组件配置
</application>

第三步:移除错误的Context赋值

删除Service中context = MyApp().getContext()这行代码,需要Context的地方直接用this@Dooa(Service本身就是Context子类)或者MyApp.instance.appContext即可。

2. 修复Dialog弹窗的Window配置

错误栈明确指向Spinner点击弹下拉Dialog、DatePickerDialog弹框时触发崩溃,原因是普通Dialog默认依赖Activity的WindowToken,Service没有对应的Activity token,你需要给所有在悬浮窗中触发的Dialog设置和悬浮窗同等级的Window类型:

处理DatePickerDialog

在dpd.show()之前添加Window类型配置:

val dpd = DatePickerDialog(...)
// 添加这行配置
dpd.window?.setType(
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
    else
        WindowManager.LayoutParams.TYPE_TOAST
)
dpd.show()

处理Spinner下拉弹窗

Spinner默认的下拉弹窗为Dialog模式,在Service场景下会缺少WindowToken,你可以直接在布局文件中给所有Spinner设置为下拉模式,避免弹Dialog:

<Spinner
    android:id="@+id/spinnerAccount"
    ...其他原有属性
    android:spinnerMode="dropdown"
    android:dropDownVerticalOffset="40dp" />

3. 修复悬浮窗LayoutParams的Flag赋值错误

你在etTitle的触摸监听中Flag赋值逻辑错误,第二行赋值直接覆盖了第一行的配置,改成叠加Flag:

// 错误写法
updatedFloatParamsFlag.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
updatedFloatParamsFlag.flags = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE

// 正确写法
updatedFloatParamsFlag.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
        WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
        WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE

4. 权限校验

确保你已经做了如下权限配置:

  • 在AndroidManifest.xml中添加权限:
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    
  • Android 6.0及以上版本,提前引导用户手动开启「显示在其他应用上层」的特殊权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:45:10