首页 > 系统 > Android > 正文

Android编程实现自定义输入法功能示例【输入密码时防止第三方窃取】

2019-12-12 03:57:15
字体:
来源:转载
供稿:网友

本文实例讲述了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();    }  }}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android视图View技巧总结》、《Android开发动画技巧汇总》、《Android编程之activity操作技巧总结》、《Android布局layout技巧总结》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》及《Android控件用法总结

希望本文所述对大家Android程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表