Android:自定义输入法(输入密码时防止第三方窃取)

对于Android用户而言,一般都会使用第三方的输入法。可是,在输入密码时(尤其是支付相关的密码),使用第三方输入法有极大的安全隐患。目前很多网银类的APP和支付宝等软件在用户输入密码时,都会弹出自定义的输入法而不是直接使用系统输入法。

本文介绍的就是如何实现一个简单的自定义输入法。当然,也可以自己写一个Dialog加上几十个按钮让用户输入,只不过这样显得不够专业。

(一)首先上效果图:

1.前面两个输入框使用了自定义的输入法:

2.第三个输入框没有进行任何设置,因此将使用默认的输入法:

(二)代码简介:

1.主页面布局,由3个输入框加上一个android.inputmethodservice.KeyboardView组成。android.inputmethodservice.KeyboardView是一个系统自带的继承自View的组件,但是它不在android.view这个包下面,因此这里需要写上完整的包名。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--前两个EditText均使用自定义的输入法-->
    <EditText
        android:id="@+id/input_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:hint="one password"
        android:layout_alignParentTop="true"
        android:inputType="textPassword" />

    <EditText
        android:id="@+id/input_password2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/input_password"
        android:layout_margin="8dp"
        android:hint="another password"
        android:inputType="textPassword" />

    <!--这个EditText使用默认的输入法-->
    <EditText
        android:id="@+id/input_normal_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/input_password2"
        android:layout_margin="8dp"
        android:hint="normal text" />

    <android.inputmethodservice.KeyboardView
        android:id="@+id/keyboardview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:visibility="gone" />

</RelativeLayout>

2.KeyboardView是一个显示输入法的容器控件,使用时需要设置具体的输入法面板内容。

(1)首先在res下新建xml目录,然后创建文件keys_layout.xml,即输入法面板的内容。每个row表示一行,Keyboad的属性keyWidth和keyHeight表示每个按键的大小,25%p表示占父组件的25%. Key的属性codes表示该按键的编号(点击时系统回调方法中会返回这个值,用以区分不同的按键),keyLabel表示按键上面显示的文字。还有很多其它的属性,不再陈述。

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="25%p"
    android:keyHeight="10%p">

    <Row>
        <Key
            android:codes="55"
            android:keyLabel="7"
            android:keyEdgeFlags="left" />
        <Key
            android:codes="56"
            android:keyLabel="8" />
        <Key
            android:codes="57"
            android:keyLabel="9" />
       <!--删除按键长按时连续响应-->
        <Key
            android:codes="60001"
            android:keyLabel="DEL"
            android:isRepeatable="true" />
    </Row>
    <Row>
        <Key
            android:codes="52"
            android:keyLabel="4"
            android:keyEdgeFlags="left" />
        <Key
            android:codes="53"
            android:keyLabel="5" />
        <Key
            android:codes="54"
            android:keyLabel="6" />
        <Key
            android:codes="48"
            android:keyLabel="0" />
    </Row>
    <Row>
        <Key
            android:codes="49"
            android:keyLabel="1"
            android:keyEdgeFlags="left" />
        <Key
            android:codes="50"
            android:keyLabel="2" />
        <Key
            android:codes="51"
            android:keyLabel="3" />
        <Key
            android:codes="60002"
            android:keyLabel="Cancel" />
    </Row>
</Keyboard>

(2)为了使用方便,新建一个类:KeyboardBuilder.java,用于初始化自定义输入法和绑定EditText,代码如下:

public class KeyboardBuilder {
    private static final String TAG = "KeyboardBuilder";
    private Activity mActivity;

    private KeyboardView mKeyboardView;

    public KeyboardBuilder(Activity ac, KeyboardView keyboardView, int keyBoardXmlResId) {
        mActivity = ac;
        mKeyboardView = keyboardView;

        Keyboard mKeyboard = new Keyboard(mActivity, keyBoardXmlResId);
        // Attach the keyboard to the view
        mKeyboardView.setKeyboard(mKeyboard);
        // Do not show the preview balloons
        mKeyboardView.setPreviewEnabled(false);

        KeyboardView.OnKeyboardActionListener keyboardListener = new KeyboardView.OnKeyboardActionListener() {
            @Override
            public void onKey(int primaryCode, int[] keyCodes) {
                // Get the EditText and its Editable
                View focusCurrent = mActivity.getWindow().getCurrentFocus();
                if (focusCurrent == null || !(focusCurrent instanceof EditText)) {
                    return;
                }

                EditText edittext = (EditText) focusCurrent;
                Editable editable = edittext.getText();
                int start = edittext.getSelectionStart();

                // Handle key
                if (primaryCode == Constant.CodeCancel) {
                    hideCustomKeyboard();
                } else if (primaryCode == Constant.CodeDelete) {
                    if (editable != null && start > 0) {
                        editable.delete(start - 1, start);
                    }
                } else {
                    // Insert character
                    editable.insert(start, Character.toString((char) primaryCode));
                }
            }

            @Override
            public void onPress(int arg0) {
            }

            @Override
            public void onRelease(int primaryCode) {
            }

            @Override
            public void onText(CharSequence text) {
            }

            @Override
            public void swipeDown() {
            }

            @Override
            public void swipeLeft() {
            }

            @Override
            public void swipeRight() {
            }

            @Override
            public void swipeUp() {
            }
        };
        mKeyboardView.setOnKeyboardActionListener(keyboardListener);
    }

    //绑定一个EditText
    public void registerEditText(EditText editText) {
        // Make the custom keyboard appear
        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    showCustomKeyboard(v);
                } else {
                    hideCustomKeyboard();
                }
            }
        });
        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "onClick");

                showCustomKeyboard(v);
            }
        });

        editText.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.d(TAG, "onTouch");

                EditText edittext = (EditText) v;
                int inType = edittext.getInputType();       // Backup the input type
                edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
                edittext.onTouchEvent(event);               // Call native handler
                edittext.setInputType(inType);              // Restore input type
                edittext.setSelection(edittext.getText().length());

                return true;
            }
        });
    }

    public void hideCustomKeyboard() {
        mKeyboardView.setVisibility(View.GONE);
        mKeyboardView.setEnabled(false);
    }

    public void showCustomKeyboard(View v) {
        mKeyboardView.setVisibility(View.VISIBLE);
        mKeyboardView.setEnabled(true);

        if (v != null) {
            ((InputMethodManager) mActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
        }
    }

    public boolean isCustomKeyboardVisible() {
        return mKeyboardView.getVisibility() == View.VISIBLE;

    }

3.最后是主Activity的代码,这里就很简单了。

/**
 * 自定义安全输入法
 */
public class MainActivity extends ActionBarActivity {
    private KeyboardBuilder builder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        KeyboardView keyboardView = (KeyboardView) findViewById(R.id.keyboardview);
        builder = new KeyboardBuilder(this, keyboardView, R.xml.keys_layout);

        EditText editText = (EditText) findViewById(R.id.input_password);
        builder.registerEditText(editText);
        EditText editText2 = (EditText) findViewById(R.id.input_password2);
        builder.registerEditText(editText2);
    }

    @Override
    public void onBackPressed() {
        if (builder != null && builder.isCustomKeyboardVisible()) {
            builder.hideCustomKeyboard();
        } else {
            this.finish();
        }
    }
}

参考文档:http://www.fampennings.nl/maarten/android/09keyboard/index.htm

时间: 2024-11-04 10:27:34

Android:自定义输入法(输入密码时防止第三方窃取)的相关文章

Android自定义Toast的时长、位置、及显示的View

Android自定义Toast 首先是自定义时长: 说是这么说,但是android自带的两个时长 LENGTH_SHORT (2秒) 和LENGTH_LONG (3.5秒)基本已经够用了,一般也没有特地去设置几十秒的Toast吧,这样的话,还不如直接弄一个Dialog来的直接. 我们先看看如何让Toast在3.5秒内自定义显示长度: public static void showShort(Context context, String msg, int duration) { final To

android studio 代码混淆如何忽略第三方jar包

最近在打包混淆时,遇到一个问题,混淆编译都不出错,运行出错,一般遇到这种问题,肯定是在运行的地方有代码被混淆了,经过错误排查,发现是程序中用到第三方的jar包的方法出现问题了,原来android studio混淆打包时把第三方的jar包给混淆了. 于是想这个问题很简单,保持jar包不混淆就好,于是直接在app目录下的proguard-rules.pro(或者proguard-rules.txt)混淆规则文件直接-libraryjars libs/xx.jar避免混淆.但是却引出了另一个错误: E

iOS8自定义输入法教程:如何创建第三方输入法

iOS8带来了很多很酷的功能,其中一个就是增加第三方输入法作为应用程序扩展.我们应当重视这个时刻,因为应用程序扩展开辟了一个全新的应用程序种类以及付费操作.凭借着在应用商店中数百万的应用程序,开发者和用户将迎来全新的一天. 在本帖中,我将向您展示如何为您的应用程序创建一个可进行全系统输入法操作的第三方输入法. 本教程将用Swift来完成.这是我的第一个真正用Swift语言完成的项目,我对其十分喜爱.现在,让我们直接研究如何创建一个第三方输入法. 首先,我先向大家展示一下我们要搭建的输入法的最终效

Android(java)学习笔记115:Android InputMethodManager输入法简介

正文 一.结构 public final class InputMethodManager extends Object Java.lang.Object android.view.inputmethod.InputMethodManager 二.类概述 整个输入法框架(IMF)结构的核心API,应用程序之间进行调度和当前输入法交互.你可以用Context.getSystemService()取得这一接口的实例. 架构总述(Architecture Overview) 输入法框架(IMF)共有三

Android项目:输入法软键盘显示/隐藏的监听和控制,InputMethodManager用法研究

在项目开发中,用到编辑框的地方经常涉及到要监听或者控制软键盘的显示/隐藏状态.本以为这是很容易解决的一个小问题,没想到当初碰到这个问题才明白还得花点小心思才能整好.现将针对软键盘的显示/隐藏状态的监听/监控方法做一些总结,以备后用. 一.点击空白处隐藏软键盘 这是具有编辑框焦点的页面对输入法软键盘状态监听的一般需求和解决方法. 首先获得InputMethodManager:        InputMethodManager manager = (InputMethodManager) getS

android自定义键盘(解决弹出提示的字体颜色问题)

最近准备要做一个项目,需要用到自定义小键盘来确保安全,而且还需要精确获得用户点击键盘时的落点位置.力度.指尖接触屏幕的面积等参数. 在写自定义键盘的时候,用到了国内网上的一些代码,出处是 http://blog.csdn.net/hfsu0419/article/details/7924673 向先人致敬! 然后发现down下来的代码用到我的项目时,出现了各种问题: 1.首先,是一打开应用,就会出现弹出的是系统的输入法键盘,而是不自定义键盘,这个问题是由于EditText会在应用打开的使用获得焦

Android Studio混淆模板及常用第三方混淆(看了都说好)

首先要在build.gradle中开启混淆,也就是minifyEnabled true,我用的build.gradle具体如下所示: def releaseTime() { return new Date().format("yyyy.MM.dd", TimeZone.getTimeZone("UTC")) } android { .... buildTypes { release { // 混淆 minifyEnabled true // Zipalign优化 z

Android 自定义View控件

一.简介 在自定义View时,我们通常会重写onDraw()方法来绘制View的显示内容.如果,该View还需要使用wrap_content属性,那么还必须重写onMeasure()方法.另外,通过自定义attrs属性,还可以设置新的属性配置值. 在View中通常有以下一些比较重要的回调方法: onFinisInflate():从XML加载组件后回调: onSizeChanged():组件大小改变时回调: onMeasure():回调该方法来进行测量: onLayout():回调该方法来确定显示

Android 自定义RecyclerView 实现真正的Gallery效果

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38173061 ,本文出自:[张鸿洋的博客] 上一篇博客我使用自定义HorizontalScrollView写了一个具有HorizontalScrollView效果和ViewPager特性的横向图片轮播,详见:Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果.其实制作横向滚动的不得不说另一个控件,就是Google