一、前言

       由于我们是做金融相关的,对账户的密码输入为了安全,实现相应的保护测试,决定自己实现密码键盘替代系统的自带输入键盘。为什么要使用密码安全键盘呢,出于以下几个原因:

       1. 第三方的键盘输入密码, 这个密码会被输入法缓存起来, 不安全,完全暴露给第三方。
       2. 由于android的root过后,可以通过读取系统驱动层dev/input/event1中的信息,获取手机触屏的位置坐标等信息,从而获取相应的信息。
       我们出于上面两个原因我们可以使用自定义view实现或者通过popwindow、dialog等实现密码键盘,这个看大家自由选择。虽然这种做法是自定义的软键盘,依然会在event1文件中写入触摸信息,因此为了保证输入更加安全,采用随机键盘。做出的一个样子大概是这样的,先给大家看看效果。

       

       这个界面有点丑,不过今天的重点不是界面,而是功能。

二、实现密码键盘

1.关键问题

       实现密码键盘我们首先有以下几个问题解决,其它的问题都是小问题:
       1.实现0-9数字随机排列
       2.关闭系统键盘,在输入密码的时候禁止弹出
       3.如果输入框在下面,弹出的密码键盘挡住了输入框,如何像系统键盘一样将布局上移,键盘在输入框的下方

       我们先看看上面的几个问题,实现数字随机排列然后并赋值到按钮上,这个还是相对简单,我们取10个随机数,从0-9中取,并不能出现重复的数字,然后赋值即可:

 private int[] getRandomNum() {        Random random = new Random();        int[] data = new int[10];        boolean b;        boolean b2 = false;        boolean b3 = true;        int x;        for (int i = 0; i < 10; i++) {            b = true;            while (b) {                x = random.nextInt(10);                if (x == 0 && b3) {                    b3 = false;                    b = false;                }                for (int y : data) {                    if (y == x) {                        b2 = false;                        break;                    } else {                        b2 = true;                    }                }                if (b2) {                    data[i] = x;                    b = false;                    break;                }            }        }        return data;    }

       上面就实现了0-9随机生成的数字,这个方法也有很多,我给出了一个大家参考。
       针对第二个问题禁止弹出系统键盘,我们可以这样设置:

setInputType(InputType.TYPE_NULL);

       这个方法意思是输入类型为没有指定明确的类型的特殊内容类型,系统键盘不会弹出,但是在android4.0以上光标不显示,在android4.0以上我们要用反射修改值,代码来源于网上:

public void hideSoftInputMethod(EditText ed) {        if (android.os.Build.VERSION.SDK_INT <= 10) {//4.0以下            ed.setInputType(InputType.TYPE_NULL);        } else {            activity.getWindow().setSoftInputMode(                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);            try {                Class cls = EditText.class;                Method setShowSoftInputOnFocus;                setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus",                        boolean.class);                setShowSoftInputOnFocus.setAccessible(true);                setShowSoftInputOnFocus.invoke(ed, false);            } catch (Exception e) {                e.printStackTrace();            }        }    }

       现在这样就是有光标的,但是我们在设置popwindow相关属性的时候,this.setFocusable(false); 不然光标一直不闪烁,如果设置为true,点击外面直接关闭系统键盘,不过用户又点击输入框键盘又弹出来了,正确的做法是,当键盘弹出时,点击输入框应该是不弹出键盘,这种用户体验感觉也不是很好。通过判断popwindow是否显示在屏幕上来决定是否弹出密码键盘,这个感觉是可以的,但是我们popwindow设置焦点为false的时候,popwindow的keyPopwindow.isShowing() 在对输入框监听的时候、先判断keyPopwindow == null ,不为空再去判断popwindow是否显示在屏幕上,但是获取的是false,我想跟焦点有关系吧,我用的是setOnTouchListener监听,popwindow上没有焦点,判断就有问题。目前还没想到好的办法,就先让光标闪烁吧,点击外面popwindow直接消失。后面我会给出源码,大家可以测试。
       如果我们在输入用户名的时候,在去输入密码,系统键盘是没有自动关闭的,这个时候我们就需要去判断一下,如果有系统键盘显示就需要关闭系统键盘,通过如下两个方法就可以实现:

/**     * 关闭系统键盘     * @param mEditText     * @param mContext     */    public void closeSoftKeybord(EditText mEditText, Context mContext) {        InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);        imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);    }    /**     * 判断是否有系统键盘显示     * @return     */    public boolean isSystemKeyboardVisible(){        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);        return imm.isActive();    }

       第三个问题其实也不难,我想的解决办法是scrollview来解决,我们计算输入框控件距离屏幕下方的距离如果小于密码键盘的高度,就要被遮住,这时候我们就需要在这个scrollview下添加一个view,这样点击布局就上移了,在关闭的时候,再把添加的view移除就好,关于这个计算涉及到android的坐标系计算,不熟悉的可以看看这篇博文:

http://blog.csdn.net/yanbober/article/details/50419117/

       我的实现后是这样的

       这个坐标计算我们先计算控件到屏幕view绘制的上方的距离,通过绝对坐标计算,数组下标0是宽度,下标1是高度,还有一个view.getLocationInWindow(location) 获取的是在父窗口的绝对坐标:

    int[] Location = new int[2];    pw_et.getLocationOnScreen(Location);    int y = Location[1];

       我们算出这个高度,然后通过获取整个view的绘制区域高度,然后通过rect.height()这个就可以获取高度:

      Rect rect = new Rect();      getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(rect);  

       这样我们就可以计算出到底部的距离,通过这个距离就可以判断是否显示密码键盘,不过计算popwindow的高度要这样计算,直接getHeight是获取不到的,一直为0,因为在实例化的时候绘制还没有完成:

keyPopwindow.getContentView().measure(0, 0);int keyHeight = keyPopwindow.getContentView().getMeasuredHeight();

       这样就可以计算出来上移的距离了,不过我们还有一点要注意,如果scrollview的高度没有超过屏幕,那么我们加上上面计算的偏移量有可能还达不到scrollview滑动的条件,我们应该在加上scrollview距离屏幕低端的距离,这样就可以了,可以说就可以达到我们上面哪个效果。

2.实现键盘

       实现我们就可以通过editable = password_et.getEditableText(); 然后

    private void insert(Button btn) {        int index = password_et.getSelectionStart();        String str = btn.getText().toString();        editable.insert(index, str);    }

       通过这个就可以实现点击事件输入到输入框,我们在设置一个回调接口,在popwindow关闭的时候调整布局:

public static LayoutAdjustListener mLayoutAdjustListener;    public interface LayoutAdjustListener {        //键盘遮挡布局使用scroll调整布局        void adjustKeyboard();    }    public static void setmLayoutAdjustListener(LayoutAdjustListener layoutAdjustListener) {        KeyPopwindow.mLayoutAdjustListener = layoutAdjustListener;    }    this.setOnDismissListener(new OnDismissListener() {            @Override            public void onDismiss() {                if (mLayoutAdjustListener != null) {                    mLayoutAdjustListener.adjustKeyboard();                }            }        });

       这样就基本上完成了,还有一些东西,大家看源码实现吧,我稍后上传下来,有问题的地方欢迎大家指出。

源码下载地址下载地址

更多相关文章

  1. Android(安卓)模拟器支持运行 ARM 应用,Android(安卓)11 系统映像
  2. android遥控器新增自定义的键值+用遥控器按键实现软键盘字符键的
  3. Android(安卓)源码分析实战 - 授权时拦截 QQ 用户名和密码
  4. Android性能优化之系统显示原理
  5. Android(安卓)7.1添加一个 系统底层服务
  6. Android进程保活(最新)带你浅析这几种可行性的保活方案
  7. LINE分享android利用系统自带分享实现LINE分享功能
  8. Android软键盘在清单文件中所有属性解释大全
  9. android注册 登录+修改帐号密码+添加资料+给指定帐号充值

随机推荐

  1. Increase the android VM heap size.
  2. Android(安卓)Studio 第五十六期 - Andro
  3. Ant 编译 Android(安卓)项目为 Apk 实战,
  4. 关于 radioButton和 checkBox 的样式
  5. ListActivity setContentView 错误
  6. android 自定义按钮的外边框
  7. android 全局异常的处理 详解
  8. android:Spinner(下拉框)控件的使用
  9. android 自定义View 在布局文件中写法
  10. Visual Studio Magazine -Mono for Andro