Android 实现密码键盘的相关知识点
一、前言
由于我们是做金融相关的,对账户的密码输入为了安全,实现相应的保护测试,决定自己实现密码键盘替代系统的自带输入键盘。为什么要使用密码安全键盘呢,出于以下几个原因:
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<EditText> 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() {@Overridepublic void onDismiss() {if (mLayoutAdjustListener != null) {mLayoutAdjustListener.adjustKeyboard();}}});
这样就基本上完成了,还有一些东西,大家看源码实现吧,我稍后上传下来,有问题的地方欢迎大家指出。
源码下载地址下载地址
Android 实现密码键盘的相关知识点相关推荐
- Android横竖屏切换相关知识点
转载自:http://www.cnblogs.com/franksunny/p/3714442.html (老样子,图片啥的详细文档,可以下载后观看 http://files.cnblogs.com/ ...
- Android中手机定位相关知识点汇总
1.手机定位分类 根据不同的定位方式,手机定位又分为卫星定位和网络定位两大类. 2.卫星定位服务提供系统 卫星定位服务由几个全球卫星导航系统提供,主要包括美国GPS,俄罗斯格洛纳斯,中国北斗. 3.卫 ...
- 并发与多线程相关知识点梳理
文章目录 并发和并行的概念 如何保证线程安全 1. 数据单线程内可见 2. 只读对象 3. 线程安全类 4. 同步与锁机制 什么是锁 线程同步 引用类型 ThreadLocal LeetCode 相关 ...
- Unity 之 解决包体过大问题记录和纹理相关知识点整理
Unity 之 解决包体过大问题记录和纹理相关知识点整理 一,发现问题: 二,分析问题: 三,解决问题 3.1 问题分析 3.2 解决方案一 3.3 解决方案二 四,相关知识: 4.1 纹理导入: 4 ...
- android手机字体库相关问题深入剖析
hi,all: 问题一.android系统支持什么字体库? 1.Android系统默认支持三类字体家族,分别为:"serif", "sans-serif&qu ...
- Android菜鸟笔记-EditText相关知识整理
不定期整理一些EditText相关知识点.参考了一些前辈的博客资料,感谢你们! 1.EditText输入字母实时自动转换为大写 editText.setFilters(new InputFilter[ ...
- 卫星轨道推演计算相关知识点总结(含欧拉角、旋转矩阵、及各坐标系转化等)
来源:轨道机动算法的C++实现_shirro123的专栏-CSDN博客 卫星轨道推演计算相关基础知识点总结 一.卫星的运动特性 二.卫星的空间坐标系 ...
- Android面试:Java相关
Android面试常见Java相关问题. 原文链接:http://www.nowcoder.com/discuss/3244 Switch能否用string做参数? 在 Java 7 之前, swit ...
- 水下机器人_相关知识点
485转232 SP3485的管脚及功能: Pin1.RO 接收器输出 Pin2.RE 接收器输出使能(低电平有效) Pin3.DE 驱动器输出使能(高电平有效) Pin4.DI 驱动器输入 P ...
最新文章
- Android 使用 ellipsize 实现文字横向移动效果(跑马灯效果)
- 在团800运维工作总结之squid做回源图片的二级缓存
- ivy java_使用Ivy管理项目中的依赖
- Angular问题03 @angular/material版本问题
- oracle那些基本知识
- 广工android嵌入式系统试卷_嵌入式系统考试试题A及答案
- 如何三步搭建一套声纹系统
- linux 创建进程 execl,linux中进程的vfork()和execl()函数
- C语言和设计模式(建造者模式)
- 数据结构与算法基础-数组
- 浏览器语音附加背景音乐
- 中国裁判文书网接口解密
- C盘爆满,使用DiskGenius调整C盘大小,实操记录
- [swift] UIImage NSImage PNG透明区域填充自定义颜色实现
- 简单学习一下ibd数据文件解析
- CDN(内容分发网络)
- 厦门超微服务器维护,超微GPU服务器品牌
- ubuntu18.4 安装谷歌浏览器
- 【探花交友】用户登录总结
- Free2022春节虎年微信祝福语拜年分享小程序源码