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)
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.
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);
}
}
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()
où anyView
est simplement une vue de votre mise en page.
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);
}
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);
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);
}
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!
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();
}
}
}
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>
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);
}