Android 弹出自定义悬浮窗“permission denied for window type”报错处理

    技术2022-07-11  177

    在Android系统中,如果应用需要弹出一个悬浮窗口, 就需要申请一项特殊权限“android.permission.SYSTEM_ALERT_WINDOW”

    Android O之前 在Android O之前的系统中申请了该权限后,再给对应的window设置

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_PHONE; 悬浮窗口就可以显示出来。

    Android O及更高版本

    但是在Android O的系统中,google规定申请"android.permission.SYSTEM_ALERT_WINDOW" 权限的应用需要给悬浮窗口设置如下type:

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 悬浮窗口才能显示出来,“TYPE_APPLICATION_OVERLAY”是重点。 如果不设置该TYPE,应用会Crash,报错如下(后面的2002表示设置的type为TYPE_PHONE): AndroidRuntime: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@c8d1f1a -- permission denied for window type 2002

    补充 另外说一下:申请android.permission.SYSTEM_ALERT_WINDOW权限

    不能使用  requestPermissions 方法。

    可以使用下面的方法:  

    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); intent.setData(Uri.parse("package:" + getPackageName())); startActivityForResult(intent, GET_DIALOG_PERMISSION);//GET_DIALOG_PERMISSION为预先定义好的返回结果常量

    然后,在onActivityResult(int requestCode, int resultCode, Intent data) 回调函数中处理,之后的操作(再次调用弹窗,就会显示)。

    例如:

     try {             showAskDialog();//对应弹框逻辑方法         }         catch (Exception e)         {             Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);             intent.setData(Uri.parse("package:" + getPackageName()));             startActivityForResult(intent, GET_DIALOG_PERMISSION);//GET_DIALOG_PERMISSION为预先定义好的返回结果常量         }      @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {         super.onActivityResult(requestCode, resultCode, data);         if(requestCode == GET_DIALOG_PERMISSION)//GET_DIALOG_PERMISSION为预先定义好的返回结果常量         {             showAskDialog();//对应弹框逻辑方法         } }  

    Processed: 0.009, SQL: 9