加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Android下Dialog及Activity屏蔽Home键分析

发布时间:2021-11-24 20:58:16 所属栏目:教程 来源:互联网
导读:屏蔽其他键,重写onKeyDown Java代码 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.i(TAG,keycode=+keyCode + isBan=+isBan); switch (keyCode) { case KeyEvent.KEYCODE_BACK: Log.i(TAG,KEYCODE_BACK); return true; } return

屏蔽其他键,重写onKeyDown
Java代码  
@Override  
public boolean onKeyDown(int keyCode, KeyEvent event) {  
    Log.i(TAG,"keycode="+keyCode + "   isBan="+isBan);  
    switch (keyCode) {  
        case KeyEvent.KEYCODE_BACK:  
        Log.i(TAG,"KEYCODE_BACK");  
        return true;  
    }  
    return super.onKeyDown(keyCode, event);  
}  
 
大家会发现,这里屏蔽Home键是捕捉不到的,因为大家的权限一般是User所以是无效的。
而其实Android处理Home键等系统级按键是有一定的处理的。
看看源码是怎样处理的 frameworkspoliciesbasephonecomandroidinternalpolicyimplPhoneWindowManager.java #1092
Java代码  
// First we always handle the home key here, so applications  
// can never break it, although if keyguard is on, we do let  
// it handle it, because that gives us the correct 5 second  
// timeout.  
if (code == KeyEvent.KEYCODE_HOME) {  
  
    // If a system window has focus, then it doesn't make sense  
    // right now to interact with applications.  
    WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;  
    if (attrs != null) {  
        final int type = attrs.type;  
        if (type == WindowManager.LayoutParams.TYPE_KEYGUARD  
           || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {  
            // the "app" is keyguard, so give it the key  
            return false;  
        }  
        final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;  
        for (int i=0; i<typeCount; i++) {  
            if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {  
                // don't do anything, but also don't pass it to the app  
                return true;  
            }  
        }  
    }  
 
通过源码,我们不难发现两个的参数 WindowManager.LayoutParams.TYPE_KEYGUARD和
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
借鉴于此,重写onAttachedToWindow,以实现屏蔽Home键
Java代码  
public void onAttachedToWindow() {  
    this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  
    super.onAttachedToWindow();  
}  
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 华丽的分界线- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
 
 
 
轮到dialog了,如果在Activity弹出dialog,在Activity设置以上2个方法是没办法屏蔽的。
其实,原理是一样的,只是地方不一样而已。
Java代码  
final Dialog dialog = new Dialog(this);  
dialog.setContentView(R.layout.mydailog);  
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  
dialog.show();  
  
dialog.setOnKeyListener(new android.content.DialogInterface.OnKeyListener(){  
    @Override  
    public boolean onKey(DialogInterface dialog, int keyCode,KeyEvent event) {  
        switch (keyCode) {  
            case KeyEvent.KEYCODE_BACK:  
            Log.i(TAG,"KEYCODE_BACK");  
            return true;  
        }  
        return false;  
    }  
});   
 
这样运行后,出错如下:
Error代码  
10-18 13:27:06.380: ERROR/AndroidRuntime(4684): Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRoot$W@2b046d68 -- permission denied for this window type  
 
其实,只需要把dialog.getWindow().setType的位置放在show后面就可以了
正确代码  
dialog.show();  
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  
 
这么,就完成了Back键的屏蔽 和Home键盘的屏蔽了!
 
总结:
1:)在以上用WindowManager.LayoutParams.TYPE_KEYGUARD的地方改用
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG 效果一样。至于两者的具体差别,得以后再研究研究。
 
2:)其实,在源码里是这样调用的。
Java代码  
final AlertDialog dialog = new AlertDialog.Builder(mContext)  
    .setTitle(null)  
    .setMessage(message)  
    .setNeutralButton(R.string.ok, null)  
    .create();  
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);  
dialog.show();  
 
    但我们如果这样调用就会出现之前的那个error:permission denied for this window type 这就显而易见了吧~~
 
3:)ProgressDialog 默认屏蔽 Back键,Dialog,AlertDialog则需setOnKeyListener
 
4:)其实屏蔽Home键,在页面的某个地方,例如一个Button的onClick里,去设置setType就可以了,如:
Java代码  
button.setOnClickListener(new View.OnClickListener() {  
    @Override  
    public void onClick(View v) {  
        getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);  
    }  
});  
 
但前提是重载Activity的onAttachedToWindow(),哪怕只是一个空实现,然后返回父类方法。
Java代码  
@Override    
public void onAttachedToWindow() {  
    super.onAttachedToWindow();  
}  
 
5:)其实它们,都是常用的~
Java代码  
switch (keyCode) {  
    case KeyEvent.KEYCODE_HOME:  
        Log.i(TAG,"KEYCODE_HOME");  
        return true;  
    case KeyEvent.KEYCODE_BACK:  
        Log.i(TAG,"KEYCODE_BACK");  
        return true;  
    case KeyEvent.KEYCODE_CALL:  
        Log.i(TAG,"KEYCODE_CALL");  
        return true;  
    case KeyEvent.KEYCODE_SYM:  
        Log.i(TAG,"KEYCODE_SYM");  
        return true;  
    case KeyEvent.KEYCODE_VOLUME_DOWN:  
        Log.i(TAG,"KEYCODE_VOLUME_DOWN");  
        return true;  
    case KeyEvent.KEYCODE_VOLUME_UP:  
        Log.i(TAG,"KEYCODE_VOLUME_UP");  
        return true;  
    case KeyEvent.KEYCODE_STAR:  
        Log.i(TAG,"KEYCODE_STAR");  
        return true;  
}

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读