From 99309cf8fd0f933a96b36d8d3476e0170ca63a99 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Sat, 12 Oct 2013 12:28:23 +0000 Subject: [PATCH] add keyboard input in the android app --- .../android/res/drawable-hdpi/ic_keyboard.png | Bin 0 -> 695 bytes src/ui/android/res/layout/input_box.xml | 19 +++++ src/ui/android/res/menu/main.xml | 4 ++ src/ui/android/res/values/strings.xml | 2 + .../ui/android/ConversationView.java | 65 ++++++++++++++++-- .../ui/android/MainActivity.java | 65 ++++++++++++++++-- 6 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 src/ui/android/res/drawable-hdpi/ic_keyboard.png create mode 100644 src/ui/android/res/layout/input_box.xml create mode 100644 src/ui/android/res/menu/main.xml diff --git a/src/ui/android/res/drawable-hdpi/ic_keyboard.png b/src/ui/android/res/drawable-hdpi/ic_keyboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ce257a2697ee365ccf2f3b2525ad55f0ec593650 GIT binary patch literal 695 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F^e0|SF(iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$ zQVa}CCY~;iAsLNtXBw_s6d=;}-})TWiaV{dD*|3H<;)8SmhNm7ZRO-#xWRa#;>>5h zCMs>RJ^8}#4v9{fQ*3*g$EBd=;>7QIYBi$&IXR#2|Ne)wU~0#MnLpEZHM+m#nX$|` zVb-~ZOe^MP*f`70KkVIc<89gAy8ZvT5*QN_)-7Ev!?33B_~SAgxz~##q&Dchp4xG* zXG@thGeiEgRK^4A7ez>2h|-@`b4&f7LG*(&4l@~*qyz+K+?3>N@0vN+eap35iD?;Y z=U&XXG9&HTtBP(87naCrp3_o;UM#w17Q24#dxj2<%vrY>CM;Wd*Ui^uDsRBiHF;*U z{iSa$`}|s?c4*0~see)_6|W0J~56;G|tSKVUQPqhx% z(f#-aTZ2Vku2Ry_J{O{-4~bz;TLaihgmc@zN>6Z4d8# zuZ?!8>+Xcr=o+poVWC~+?h(JouG&4GRC6|d~Qw)$Ga ht8b|I|4)9+uT;KVSuaIQiGhKE!PC{xWt~$(698MTF<1Zq literal 0 HcmV?d00001 diff --git a/src/ui/android/res/layout/input_box.xml b/src/ui/android/res/layout/input_box.xml new file mode 100644 index 000000000..7a5a9ce99 --- /dev/null +++ b/src/ui/android/res/layout/input_box.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/src/ui/android/res/menu/main.xml b/src/ui/android/res/menu/main.xml new file mode 100644 index 000000000..0f628e334 --- /dev/null +++ b/src/ui/android/res/menu/main.xml @@ -0,0 +1,4 @@ + + + diff --git a/src/ui/android/res/values/strings.xml b/src/ui/android/res/values/strings.xml index 2720ed10c..af659fcec 100644 --- a/src/ui/android/res/values/strings.xml +++ b/src/ui/android/res/values/strings.xml @@ -6,4 +6,6 @@ Microphone Switch languages Opening + Speech Input + Keyboard Input diff --git a/src/ui/android/src/org/grammaticalframework/ui/android/ConversationView.java b/src/ui/android/src/org/grammaticalframework/ui/android/ConversationView.java index f138da336..06fbe3ae4 100644 --- a/src/ui/android/src/org/grammaticalframework/ui/android/ConversationView.java +++ b/src/ui/android/src/org/grammaticalframework/ui/android/ConversationView.java @@ -5,9 +5,14 @@ import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.view.KeyEvent; +import android.widget.EditText; import android.widget.ImageView; import android.widget.ScrollView; import android.widget.TextView; +import android.widget.TextView.OnEditorActionListener; public class ConversationView extends ScrollView { @@ -15,7 +20,8 @@ public class ConversationView extends ScrollView { private ViewGroup mContent; - private OnWordSelectedListener mListener; + private OnWordSelectedListener mWordListener; + private ASR.Listener mSpeechListener; public ConversationView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); @@ -49,6 +55,47 @@ public class ConversationView extends ScrollView { }); } + public void addInputBox() { + final View view = + mInflater.inflate(R.layout.input_box, mContent, false); + EditText edittext = (EditText) view.findViewById(R.id.input_text); + edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (hasFocus) { + InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null) { + inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + } + }); + edittext.setOnEditorActionListener(new OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if ((actionId & EditorInfo.IME_MASK_ACTION) != 0) { + CharSequence text = v.getText(); + mContent.removeView(view); + addFirstPersonUtterance("..."); + InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (inputMethodManager != null) { + inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); + } + if (mSpeechListener != null) + mSpeechListener.onSpeechInput(text.toString()); + return true; + } + return false; + } + }); + mContent.addView(view); + post(new Runnable() { + public void run() { + fullScroll(FOCUS_DOWN); + } + }); + } + public void addSecondPersonUtterance(CharSequence text) { TextView view = (TextView) mInflater.inflate(R.layout.second_person_utterance, mContent, false); @@ -68,7 +115,7 @@ public class ConversationView extends ScrollView { TextView textview = (TextView) view.findViewById(R.id.text); textview.setText(text); - if (lexicon != null && mListener != null) { + if (lexicon != null && mWordListener != null) { ImageView showWordButton = (ImageView) view.findViewById(R.id.show_word); showWordButton.setVisibility(VISIBLE); @@ -76,10 +123,12 @@ public class ConversationView extends ScrollView { showWordButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - TextView textview = (TextView) + if (mWordListener != null) { + TextView textview = (TextView) ((View) v.getParent()).findViewById(R.id.text); - CharSequence text = textview.getText(); - mListener.onWordSelected(text, lexicon2); + CharSequence text = textview.getText(); + mWordListener.onWordSelected(text, lexicon2); + } } }); } @@ -87,7 +136,11 @@ public class ConversationView extends ScrollView { } public void setOnWordSelectedListener(OnWordSelectedListener listener) { - mListener = listener; + mWordListener = listener; + } + + public void setSpeechInputListener(ASR.Listener listener) { + mSpeechListener = listener; } public interface OnWordSelectedListener { diff --git a/src/ui/android/src/org/grammaticalframework/ui/android/MainActivity.java b/src/ui/android/src/org/grammaticalframework/ui/android/MainActivity.java index 9efd841f1..eab45ffdd 100644 --- a/src/ui/android/src/org/grammaticalframework/ui/android/MainActivity.java +++ b/src/ui/android/src/org/grammaticalframework/ui/android/MainActivity.java @@ -5,13 +5,18 @@ import java.io.Serializable; import java.util.List; import android.app.Activity; +import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.speech.SpeechRecognizer; import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; +import android.view.inputmethod.InputMethodManager; import android.widget.ImageView; import org.grammaticalframework.ui.android.ASR.State; @@ -41,6 +46,10 @@ public class MainActivity extends Activity { private TTS mTts; private Translator mTranslator; + + private boolean input_mode; + + private SpeechInputListener mSpeechListener; @Override protected void onCreate(Bundle savedInstanceState) { @@ -64,7 +73,13 @@ public class MainActivity extends Activity { } }); - mStartStopButton.setEnabled(SpeechRecognizer.isRecognitionAvailable(this)); + input_mode = true; + if (!SpeechRecognizer.isRecognitionAvailable(this)) { + input_mode = false; + mStartStopButton.setImageResource(R.drawable.ic_keyboard); + } + + mSpeechListener = new SpeechInputListener(); mConversationView.setOnWordSelectedListener(new OnWordSelectedListener() { @Override @@ -75,9 +90,10 @@ public class MainActivity extends Activity { MainActivity.this.startActivity(myIntent); } }); + mConversationView.setSpeechInputListener(mSpeechListener); mAsr = new ASR(this); - mAsr.setListener(new SpeechInputListener()); + mAsr.setListener(mSpeechListener); mTts = new TTS(this); @@ -114,6 +130,37 @@ public class MainActivity extends Activity { mTargetLanguageView.setSelectedLanguage(mTranslator.getTargetLanguage()); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main, menu); + + if (!SpeechRecognizer.isRecognitionAvailable(this)) { + menu.getItem(0).setEnabled(false); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.input_mode: + if (input_mode) { + item.setTitle(R.string.mic_input); + mStartStopButton.setImageResource(R.drawable.ic_keyboard); + input_mode = false; + } else { + item.setTitle(R.string.keyboard_input); + mStartStopButton.setImageResource(R.drawable.ic_mic); + input_mode = true; + } + return true; + default: + return super.onOptionsItemSelected(item); + } + } + @Override protected void onDestroy() { if (mAsr != null) { @@ -151,14 +198,18 @@ public class MainActivity extends Activity { } private void startRecognition() { - mConversationView.addFirstPersonUtterance("..."); - - if (FAKE_SPEECH) { + if (FAKE_SPEECH) { handleSpeechInput("where is the hotel"); - } else { + return; + } + + if (input_mode) { + mConversationView.addFirstPersonUtterance("..."); mAsr.setLanguage(getSourceLanguageCode()); mAsr.startRecognition(); - } + } else { + mConversationView.addInputBox(); + } } private void stopRecognition() {