1. 程式人生 > >android.view.WindowManager$BadTokenException: Unable to add window-permission denied 完美相容8.0的系統

android.view.WindowManager$BadTokenException: Unable to add window-permission denied 完美相容8.0的系統

問題,從問題反饋看就是 window type許可權拒絕導致,我的dialog設定的type為
mWindow.setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
安卓6.0及以後該許可權需要手動申請,且清單檔案註冊該許可權
第一步:

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

第二步:手動在程式碼申請,程式碼如下

  if (Build.VERSION.SDK_INT >= 23) {
            if
(! Settings.canDrawOverlays(this)) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); this.startActivityForResult(intent,10); } } @Override protected
void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 10) { if (Build.VERSION.SDK_INT >= 23) { if (!Settings.canDrawOverlays(this)) { // SYSTEM_ALERT_WINDOW permission not granted... Log.d(TAG, "onActivityResult: not granted"
); Toast.makeText(MainActivity.this,"not granted",Toast.LENGTH_SHORT); //需要等待許可權成功後 }else { //執行dialog的顯示 dialog.show(); } } } }

第三步:判定系統是否為8.0,需要對8.0做適配。否則8.0系統手機會奔潰的,無法顯示dialog

if (Build.VERSION.SDK_INT>=26){//8.0以後dialog的type型別需要用這個,而且非系統app也建議用它
                mWindow.setType((WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY));
            }else {
                mWindow.setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
            }

最後總結注意事項:
第一點:正常情況申請許可權成功後才能呼叫diaolog.show方法,否則會crash掉。
第二點:8.0的系統對type型別的許可權拒絕,所以對於8.0以後的系統需要進一步判定:
完成後既可以實現8.0之前的系統也可以對8.0系統都做了相容,具體效果如下顯示:
這裡寫圖片描述