web-dev-qa-db-fra.com

Erreur de pointeur NULL avec hideSoftInputFromWindow

Je reçois une exception de pointeur null à cette ligne:

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

Ceci est appelé de la méthode suivante:

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

C'est dans la seule activité. Le bouton de retour est appuyé sur un fragment.

EMPILER:

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)
19
Karl Morrison

Comme le mentionnait CommonsWare, getCurrentFocus () est nul, car il n'y a pas de composant View dans l'actuel Activity contenant le focus.

Si vous avez déjà une vue dans votre activité, utilisez-la pour obtenir le jeton de fenêtre. Par exemple, si j'ai un composant Button:

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

Ou pire encore, si je n'ai pas encore de vue dans mon activité, je pourrais le faire:

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

Cela résoudrait votre problème de NPE, mais j'espère que vous trouverez la description utile.

Une autre chose à propos des claviers, c’est que lorsque l’utilisateur appuie sur le bouton Précédent alors que le clavier est visible, le clavier reçoit et utilise la touche Retour pour se cacher. Ou du moins la plupart des claviers se comportent de cette façon.

27
Armin

Je dois juste vérifier s'il y a une vue focalisée avant de cacher le clavier.

Par exemple, si vous avez une EditText dans votre activité ou dans votre fragment, ce sera probablement la vue ciblée. Lorsque la EditText n'est plus focalisée, getCurrentFocus() peut retourner la valeur null (sauf si une autre vue est focalisée).

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);
    }
}
21
Maksim Dmitriev

Tout le monde ci-dessus a correctement indiqué que getWindowToken() renvoyait la valeur null.

J'utilisais le code par défaut getCurrentFocus().getWindowToken() pour masquer le clavier lorsque j'ai rencontré le même problème.

J'ai alors réalisé que comme il n'y avait pas de vue pour obtenir le focus, j'ai la NullPointerException.

Nous pouvons changer ce qui précède pour:

anyView.getWindowToken()

anyView est simplement une vue de votre mise en page.

19
Atul O Holic

J'ai eu le même problème où getCurrentFocus () retournait null. Donc, cette méthode a fonctionné pour moi, et je l’appellerais simplement sur mon onClick pour cacher le clavier si elle est montrée ou quand même pas une exception de pointeur nulle même si le clavier n’est pas montré:

public void hiddenInputMethod() {

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

Si vous souhaitez masquer le clavier lorsque vous touchez à l'écran, utilisez le code ci-dessous

       @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;
}

Si vous voulez faire cela dans une vue spécifique (EditText)

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

}

ou vous pouvez utiliser n'importe quelle vue.

Pour avoir la vue actuelle

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

Utilisez cette option si vous obtenez une erreur: provoquée par: Java.lang.NullPointerException: essayez d'appeler la méthode virtuelle 'Android.os.IBinder Android.view.View.get.WindowToken ()' sur une référence d'objet null


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

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

Le problème principal est dans 

getCurrentFocus().getWindowToken()

Ici getcurrentFocus () est le problème. Ce problème peut être résolu facilement en fournissant une vue valide résidant sur votre écran actuel, comme

yourButtonOnScreen.getWindowToken()

Ce bouton ne sera pas nul car il est affiché sur votre écran pour résoudre le problème.

Toujours si vous n’avez pas de vue valide sur votre écran il suffit de remplacer

getCurrentFocus().getWindowToken()...

avec

//in case of fragment

new View(getActivity()).getWindowToken()

//in case of activity

new View(this).getWindowToken()

espérons que cela résoudra le problème .. bonne chance!

1
Ali Nawaz

Il peut afficher une erreur si l'instance de InputMethodManager est null. Essayez le code ci-dessous cela a fonctionné pour moi.

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

Je faisais face au même problème tout en cachant le clavier. J'ai trouvé la solution simple en rendant la vue racine de la disposition mise au point en mode tactile.

<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

Cela fonctionne pour moi. Ajoutez simplement la méthode getWindow (). GetDecorView (). GetRootView (). GetWindowToken () à la place de la méthode getCurrectFocus (). Après cela, vous pouvez utiliser cette méthode pour n’importe où dans votre activité.

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