android.view.WindowManager$BadTokenException: Unable to add window-permission denied 完美相容8.0的系統
阿新 • • 發佈:2019-01-31
問題,從問題反饋看就是 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系統都做了相容,具體效果如下顯示: