我已经实现了“自定义”键盘,它在我可用的不同测试设备上都可以正常工作,但是我注意到开发者控制台上报告了一些崩溃,并且发生在触摸事件上,我无法确定原因当我在可用设备上进行测试时,它崩溃了,并且在它们上运行良好。
这是我的“自定义”键盘代码。
public CustomKeyboard(@NonNull Activity host, int viewid, int layoutid, @NonNull View rootView) {
try {
view = rootView;
// LayoutInflater inflater = (LayoutInflater) host.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// view = inflater.inflate(R.layout.voice_dialpadscreen, null);
mHostActivity = host;
mKeyboardView = (KeyboardView) rootView.findViewById(viewid);
mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons
mKeyboardView.setOnKeyboardActionListener(new OnKeyboardActionListener() {
public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
public final static int CodePrev = 55000;
public final static int CodeAllLeft = 55001;
public final static int CodeLeft = 55002;
public final static int CodeRight = 55003;
public final static int CodeAllRight = 55004;
public final static int CodeNext = 55005;
public final static int CodeClear = 55006;
@Override
public void onKey(int primaryCode, int[] keyCodes) {
try {
// NOTE We can say '<Key android:codes="49,50" ... >' in the xml file; all codes come in keyCodes, the first in this list in primaryCode
// Get the EditText and its Editable
View focusCurrent = view.findFocus();
// if( focusCurrent==null || focusCurrent.getClass()!=EditText.class ) {
// Log.d("tag", "Value: not foccusedd ");
//
// return;
// }
Log.d("tag", "Value: focused ");
EditText edittext = (EditText) focusCurrent;
Editable editable = edittext.getText();
int start = edittext.getSelectionStart();
// Apply the key to the edittext
if (primaryCode == CodeCancel) {
hideCustomKeyboard();
} else if (primaryCode == CodeDelete) {
if (editable != null && start > 0) editable.delete(start - 1, start);
} else if (primaryCode == CodeClear) {
if (editable != null) editable.clear();
} else if (primaryCode == CodeLeft) {
if (start > 0) edittext.setSelection(start - 1);
} else if (primaryCode == CodeRight) {
if (start < edittext.length()) edittext.setSelection(start + 1);
} else if (primaryCode == CodeAllLeft) {
edittext.setSelection(0);
} else if (primaryCode == CodeAllRight) {
edittext.setSelection(edittext.length());
} else if (primaryCode == CodePrev) {
View focusNew = edittext.focusSearch(View.FOCUS_BACKWARD);
if (focusNew != null) focusNew.requestFocus();
} else if (primaryCode == CodeNext) {
View focusNew = edittext.focusSearch(View.FOCUS_FORWARD);
if (focusNew != null) focusNew.requestFocus();
} else { // insert character
editable.insert(start, Character.toString((char) primaryCode));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void onPress(int primaryCode) {
try {
if (primaryCode == CodeDelete) {
View focusCurrent = view.findFocus();
// if( focusCurrent==null || focusCurrent.getClass()!=EditText.class ) {
// Log.d("tag", "Value: not foccusedd ");
//
// return;
// }
Log.d("tag", "Value: focused ");
EditText edittext = (EditText) focusCurrent;
Editable editable = edittext.getText();
int start = edittext.getSelectionStart();
if (editable != null && start > 0) editable.delete(start - 1, start);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
// Hide the standard keyboard initially
mHostActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/** Returns whether the CustomKeyboard is visible. */
public boolean isCustomKeyboardVisible() {
return mKeyboardView.getVisibility() == View.VISIBLE;
}
/** Make the CustomKeyboard visible, and hide the system keyboard for view v. */
public void showCustomKeyboard(@Nullable View v) {
mKeyboardView.setVisibility(View.VISIBLE);
mKeyboardView.setEnabled(true);
if( v!=null ) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
}
/** Make the CustomKeyboard invisible. */
public void hideCustomKeyboard() {
mKeyboardView.setVisibility(View.GONE);
mKeyboardView.setEnabled(false);
}
/**
* Register <var>EditText<var> with resource id <var>resid</var> (on the hosting activity) for using this custom keyboard.
*
*/
public void registerEditText(int resid, @NonNull View rootView) {
// Find the EditText 'resid'
EditText edittext= (EditText)rootView.findViewById(resid);
// Make the custom keyboard appear
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
// NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus
@Override public void onFocusChange(View v, boolean hasFocus) {
if( hasFocus ) showCustomKeyboard(v); else hideCustomKeyboard();
}
});
edittext.setOnClickListener(new OnClickListener() {
// NOTE By setting the on click listener, we can show the custom keyboard again, by tapping on an edit box that already had focus (but that had the keyboard hidden).
@Override public void onClick(View v) {
showCustomKeyboard(v);
}
});
// Disable standard keyboard hard way
// NOTE There is also an easy way: 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
edittext.setOnTouchListener(new OnTouchListener() {
@Override public boolean onTouch(View v, MotionEvent event) {
try {
EditText edittext = (EditText) v;
int inType = edittext.getInputType(); // Backup the input type
// edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
edittext.onTouchEvent(event); // makeVideoCall native handler
edittext.setInputType(inType); // Restore input type
} catch (Exception e) {
e.printStackTrace();
}
return true; // Consume touch event
}
});
// Disable spell check (hex strings look like words to Android)
edittext.setInputType(edittext.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
}
这是我在开发人员控制台上遇到的崩溃
java.lang.NullPointerException:
at android.inputmethodservice.KeyboardView.sendAccessibilityEventForUnicodeCharacter (KeyboardView.java:998)
at android.inputmethodservice.KeyboardView.showPreview (KeyboardView.java:883)
at android.inputmethodservice.KeyboardView.onModifiedTouchEvent (KeyboardView.java:1301)
at android.inputmethodservice.KeyboardView.onTouchEvent (KeyboardView.java:1223)
at android.view.View.dispatchTouchEvent (View.java:10717)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.widget.ScrollView.dispatchTouchEvent (ScrollView.java:738)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:2865)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2492)
at com.android.internal.policy.DecorView.superDispatchTouchEvent (DecorView.java:559)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent (PhoneWindow.java:1870)
at android.app.Activity.dispatchTouchEvent (Activity.java:3236)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent (WindowCallbackWrapper.java:68)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent (WindowCallbackWrapper.java:68)
at com.android.internal.policy.DecorView.dispatchTouchEvent (DecorView.java:521)
at android.view.View.dispatchPointerEvent (View.java:10946)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent (ViewRootImpl.java:5110)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:4962)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4493)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:4546)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:4512)
at android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:4645)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:4520)
at android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:4702)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4493)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:4546)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:4512)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:4520)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:4493)
at android.view.ViewRootImpl.deliverInputEvent (ViewRootImpl.java:7000)
at android.view.ViewRootImpl.doProcessInputEvents (ViewRootImpl.java:6929)
at android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:6890)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent (ViewRootImpl.java:7110)
at android.view.InputEventReceiver.dispatchInputEvent (InputEventReceiver.java:185)
at android.os.MessageQueue.nativePollOnce (MessageQueue.java)
at android.os.MessageQueue.next (MessageQueue.java:323)
at android.os.Looper.loop (Looper.java:136)
at android.app.ActivityThread.main (ActivityThread.java:6682)
at java.lang.reflect.Method.invoke (Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1410)