I've implemented a Custom keyboard it is working fine on the different test devices I've available but I've noticed some crashes are reported on developer console and it's occurring on touch event I'm not being able to identify why it's crashing as I've tested on devices that I've available and it's working fine on them.
This is my code for Custom keyboard.
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);
}
}
This is crash I'm getting on developer console
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)