この行でヌルポインター例外が発生します。
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)
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つのことは、キーボードが表示されているときにユーザーが戻るボタンを押すと、キーボードが戻るキーの押下を受け取り、消費してそれ自体を隠すことです。または、少なくともほとんどのキーボードはそのように動作します。
キーボードを非表示にする前に、フォーカスされたビューがあるかどうかを確認するだけです。
たとえば、アクティビティまたはフラグメントに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);
}
}
上記の誰もがgetWindowToken()
がnullを返していると正しく指摘していました。
同じ問題が発生したときに、デフォルトのコードgetCurrentFocus().getWindowToken()
を使用してキーボードを非表示にしました。
次に、フォーカスを取得するビューがないため、NullPointerException
を取得したことに気付きました。
上記を次のように変更できます。
anyView.getWindowToken()
anyView
は、レイアウト内の任意のビューです。
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);
}
画面をタッチするときにキーボードを非表示にするには、以下のコードを使用します
@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);
エラーが発生している場合は、これを使用します。原因: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);
}
主な問題は
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()
これで問題が解決することを願っています。
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();
}
}
}
問題は、フォーカスされた要素がない場合に発生します。つまり、この検証で十分です。
if(activity.getCurrentFocus() != null)
{
InputMethodManager inputMethodManager =
(InputMethodManager) activity.getSystemService(
Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(
activity.getCurrentFocus().getWindowToken(), 0);
}
キーボードを非表示にしているときに同じ問題に直面していましたが、タッチモードでレイアウトのルートビューをフォーカス可能にすることで簡単な解決策を見つけました。
<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>