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

Android WindowManager$BadTokenException权限问题求助(适配Oreo仍报错)

解决Android ViewRootImpl$W权限拒绝报错(WindowManager$BadTokenException)

问题回顾

你遇到的报错信息如下:

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@c745883 - permission denied

对应的栈追踪:

01-30 15:11:41.037 13010-13010/project.app E/AndroidRuntime: FATAL EXCEPTION: main Process: project.app, PID: 13010 android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@c745883 -- permission denied for window type 2003 at android.view.ViewRootImpl.setView(ViewRootImpl.java:789) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) at android.app.Dialog.show(Dialog.java:330) at com.facebook.react.devsupport.DevSupportManagerImpl$4.run(DevSupportManagerImpl.java:344) at android.os.Handler.handleCallback(Handler.java:790) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

你已经意识到TYPE_SYSTEM_ERROR在Android 8.0+被弃用,替换为TYPE_APPLICATION_OVERLAY,但依然报错。


问题根源

Android 8.0(API 26)开始,TYPE_APPLICATION_OVERLAY对应的**SYSTEM_ALERT_WINDOW权限升级为特殊权限**——它不能像普通权限那样通过代码弹窗请求,必须引导用户到系统设置中手动开启。你的代码只替换了窗口类型,但没有完成权限的检查与申请流程,所以系统依然拒绝添加窗口。


解决方案

1. 声明权限

首先在AndroidManifest.xml中添加权限声明(即使是特殊权限,这一步也不能省略):

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

2. 检查并申请特殊权限

添加权限检查方法,引导用户到设置页面开启权限:

private void checkOverlayPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // 判断是否已获取悬浮窗权限
        if (!Settings.canDrawOverlays(this)) {
            // 跳转到系统设置页面,让用户开启权限
            Intent overlayIntent = new Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getPackageName())
            );
            startActivityForResult(overlayIntent, 1001);
        } else {
            // 已获取权限,执行窗口初始化逻辑
            fixAndroid();
        }
    } else {
        // Android 6.0以下无需特殊处理,直接执行
        fixAndroid();
    }
}

3. 处理权限申请结果

重写onActivityResult方法,处理用户的权限选择:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1001) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.canDrawOverlays(this)) {
                // 用户同意权限,执行窗口逻辑
                fixAndroid();
            } else {
                // 用户拒绝权限,给出提示
                Toast.makeText(this, "需要开启悬浮窗权限才能正常使用调试功能", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

4. 调整初始化流程

修改onCreate方法,先检查权限再执行窗口初始化:

@Override
public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 优先检查权限
    checkOverlayPermission();
}

针对Expo Kit/React Native 0.48的额外说明

因为你的项目已经分离到Expo Kit,修改完上述代码后:

  • 务必清理项目缓存(执行./gradlew clean)
  • 在Android Studio中同步项目后再运行API 27的模拟器
  • 这个报错来自React Native的调试支持类DevSupportManagerImpl,说明调试弹窗需要悬浮窗权限,所以调试模式下必须确保权限已开启

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:31:00