web-dev-qa-db-ja.com

hideSoftInputFromWindowでのNULLポインターエラー

この行でヌルポインター例外が発生します。

public void hideKeyboard(){ 
InputMethodManager inputManager = (InputMethodManager)            
            this.getSystemService(Context.INPUT_METHOD_SERVICE);    
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(),      
            InputMethodManager.HIDE_NOT_ALWAYS);
}

これは、次のメソッドから呼び出されます。

@Override
public void onBackPressed() {
    super.onBackPressed();
    hideKeyboard();
}

これは唯一のアクティビティです。フラグメントから戻るボタンが押されました。

スタック:

09-28 19:14:40.301: E/InputEventSender(30324): Exception dispatching finished signal.
09-28 19:14:40.301: E/MessageQueue-JNI(30324): Exception in MessageQueue callback: handleReceiveCallback
09-28 19:14:40.325: E/MessageQueue-JNI(30324): Java.lang.NullPointerException
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at com.example.ecohelp.MainActivity.hideKeyboard(MainActivity.Java:75)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at com.example.ecohelp.MainActivity.onBackPressed(MainActivity.Java:31)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.app.Activity.onKeyUp(Activity.Java:2159)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.KeyEvent.dispatch(KeyEvent.Java:2647)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.app.Activity.dispatchKeyEvent(Activity.Java:2389)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at com.Android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.Java:1860)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.Java:3791)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.Java:3774)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.Java:3379)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.Java:3429)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.Java:3398)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.Java:3483)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.Java:3406)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.Java:3540)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.Java:3379)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.Java:3429)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.Java:3398)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.Java:3406)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.Java:3379)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.Java:3429)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.Java:3398)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.Java:3516)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.Java:3666)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.Java:1982)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.Java:1698)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.Java:1689)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.Java:1959)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.Java:141)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.os.MessageQueue.nativePollOnce(Native Method)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.os.MessageQueue.next(MessageQueue.Java:132)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.os.Looper.loop(Looper.Java:124)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Android.app.ActivityThread.main(ActivityThread.Java:5103)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Java.lang.reflect.Method.invokeNative(Native Method)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at Java.lang.reflect.Method.invoke(Method.Java:525)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:737)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:553)
09-28 19:14:40.325: E/MessageQueue-JNI(30324):  at dalvik.system.NativeStart.main(Native Method)
21
Karl Morrison

CommonsWareが述べたように、 getCurrentFocus() はnullです。これは、現在の Activity 内に View コンポーネントがないためです。

アクティビティにすでにビューがある場合は、それを使用してウィンドウトークンを取得します。たとえば、Buttonコンポーネントがある場合:

inputManager.hideSoftInputFromWindow(myButton.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

さらに悪いことに、アクティビティにまだビューがない場合、これを行うことができます:

inputManager.hideSoftInputFromWindow(new View(this).getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

これでNPEの問題は解決しますが、説明が役立つことを願っています。

キーボードに関するもう1つのことは、キーボードが表示されているときにユーザーが戻るボタンを押すと、キーボードが戻るキーの押下を受け取り、消費してそれ自体を隠すことです。または、少なくともほとんどのキーボードはそのように動作します。

30
Armin

キーボードを非表示にする前に、フォーカスされたビューがあるかどうかを確認するだけです。

たとえば、アクティビティまたはフラグメントにEditTextがある場合、それはおそらくフォーカスされたビューになります。 EditTextがもうフォーカスされていない場合、getCurrentFocus()はnullを返すことがあります(他のビューがフォーカスされていない限り)。

void hideKeyboard() {
    InputMethodManager inputManager = (InputMethodManager) getActivity().getSystemService(
            Context.INPUT_METHOD_SERVICE);
    View focusedView = getActivity().getCurrentFocus();
    /*
     * If no view is focused, an NPE will be thrown
     * 
     * Maxim Dmitriev
     */
    if (focusedView != null) {
        inputManager.hideSoftInputFromWindow(focusedView.getWindowToken(),
                InputMethodManager.HIDE_NOT_ALWAYS);
    }
}
30
Maksim Dmitriev

上記の誰もがgetWindowToken()がnullを返していると正しく指摘していました。

同じ問題が発生したときに、デフォルトのコードgetCurrentFocus().getWindowToken()を使用してキーボードを非表示にしました。

次に、フォーカスを取得するビューがないため、NullPointerExceptionを取得したことに気付きました。

上記を次のように変更できます。

anyView.getWindowToken()

anyViewは、レイアウト内の任意のビューです。

21
Atul O Holic

GetCurrentFocus()がnullを返すという同じ問題がありました。したがって、このメソッドは私のために働いたので、キーボードが表示されていない場合でも、onClickで呼び出してキーボードを非表示にするか、nullポインタ例外をスローします:

public void hiddenInputMethod() {

    InputMethodManager imm = (InputMethodManager) getSystemService(MyActivity.this.INPUT_METHOD_SERVICE);
    if (getCurrentFocus() != null)
        imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
7
Richmond

画面をタッチするときにキーボードを非表示にするには、以下のコードを使用します

       @Override
public boolean onTouchEvent(MotionEvent event) {
    InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.
            INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(this.getWindow().getDecorView().getRootView().getWindowToken(), 0);
    return true;
}

特定のビュー(EditText)でこれを行いたい場合

      public void  hideKeyBoard(EditText edt) {
    InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.
            INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(edt.getWindowToken(), 0);

}

または、任意のビューを使用できます。

現在のビューを取得するには

    imm.hideSoftInputFromWindow(this.getWindow().getDecorView().getRootView().getWindowToken(), 0);
5
sreenadh

エラーが発生している場合は、これを使用します。原因:Java.lang.NullPointerException:nullオブジェクト参照で仮想メソッド 'Android.os.IBinder Android.view.View.getWindowToken()'を呼び出そうとしています


InputMethodManager inputMethodManager = (InputMethodManager) MainActivity.this.getSystemService(Activity.INPUT_METHOD_SERVICE);

   if(MainActivity.this.getCurrentFocus() != null)
        {
         inputMethodManager.hideSoftInputFromWindow(MainActivity.this.getCurrentFocus().
getWindowToken(), 0);
        }

これは私のために動作します。 getCurrectFocus()を使用する代わりに、getWindow()。getDecorView()。getRootView()。getWindowToken()を追加するだけです。その後、アクティビティの任意の場所でこのメソッドを使用できます。

public static void hideSoftKeyboard(Activity activity) {
        InputMethodManager inputMethodManager =
                (InputMethodManager) activity.getSystemService(
                        Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(
                activity.getWindow().getDecorView().getRootView().getWindowToken(), 0);
    }
2
Nuwan Withanage

主な問題は

getCurrentFocus().getWindowToken()

ここでgetcurrentFocus()が問題です。この問題は、現在の画面上にある有効なビューを提供することで簡単に解決できます。

yourButtonOnScreen.getWindowToken()

このボタンは画面に表示されているため、nullではないため、問題は解決します。

それでも、画面に有効なビューがない場合は、単に置き換えてください

getCurrentFocus().getWindowToken()...

with

//in case of fragment

new View(getActivity()).getWindowToken()

//in case of activity

new View(this).getWindowToken()

これで問題が解決することを願っています。

1
Ali Nawaz

InputMethodManagerのインスタンスがnullの場合、エラーが表示される場合があります。私のために働いた以下のコードを試してください。

void hideKeyboard() {
InputMethodManager inputManager = (InputMethodManager) 
getActivity().getSystemService(
        Context.INPUT_METHOD_SERVICE);
View focusedView = getActivity().getCurrentFocus();

if (focusedView != null) {

    try{
    assert inputManager != null;
    inputManager.hideSoftInputFromWindow(focusedView.getWindowToken(),
            InputMethodManager.HIDE_NOT_ALWAYS);
}catch(AssertionError e{
     e.printStackTrace();
    }
  }
}
0
neer17

問題は、フォーカスされた要素がない場合に発生します。つまり、この検証で十分です。

if(activity.getCurrentFocus() != null)
{
    InputMethodManager inputMethodManager =
    (InputMethodManager) activity.getSystemService(
    Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(
    activity.getCurrentFocus().getWindowToken(), 0);
}
0
Alejandro Luna

キーボードを非表示にしているときに同じ問題に直面していましたが、タッチモードでレイアウトのルートビューをフォーカス可能にすることで簡単な解決策を見つけました。

<RelativeLayout xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:clickable="true"
Android:id="@+id/rlSignActivity"
Android:focusableInTouchMode="true"
xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    .......
</RelativeLayout>
0
Apoorv Singh