Пользовательский сбой клавиатуры - PullRequest
0 голосов
/ 30 января 2019

Я реализовал пользовательскую клавиатуру, она отлично работает на разных доступных мне тестовых устройствах, но я заметил, что о некоторых сбоях сообщают на консоли разработчика, и это происходит при сенсорном событии. Я не могу определить, почемуЭто сбой, так как я тестировал на устройствах, которые у меня есть, и работает на них нормально.

Это мой код для клавиатуры Custom.

    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)
...