I've now been able to figure this out. By looking at the code for InputMethodManager.showSoftInput(View, int)
, I worked out that my request to bring up the keyboard was being ignored because the view I was passing wasn't the InputMethodManager's active view.
To solve my problem, I added two new fields to the MyActivity
class, namely:
private EditText search_edit_text;
private boolean mySearchView_editflag;
The search_edit_text
variable will be the view inside the SearchView mySearchView
which is the view that actually gets the focus and receives the input from the keyboard. The mySearchView_editflag
will normally be false, but it will be true
when the app is waiting for the right time to bring up the keyboard.
To get hold of the search_edit_text
EditText object I used the following function
public static EditText GetEditText(ViewGroup vg) {
for(int i=0; i< vg.getChildCount(); i++) {
View v = vg.getChildAt(i);
if (v instanceof EditText) {
return (EditText)v;
} else if (v instanceof ViewGroup) {
EditText et = GetEditText((ViewGroup)v);
if (et != null) return et;
}
}
return null;
}
and altered my onCreateOptionsMenu(Menu)
function to include the following
DestinationTxt = menu.findItem(R.id.actionbar_search);
mySearchView = (SearchView)DestinationTxt.getActionView();
search_edit_text = GetEditText(mySearchView);
mySearchView_editflag = false;
This initializes the search_edit_text
and mySearchView_editflag
variables. My onResume()
method was altered to
@Override
public void onResume() {
super.onResume();
if (startsearch) {
DestinationTxt.expandActionView();
mySearchView_editflag = true;
}
}
and I included code which calls the following method at high frequency:
public void CheckStatus() {
if (mySearchView_editflag && imm.isActive(search_edit_text)) {
imm.showSoftInput(search_edit_text, 0);
mySearchView_editflag=false;
}
}
This app now works as I want it to, because following the activity switch when search input in the actionbar is required, the app now waits until imm.isActive(search_edit_text)
is true (which means the EditText
object is receiving input) before calling imm.showSoftInput(search_edit_text, 0)
to make sure that the keyboard is visible.
To help me work all this out, I used InputMethodManager.showSoftInput(View, int, ResultReceiver)
instead of InputMethodManager.showSoftInput(View, int)
, so instead of
imm.showSoftInput(search_edit_text, 0);
I had
ImmResultsReceiver irr = new ImmResultsReceiver();
imm.showSoftInput(search_edit_text, 0, irr);
where ImmResultsReceiver
is the class
public class ImmResultsReceiver extends ResultReceiver {
public ImmResultsReceiver() { super(null); }
@Override
protected void onReceiveResult (int resultCode, Bundle resultData) {
String descrip;
switch(resultCode) {
case InputMethodManager.RESULT_UNCHANGED_SHOWN: descrip = "RESULT_UNCHANGED_SHOWN"; break;
case InputMethodManager.RESULT_UNCHANGED_HIDDEN: descrip = "RESULT_UNCHANGED_HIDDEN"; break;
case InputMethodManager.RESULT_SHOWN: descrip = "RESULT_SHOWN"; break;
case InputMethodManager.RESULT_HIDDEN: descrip = "RESULT_HIDDEN"; break;
default:descrip="InputMethodManager("+resultCode+")"; break;
}
Log.d("MyLog", "ImmResultsReceiver,"+descrip+","+(resultData == null?"":"resultData.size()="+resultData.size()));
}
}
If the ImmResultsReceiver.onReceiveResult(...)
method is never called, it means that the call to InputMethodManager.showSoftInput(...)
has been ignored because the view that's passed to InputMethodManager.showSoftInput(...)
isn't the InputMethodManager's active view.