diff --git a/res/drawable-hdpi/ic_mic_dialog.png b/res/drawable-hdpi/ic_mic_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..349dc4b37c6a5530cd2846eeba3024f976cab75a Binary files /dev/null and b/res/drawable-hdpi/ic_mic_dialog.png differ diff --git a/res/drawable-hdpi/ic_suggest_strip_microphone.png b/res/drawable-hdpi/ic_suggest_strip_microphone.png new file mode 100644 index 0000000000000000000000000000000000000000..c00b4aaa645b244f89b209b540668737795f29f3 Binary files /dev/null and b/res/drawable-hdpi/ic_suggest_strip_microphone.png differ diff --git a/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png b/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png new file mode 100644 index 0000000000000000000000000000000000000000..256dc3d6155009d2ed7b495d911d661f59c100fa Binary files /dev/null and b/res/drawable-hdpi/ic_suggest_strip_microphone_swipe.png differ diff --git a/res/drawable-hdpi/list_selector_background_pressed.9.png b/res/drawable-hdpi/list_selector_background_pressed.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ba79cf7f85d3cf1709ef6332322fb6543555fab3 Binary files /dev/null and b/res/drawable-hdpi/list_selector_background_pressed.9.png differ diff --git a/res/drawable-hdpi/mic_slash.png b/res/drawable-hdpi/mic_slash.png old mode 100755 new mode 100644 index 87153dc336320a73e9aecadaced901f35d5e0d95..a7b734c71011252d80283f9ee49b36f28b8e2629 Binary files a/res/drawable-hdpi/mic_slash.png and b/res/drawable-hdpi/mic_slash.png differ diff --git a/res/drawable-hdpi/speak_now_level0.png b/res/drawable-hdpi/speak_now_level0.png index 5c5ca309d05e05143d6a151f24fc708670705bc1..a681da606b634b33c3ce5be7096c5ec42afca4ba 100755 Binary files a/res/drawable-hdpi/speak_now_level0.png and b/res/drawable-hdpi/speak_now_level0.png differ diff --git a/res/drawable-hdpi/speak_now_level1.png b/res/drawable-hdpi/speak_now_level1.png index 4d5f7d6bb912fdd4f3c39cdcd7271975a0e96060..0dbec69a7a063ac9c34eddebd793795720c52de3 100755 Binary files a/res/drawable-hdpi/speak_now_level1.png and b/res/drawable-hdpi/speak_now_level1.png differ diff --git a/res/drawable-hdpi/speak_now_level2.png b/res/drawable-hdpi/speak_now_level2.png index be5a7d37aea56566098edd2fe31319aab7e92513..45cbff2b7f63cf0ceb36f4d4578b564fe0c659c7 100755 Binary files a/res/drawable-hdpi/speak_now_level2.png and b/res/drawable-hdpi/speak_now_level2.png differ diff --git a/res/drawable-hdpi/speak_now_level3.png b/res/drawable-hdpi/speak_now_level3.png index 82968f4768864ac8bb93f9fd6289a2d683a60e0e..abda8f683c4670ca983559d46e509da6021953d5 100755 Binary files a/res/drawable-hdpi/speak_now_level3.png and b/res/drawable-hdpi/speak_now_level3.png differ diff --git a/res/drawable-hdpi/speak_now_level4.png b/res/drawable-hdpi/speak_now_level4.png index e8ce7bd7f5cf45881e3d49d7307f1597ffc4f754..18356351a5f0ba664357ec1606e1391faf9a517d 100755 Binary files a/res/drawable-hdpi/speak_now_level4.png and b/res/drawable-hdpi/speak_now_level4.png differ diff --git a/res/drawable-hdpi/speak_now_level5.png b/res/drawable-hdpi/speak_now_level5.png index 77d0b8e9bb4780599c142095b4c48b44d4c9e496..7d4fd5f20848b753e27d67bd4db7852265cf7432 100755 Binary files a/res/drawable-hdpi/speak_now_level5.png and b/res/drawable-hdpi/speak_now_level5.png differ diff --git a/res/drawable-hdpi/speak_now_level6.png b/res/drawable-hdpi/speak_now_level6.png new file mode 100755 index 0000000000000000000000000000000000000000..e06990faaaa7490ee52b428d70fd7a09cdaa63be Binary files /dev/null and b/res/drawable-hdpi/speak_now_level6.png differ diff --git a/res/drawable-hdpi/sym_keyboard_feedback_mic.png b/res/drawable-hdpi/sym_keyboard_feedback_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..cb86a5598a7a9213a0755ea1670f6e27d25e9528 Binary files /dev/null and b/res/drawable-hdpi/sym_keyboard_feedback_mic.png differ diff --git a/res/drawable-hdpi/sym_keyboard_mic.png b/res/drawable-hdpi/sym_keyboard_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..0a0a68a96cdb53b36df9610654eca6e3ecd452b4 Binary files /dev/null and b/res/drawable-hdpi/sym_keyboard_mic.png differ diff --git a/res/drawable-hdpi/voice_background.9.png b/res/drawable-hdpi/voice_ime_background.9.png similarity index 100% rename from res/drawable-hdpi/voice_background.9.png rename to res/drawable-hdpi/voice_ime_background.9.png diff --git a/res/drawable-mdpi/ic_mic_dialog.png b/res/drawable-mdpi/ic_mic_dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..77613ca05c3686518c0879d325adb0111ead893d Binary files /dev/null and b/res/drawable-mdpi/ic_mic_dialog.png differ diff --git a/res/drawable-mdpi/ic_suggest_strip_microphone.png b/res/drawable-mdpi/ic_suggest_strip_microphone.png new file mode 100644 index 0000000000000000000000000000000000000000..18f314a61a15f05cb20aad5dd8ad317eb3b4c70e Binary files /dev/null and b/res/drawable-mdpi/ic_suggest_strip_microphone.png differ diff --git a/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png b/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png new file mode 100644 index 0000000000000000000000000000000000000000..ff629b6744095c35ecc715ed6a91ff90c7b28e8d Binary files /dev/null and b/res/drawable-mdpi/ic_suggest_strip_microphone_swipe.png differ diff --git a/res/drawable-mdpi/list_selector_background_pressed.9.png b/res/drawable-mdpi/list_selector_background_pressed.9.png new file mode 100644 index 0000000000000000000000000000000000000000..02b4e9a536fedd342ecef1d0153ef97a3fe69452 Binary files /dev/null and b/res/drawable-mdpi/list_selector_background_pressed.9.png differ diff --git a/res/drawable-mdpi/sym_keyboard_feedback_mic.png b/res/drawable-mdpi/sym_keyboard_feedback_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..247d5b3a9cec75d14aac825139c52ab6207f1c23 Binary files /dev/null and b/res/drawable-mdpi/sym_keyboard_feedback_mic.png differ diff --git a/res/drawable-mdpi/sym_keyboard_mic.png b/res/drawable-mdpi/sym_keyboard_mic.png new file mode 100644 index 0000000000000000000000000000000000000000..a7580954932deb94136d936fd3fe5f1b1a02fb8c Binary files /dev/null and b/res/drawable-mdpi/sym_keyboard_mic.png differ diff --git a/res/drawable/cancel.png b/res/drawable/cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..081532bec57494366c9fde7a6b33154c3ac0555b Binary files /dev/null and b/res/drawable/cancel.png differ diff --git a/res/drawable/caution.png b/res/drawable/caution.png new file mode 100644 index 0000000000000000000000000000000000000000..eaef534254f1b5feef517949b559f5653b81fcba Binary files /dev/null and b/res/drawable/caution.png differ diff --git a/res/drawable/dialog_top_dark_bottom_medium.9.png b/res/drawable/dialog_top_dark_bottom_medium.9.png new file mode 100644 index 0000000000000000000000000000000000000000..cf7ecaf1ea64435bad70e7513b4e1c3d5a19a21a Binary files /dev/null and b/res/drawable/dialog_top_dark_bottom_medium.9.png differ diff --git a/res/drawable/ic_dialog_alert_large.png b/res/drawable/ic_dialog_alert_large.png new file mode 100644 index 0000000000000000000000000000000000000000..2d4a164a78de6e70dfafc70c7e5820601ac6db8d Binary files /dev/null and b/res/drawable/ic_dialog_alert_large.png differ diff --git a/res/drawable/ic_dialog_voice_input.png b/res/drawable/ic_dialog_voice_input.png new file mode 100644 index 0000000000000000000000000000000000000000..d2891413227855950e6113ec64319a4b8e49c468 Binary files /dev/null and b/res/drawable/ic_dialog_voice_input.png differ diff --git a/res/drawable/ic_dialog_wave_0_0.png b/res/drawable/ic_dialog_wave_0_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9c3c28f37b79a696820fd971b3c660a94e9b31ef Binary files /dev/null and b/res/drawable/ic_dialog_wave_0_0.png differ diff --git a/res/drawable/ic_dialog_wave_1_3.png b/res/drawable/ic_dialog_wave_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d33bd0d9b534cb7107c8a770b57891349157ec59 Binary files /dev/null and b/res/drawable/ic_dialog_wave_1_3.png differ diff --git a/res/drawable/ic_dialog_wave_2_3.png b/res/drawable/ic_dialog_wave_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..5094a6e6cb600b90562c1d638255e1fe9a5bba21 Binary files /dev/null and b/res/drawable/ic_dialog_wave_2_3.png differ diff --git a/res/drawable/ic_dialog_wave_3_3.png b/res/drawable/ic_dialog_wave_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..69917564d785326f846563c46a09074d809f6004 Binary files /dev/null and b/res/drawable/ic_dialog_wave_3_3.png differ diff --git a/res/drawable/ic_dialog_wave_4_3.png b/res/drawable/ic_dialog_wave_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..af5a84c31a40b52848a7ebfd210d3ef2db3bd74e Binary files /dev/null and b/res/drawable/ic_dialog_wave_4_3.png differ diff --git a/res/drawable/mic_slash.png b/res/drawable/mic_slash.png new file mode 100644 index 0000000000000000000000000000000000000000..0b0fb5803a1afb80f5c02d58545d5c94e20144ca Binary files /dev/null and b/res/drawable/mic_slash.png differ diff --git a/res/drawable/ok_cancel.png b/res/drawable/ok_cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..0601d3231778e967cd376e048aa0f515a75ca1d0 Binary files /dev/null and b/res/drawable/ok_cancel.png differ diff --git a/res/drawable/speak_now_level0.png b/res/drawable/speak_now_level0.png new file mode 100644 index 0000000000000000000000000000000000000000..abc84546625390f4d40e47b341519a8bac3782e9 Binary files /dev/null and b/res/drawable/speak_now_level0.png differ diff --git a/res/drawable/speak_now_level1.png b/res/drawable/speak_now_level1.png new file mode 100644 index 0000000000000000000000000000000000000000..67cb235bf22327b93e6c95e29bb611a8a72cc95f Binary files /dev/null and b/res/drawable/speak_now_level1.png differ diff --git a/res/drawable/speak_now_level2.png b/res/drawable/speak_now_level2.png new file mode 100644 index 0000000000000000000000000000000000000000..1e07f26c693c34611b03de9f7e23bc75f3cb95c3 Binary files /dev/null and b/res/drawable/speak_now_level2.png differ diff --git a/res/drawable/speak_now_level3.png b/res/drawable/speak_now_level3.png new file mode 100644 index 0000000000000000000000000000000000000000..31991daee2c84fcb96637102c55e1ab082949776 Binary files /dev/null and b/res/drawable/speak_now_level3.png differ diff --git a/res/drawable/speak_now_level4.png b/res/drawable/speak_now_level4.png new file mode 100644 index 0000000000000000000000000000000000000000..7363ca892516d9c03e96b02e08b3dcbc4b1f3c66 Binary files /dev/null and b/res/drawable/speak_now_level4.png differ diff --git a/res/drawable/speak_now_level5.png b/res/drawable/speak_now_level5.png new file mode 100644 index 0000000000000000000000000000000000000000..9034908f475a4006dad1bb7841a8818a5857947b Binary files /dev/null and b/res/drawable/speak_now_level5.png differ diff --git a/res/drawable/speak_now_level6.png b/res/drawable/speak_now_level6.png new file mode 100644 index 0000000000000000000000000000000000000000..3eaa9bdad585b60c4a177a01fe574b28bb6c8ac1 Binary files /dev/null and b/res/drawable/speak_now_level6.png differ diff --git a/res/drawable/voice_ime_background.9.png b/res/drawable/voice_ime_background.9.png new file mode 100644 index 0000000000000000000000000000000000000000..67802492aa3799dd0cdae8de0ac60ad7c8c3b639 Binary files /dev/null and b/res/drawable/voice_ime_background.9.png differ diff --git a/res/drawable/voice_swipe_hint.png b/res/drawable/voice_swipe_hint.png new file mode 100644 index 0000000000000000000000000000000000000000..bb88732510de9ee07ce4b8ad22c41b43b3d57424 Binary files /dev/null and b/res/drawable/voice_swipe_hint.png differ diff --git a/res/drawable/working.png b/res/drawable/working.png new file mode 100644 index 0000000000000000000000000000000000000000..6246a6d1cbcf1afabfa9af3dac348ab72100cd54 Binary files /dev/null and b/res/drawable/working.png differ diff --git a/res/layout/recognition_status.xml b/res/layout/recognition_status.xml new file mode 100644 index 0000000000000000000000000000000000000000..ea23824a16fa2973c765514871284b951e7f2059 --- /dev/null +++ b/res/layout/recognition_status.xml @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@android:color/black" + android:paddingBottom="0dip" + android:paddingLeft="0dip" + android:paddingRight="0dip" +> + + <LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/main_image" + android:orientation="vertical" + android:background="@drawable/voice_ime_background" + android:scaleType="fitXY" + android:layout_width="match_parent" + android:layout_height="180dip" + android:paddingBottom="2dip" + android:paddingTop="2dip" + > + + <TextView android:id="@+id/text" + android:text="@string/voice_initializing" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginTop="15dip" + android:textSize="28sp" + android:textColor="#ffffff" + android:layout_gravity="center_horizontal" + /> + + <ImageView android:id="@+id/image" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginTop="20dip" + android:layout_gravity="center_horizontal" + android:src="@drawable/mic_slash" + /> + + <ProgressBar android:id="@+id/progress" + android:layout_height="60dip" + android:layout_width="60dip" + android:layout_marginTop="20dip" + android:layout_gravity="center_horizontal" + android:visibility="gone" + android:indeterminate="true" + /> + + + + </LinearLayout> + + <LinearLayout android:id="@+id/button" + android:orientation="vertical" + android:background="@drawable/ok_cancel" + android:scaleType="fitXY" + android:layout_width="match_parent" + android:layout_height="42dip" + android:paddingLeft="1dip" + android:paddingRight="1dip" + > + + <TextView android:id="@+id/button_text" + android:text="@string/cancel" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_marginTop="7dip" + android:textSize="19sp" + android:textColor="#ffffff" + android:layout_gravity="center_horizontal" + /> + </LinearLayout> + +</LinearLayout> + diff --git a/res/layout/voice_punctuation_hint.xml b/res/layout/voice_punctuation_hint.xml new file mode 100644 index 0000000000000000000000000000000000000000..629a7f2b53d8314ad276878fec896d73c24b31da --- /dev/null +++ b/res/layout/voice_punctuation_hint.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/keyboard_suggest_strip"> + + <!-- TODO: Use dark mic icon. --> + <ImageView android:id="@+id/image" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:paddingLeft="8dip" + android:paddingRight="8dip" + android:layout_gravity="center_horizontal" + android:src="@drawable/ic_suggest_strip_microphone" + /> + + <TextView android:id="@+id/text" + android:text="@string/voice_punctuation_hint" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:paddingTop="2dip" + android:paddingRight="3dip" + android:textSize="13sp" + android:textColor="#888888" + android:layout_gravity="center_horizontal" + /> + +</LinearLayout> diff --git a/res/layout/voice_swipe_hint.xml b/res/layout/voice_swipe_hint.xml new file mode 100644 index 0000000000000000000000000000000000000000..4e8859a71ef296c20888a11e6ce446b5874aa4a0 --- /dev/null +++ b/res/layout/voice_swipe_hint.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@drawable/keyboard_suggest_strip" + android:gravity="center_horizontal" + android:paddingTop="2dip"> + + <TextView android:id="@+id/text" + android:text="@string/voice_swipe_hint" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:paddingTop="10dip" + android:paddingRight="6dip" + android:textSize="13sp" + android:textColor="#888888" + android:layout_gravity="center_horizontal" + /> + + <ImageView + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_gravity="center_horizontal" + android:src="@drawable/ic_suggest_strip_microphone" + /> + + <ImageView + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_gravity="center_horizontal" + android:src="@drawable/ic_suggest_strip_microphone_swipe" + /> + + +</LinearLayout> diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 078e3001e94fa13773b8bffe258d35db5c8d326d..75bdda15249bccb5586ca719e0f30359b99f6d1f 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"ZákladnÃ"</item> <item msgid="4894328801530136615">"PokroÄilé"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Uloženo"</string> <string name="alternates_for_a" msgid="2566516493365324765">"áà âãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"éěèêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ňñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"Äç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"PodrženÃm klávesy zobrazÃte diakritiku (ž, á atd.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"StisknutÃm klávesy ZpÄ›t ↶ můžete klávesnici kdykoli zavÅ™Ãt"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"PÅ™Ãstup k ÄÃslům a symbolům"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"Alt"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Hlasový vstup"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Pro váš jazyk aktuálnÄ› nenà hlasový vstup podporován, ale funguje v angliÄtinÄ›."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Hlasový vstup je experimentálnà funkce, která využÃvá sÃÅ¥ové rozpoznávánà řeÄi spoleÄnosti Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Chcete-li vypnout hlasový vstup, pÅ™ejdÄ›te do nastavenà klávesnice."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Chcete-li použÃt hlasový vstup, stisknÄ›te tlaÄÃtko mikrofonu nebo pÅ™ejeÄte prstem pÅ™es klávesnici na obrazovce."</string> + <string name="voice_listening" msgid="467518160751321844">"Mluvte"</string> + <string name="voice_working" msgid="6666937792815731889">"ProbÃhá zpracovánÃ"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Chyba. Zkuste to prosÃm znovu."</string> + <string name="voice_network_error" msgid="6649556447401862563">"PÅ™ipojenà se nezdaÅ™ilo."</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Chyba, Å™eÄ je pÅ™ÃliÅ¡ dlouhá."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problém se zvukem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Chyba serveru"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Nebyla detekována žádná Å™eÄ."</string> + <string name="voice_no_match" msgid="4285117547030179174">"Nebyly nalezeny žádné shody"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Hlasové vyhledávánà nenà nainstalováno"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"NápovÄ›da:"</b>" Chcete-li aktivovat hlasový vstup, pÅ™ejeÄte prstem pÅ™es klávesnici."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"NápovÄ›da:"</b>" PÅ™ÃÅ¡tÄ› zkuste vyslovit interpunkci, napÅ™Ãklad „teÄka“, „Äárka“ nebo „otaznÃk“."</string> + <string name="cancel" msgid="6830980399865683324">"ZruÅ¡it"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Hlasový vstup"</string> + <string name="auto_submit" msgid="9151008027068358518">"Po hlasovém vstupu automaticky odeslat"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"PÅ™i vyhledávánà nebo pÅ™echodu na dalÅ¡Ã pole automaticky stisknout Enter."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"OtevÅ™ete klávesnici"\n</b></font><font size="3">\n</font>"DotknÄ›te se jakéhokoli textového pole."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"ZavÅ™ete klávesnici"\n</b></font><font size="3">\n</font>"StisknÄ›te klávesu ZpÄ›t."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"PÅ™idrženÃm klávesy zobrazte možnosti"\n</b></font><font size="3">\n</font>"Použijte interpunkÄnà znaménka a diakritiku."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".eu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Metoda zadávánà dat"</string> </resources> diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index acefb020b294f897f198efc83097f9b89be6c935..70ba54729fc282f8102ad79c0a551ac7788f3e97 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Grundlæggende"</item> <item msgid="4894328801530136615">"Avanceret"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Gemt"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Hold en tast nede for at se accenter (ø, ö osv.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Tryk pÃ¥ tilbagetasten ↶ for nÃ¥r som helst at lukke for tastaturet"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"FÃ¥ adgang til tal og symboler"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Stemmeinput"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmeinput understøttes i øjeblikket ikke for dit sprog, men fungerer pÃ¥ engelsk."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Stemme-input er en funktion pÃ¥ forsøgsbasis, som bruger Googles netværksstemmegenkendelse."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"SlÃ¥ stemmeinput fra i indstillingerne for tastaturet."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"For at bruge stemme-input skal du trykke pÃ¥ knappen mikrofon eller lade glide fingeren hen over skærmtastaturet."</string> + <string name="voice_listening" msgid="467518160751321844">"Tal nu"</string> + <string name="voice_working" msgid="6666937792815731889">"Arbejder"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Fejl. Prøv igen."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Kunne ikke oprette forbindelse"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Fejl. For meget tale."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Lydproblem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Serverfejl"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Der høres ingen tale"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Der blev ikke fundet nogen matches"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Stemmesøgning er ikke installeret"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Tip:"</b>" Glid hen over tastaturet for at tale"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Tip:"</b>" Næste gang kan du forsøge at sige tegnsætning, f.eks. \"punktum\", \"komma\" eller \"spørgsmÃ¥lstegn\"."</string> + <string name="cancel" msgid="6830980399865683324">"Annuller"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Stemmeinput"</string> + <string name="auto_submit" msgid="9151008027068358518">"Send automatisk efter stemme"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Tryk automatisk pÃ¥ enter, nÃ¥r du søger eller gÃ¥r til det næste felt."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Ã…bn tastaturet"\n</b></font><font size="3">\n</font>"Tryk pÃ¥ et hvilket som helst tekstfelt."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Luk tastaturet"\n</b></font><font size="3">\n</font>"Tryk pÃ¥ Tilbagetasten."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tryk pÃ¥ og hold en tast nede for valgmuligheder"\n</b></font><font size="3">\n</font>"FÃ¥ adgang til tegnsætning og accenter."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Inputmetode"</string> </resources> diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index c4e7c9d589a6099e5208a2b23b5bdfc46a3a0146..1d821899e9048811db9f62ef50904cd67864d07b 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Standard"</item> <item msgid="4894328801530136615">"Erweitert"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Gespeichert"</string> <string name="alternates_for_a" msgid="2566516493365324765">"ä"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Zur Anzeige von Umlauten (ä, ö usw.) Taste gedrückt halten"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Zum Schließen der Tastatur ↶ drücken"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Auf Zahlen und Symbole zugreifen"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Spracheingabe"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spracheingaben werden derzeit nicht für Ihre Sprache unterstützt, funktionieren jedoch in Englisch."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Die Spracheingabe ist eine Funktion im Versuchsstadium, die die vernetzte Spracherkennung von Google verwendet."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Wenn Sie die Spracheingabe deaktivieren möchten, rufen Sie die Tastatureinstellungen auf."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Um die Spracheingabe zu verwenden, drücken Sie den Mikrofonknopf oder ziehen Sie Ihren Finger über die Bildschirmtastatur."</string> + <string name="voice_listening" msgid="467518160751321844">"Jetzt sprechen"</string> + <string name="voice_working" msgid="6666937792815731889">"Vorgang läuft"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Fehler. Versuchen Sie es erneut.."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Keine Verbindung"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Fehler – Text zu lang"</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Audio-Problem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Serverfehler"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Keine Sprache zu hören"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Keine Ãœbereinstimmungen gefunden"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Sprach-Suche nicht installiert"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Hinweis:"</b>" Ziehen Sie zum Sprechen den Finger über die Tastatur."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hinweis:"</b>" Versuchen Sie beim nächsten Mal, Satzzeichen wie \"Punkt\", \"Komma\" oder \"Fragezeichen\" per Sprachbefehl einzugeben."</string> + <string name="cancel" msgid="6830980399865683324">"Abbrechen"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Spracheingabe"</string> + <string name="auto_submit" msgid="9151008027068358518">"Nach Sprachaufnahme automatisch senden"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Drücken Sie auf die Eingabetaste, wenn Sie einen Suchvorgang durchführen oder zum nächsten Feld wechseln."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Tastatur öffnen"\n</b></font><font size="3">\n</font>"Berühren Sie ein beliebiges Textfeld."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Tastatur schließen"\n</b></font><font size="3">\n</font>"Drücken Sie die Taste \"Zurück\"."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Eine Taste für Optionen berühren und gedrückt halten"\n</b></font><font size="3">\n</font>"Greifen Sie auf Satzzeichen und Akzente zu."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Eingabemethode"</string> </resources> diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 46092903221423e38773ff6172eed9ab141698a2..acbe2945b94009a2aadd42f301875b58bb2f912f 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Βασική"</item> <item msgid="4894328801530136615">"ΣÏνθετη"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ΑποθηκεÏτηκε"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"ΚÏατήστε πατημÎνο Îνα πλήκτÏο για να δείτε τους τονισμÎνους χαÏακτήÏες (ø, ö, κ.Ï„.λ.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Πατήστε το πλήκτÏο Πίσω ↶ για να κλείσετε το πληκτÏολόγιο ανά πάσα στιγμή"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Î Ïόσβαση σε αÏιθμοÏÏ‚ και σÏμβολα"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ΑΒΓ"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Φωνητική είσοδος"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Η φωνητική είσοδος δεν υποστηÏίζεται αυτή τη στιγμή για τη γλώσσα σας, ωστόσο λειτουÏγεί στα Αγγλικά."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Οι φωνητικÎÏ‚ εντολÎÏ‚ είναι μια πειÏαματική λειτουÏγία, η οποία χÏησιμοποιεί τη δικτυακή αναγνώÏιση ομιλίας της Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Για να απενεÏγοποιήσετε τη φωνητική είσοδο, μεταβείτε στις Ïυθμίσεις πληκτÏολογίου."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Για να χÏησιμοποιήσετε τις φωνητικÎÏ‚ εντολÎÏ‚, πιÎστε το κουμπί μικÏοφώνου ή σÏÏετε το δάχτυλό σας κατά μήκος του πληκτÏολογίου της οθόνης."</string> + <string name="voice_listening" msgid="467518160751321844">"Μιλήστε Ï„ÏŽÏα"</string> + <string name="voice_working" msgid="6666937792815731889">"Σε λειτουÏγία"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Σφάλμα. Δοκιμάστε ξανά."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Δεν ήταν δυνατή η σÏνδεση"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Σφάλμα, πολλÎÏ‚ λÎξεις."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Î Ïόβλημα ήχου"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Σφάλμα διακομιστή"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Δεν ακοÏγεται ομιλία"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Δεν βÏÎθηκε καμία αντιστοίχιση"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Η Αναζήτηση με φωνή δεν εγκαταστάθηκε"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Υπόδειξη:"</b>" ΣÏÏετε κατά μήκος του πληκτÏολογίου για να μιλήσετε"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Υπόδειξη:"</b>" Την επόμενη φοÏά, Ï€Ïοσπαθήστε να Ï€ÏοφÎÏετε σημεία στίξης, όπως \"τελεία\", \"κόμμα\" ή \"εÏωτηματικό\"."</string> + <string name="cancel" msgid="6830980399865683324">"ΑκÏÏωση"</string> + <string name="ok" msgid="7898366843681727667">"ΟΚ"</string> + <string name="enable_voice" msgid="8299503298530853956">"Φωνητική είσοδος"</string> + <string name="auto_submit" msgid="9151008027068358518">"Αυτόματη υποβολή μετά από ήχο"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Πατήστε enter αυτόματα κατά την αναζήτηση ή τη μετάβαση στο επόμενο πεδίο."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Ανοίξτε το πληκτÏολόγιο"\n</b></font><font size="3">\n</font>"Αγγίξτε οποιοδήποτε πεδίο κειμÎνου."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Κλείστε το πληκτÏολόγιο"\n</b></font><font size="3">\n</font>"Πατήστε το πλήκτÏο Πίσω."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Αγγίξτε και κÏατήστε Îνα πλήκτÏο για οÏισμό επιλογών"\n</b></font><font size="3">\n</font>"Î Ïόσβαση στα σημεία στίξης και τονισμοÏ."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"ÎœÎθοδος εισόδου"</string> </resources> diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml index cb2f38399a70c4ff117280d040f369e0b01b8a3c..8a8ded8f91fed12410f2618be49b9183bc62e725 100644 --- a/res/values-es-rUS/strings.xml +++ b/res/values-es-rUS/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Básico"</item> <item msgid="4894328801530136615">"Avanzado"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: guardada"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Mantén una tecla presionada para ver los acentos (ø, ö, etc.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Pulsa la tecla hacia atrás ↶ para cerrar el teclado en cualquier momento"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Acceder a números y sÃmbolos"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Entrada por voz"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La entrada por voz no está admitida en tu idioma, pero sà funciona en inglés."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"La entrada por voz es una caracterÃstica experimental que utiliza la red de reconocimiento de voz de Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desactivar la entrada por voz, ve a configuración del teclado."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para realizar entrada por voz, presiona el botón del micrófono o desliza tus dedos por el teclado en pantalla."</string> + <string name="voice_listening" msgid="467518160751321844">"Habla ahora"</string> + <string name="voice_working" msgid="6666937792815731889">"Procesando"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Error. Vuelve a intentarlo."</string> + <string name="voice_network_error" msgid="6649556447401862563">"No se pudo establecer la conexión."</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Error, demasiado discurso."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problema de audio"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Error del servidor"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"No se oyó la voz"</string> + <string name="voice_no_match" msgid="4285117547030179174">"No se encontraron coincidencias"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Búsqueda por voz no instalada"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Sugerencia:"</b>" Deslizar en el teclado para hablar"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugerencia:"</b>" La próxima vez intenta decir la puntuación como \"punto\", \"coma\" o \"signo de pregunta\"."</string> + <string name="cancel" msgid="6830980399865683324">"Cancelar"</string> + <string name="ok" msgid="7898366843681727667">"Aceptar"</string> + <string name="enable_voice" msgid="8299503298530853956">"Entrada por voz"</string> + <string name="auto_submit" msgid="9151008027068358518">"Enviar automáticamente después del audio"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Presionar automáticamente Ingresar al buscar o ir al campo siguiente."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abrir el teclado"\n</b></font><font size="3">\n</font>"Tocar cualquier campo de texto."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Cerrar el teclado"\n</b></font><font size="3">\n</font>"Presionar la tecla Atrás."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tocar & y mantener presionada una tecla para las opciones"\n</b></font><font size="3">\n</font>"Acceder a puntuación y acentos."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Método de entrada"</string> </resources> diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 0b96bea767035d1f4f6589124af90891240caf8a..4977cbac509d148319a01d166c28a7063b12f662 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Básico"</item> <item msgid="4894328801530136615">"Avanzado"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Guardada"</string> <string name="alternates_for_a" msgid="2566516493365324765">"á"</string> <string name="alternates_for_e" msgid="3900510936875547555">"é"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Mantén pulsada una tecla para ver los caracteres acentuados (ø, ö, etc.)."</string> <string name="tip_dismiss" msgid="7585579046862204381">"Pulsa la tecla \"Atrás\" ↶ para cerrar el teclado en cualquier momento."</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Acceso a números y sÃmbolos"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Introducción de voz"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente la introducción de voz no está disponible en tu idioma, pero se puede utilizar en inglés."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"La introducción de voz es una función en fase experimental que utiliza la tecnologÃa de reconocimiento de voz en red de Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desactivar la función de introducción de voz, accede a la configuración del teclado."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para utilizar la función de introducción de voz, pulsa el botón de micrófono o desliza el dedo por el teclado en pantalla."</string> + <string name="voice_listening" msgid="467518160751321844">"Hablar ahora"</string> + <string name="voice_working" msgid="6666937792815731889">"Trabajando"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Se ha producido un error. Inténtalo de nuevo."</string> + <string name="voice_network_error" msgid="6649556447401862563">"No se ha podido establecer conexión."</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Se ha producido un error debido a un exceso de introducción de datos de voz."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problema de audio"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Error del servidor"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Ninguna conversación escuchada"</string> + <string name="voice_no_match" msgid="4285117547030179174">"No se ha encontrado ninguna coincidencia."</string> + <string name="voice_not_installed" msgid="5552450909753842415">"La búsqueda por voz no está instalada."</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Sugerencia:"</b>" muévete por el teclado para hablar."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugerencia:"</b>" la próxima vez, prueba a indicar signos de puntuación como, por ejemplo, \"punto\", \"coma\" o \"signo de interrogación\"."</string> + <string name="cancel" msgid="6830980399865683324">"Cancelar"</string> + <string name="ok" msgid="7898366843681727667">"Aceptar"</string> + <string name="enable_voice" msgid="8299503298530853956">"Introducción de voz"</string> + <string name="auto_submit" msgid="9151008027068358518">"Enviar automáticamente después de la introducción de voz"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Pulsar Intro automáticamente al buscar o al pasar al siguiente campo"</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abrir el teclado"\n</b></font><font size="3">\n</font>"Pulsa cualquier campo de texto."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Cerrar el teclado"\n</b></font><font size="3">\n</font>"Pulsa la tecla \"Atrás\"."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Mantén pulsada una tecla para acceder a las opciones."\n</b></font><font size="3">\n</font>"Accede a los signos de puntuación y a los acentos."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Método de introducción de texto"</string> </resources> diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 0bb70218c280337dc7c7fba5410d6e655db73800..f4834da1355d80ec75e5ba785b89a0662e00d2c4 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Simple"</item> <item msgid="4894328801530136615">"Avancé"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : enregistré"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Maintenir une touche enfoncée pour afficher les accents (à , é, etc.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Appuyez sur la touche Retour ↶ pour fermer le clavier à tout moment."</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Accéder aux chiffres et symboles"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Saisie vocale"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"La saisie vocale n\'est pas encore prise en charge pour votre langue, mais elle fonctionne en anglais."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"La saisie vocale est une fonctionnalité expérimentale qui fait appel à la reconnaissance vocale en réseau de Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Pour désactiver la saisie vocale, accédez aux paramètres du clavier."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Pour utiliser la saisie vocale, appuyez sur la touche du microphone ou faites glisser votre doigt sur le clavier à l\'écran."</string> + <string name="voice_listening" msgid="467518160751321844">"Parlez maintenant"</string> + <string name="voice_working" msgid="6666937792815731889">"Traitement en cours"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Erreur. Veuillez réessayer."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Connexion impossible"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Erreur, discours trop long."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problème audio"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Erreur serveur"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Aucune requête vocale détectée"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Aucune correspondance n\'a été trouvée."</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Recherche vocale non installée"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Astuce :"</b>" Faites glisser votre doigt sur le clavier pour parler."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Astuce :"</b>" La prochaine fois, essayez de prononcer la ponctuation, en énonçant des termes tels que \"point\", \"virgule\" ou \"point d\'interrogation\"."</string> + <string name="cancel" msgid="6830980399865683324">"Annuler"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Saisie vocale"</string> + <string name="auto_submit" msgid="9151008027068358518">"Envoi automatique après la saisie vocale"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Appuyez automatiquement sur Entrée pour effectuer une recherche ou accéder au champ suivant."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Ouvrir le clavier"\n</b></font><font size="3">\n</font>"Appuyez sur un champ de texte."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Fermer le clavier"\n</b></font><font size="3">\n</font>"Appuyez sur la touche Retour."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Appuyer sur une touche de manière prolongée pour accéder aux options"\n</b></font><font size="3">\n</font>"Accédez aux signes de ponctuation et aux accents."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Mode de saisie"</string> </resources> diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index 5e3b0e3e14af4c7410ff131e0c9bb8b962f186a1..94478ce88e742dd8babf4d0b481097429826f6de 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Base"</item> <item msgid="4894328801530136615">"Avanzate"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : parola salvata"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à á"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èé"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Tieni premuto un tasto per vedere le lettere con segni diacritici (ø, ö etc.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Premi il tasto Indietro ↶ per chiudere la tastiera"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Accedi a numeri e simboli"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Comandi vocali"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"I comandi vocali non sono attualmente supportati per la tua lingua ma funzionano in inglese."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"I comandi vocali sono una funzione sperimentale che utilizza il riconoscimento vocale in rete di Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Per disattivare i comandi vocali, vai alle impostazioni della tastiera."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Per utilizzare i comandi vocali, premi il pulsante del microfono o fai scorrere il dito sulla tastiera sullo schermo."</string> + <string name="voice_listening" msgid="467518160751321844">"Parla ora"</string> + <string name="voice_working" msgid="6666937792815731889">"Elaborazione in corso"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Errore. Riprova più tardi."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Impossibile connettersi."</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Errore: conversazione troppo lunga."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problema audio"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Errore del server"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Nessuna frase vocale rilevata"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Nessuna corrispondenza trovata"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Ricerca vocale non installata"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Suggerimento."</b>" Fai scorrere il dito sulla tastiera per parlare"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Suggerimento."</b>" La prossima volta, prova a pronunciare termini relativi alla punteggiatura come \"punto\", \"virgola\" o \"punto di domanda\"."</string> + <string name="cancel" msgid="6830980399865683324">"Annulla"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Comandi vocali"</string> + <string name="auto_submit" msgid="9151008027068358518">"Invia automaticamente dopo comando vocale"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Premi automaticamente \"Invio\" durante una ricerca o un passaggio al campo successivo."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Apertura tastiera"\n</b></font><font size="3">\n</font>"Tocca qualsiasi campo di testo."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Chiusura tastiera"\n</b></font><font size="3">\n</font>"Premi il tasto Indietro."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tocca e tieni premuto un tasto per le opzioni"\n</b></font><font size="3">\n</font>"Accesso a punteggiatura e accenti."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Metodo inserimento"</string> </resources> diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 133d64f2f73a6d5ca6db9d36fd9712872e2c3244..3f29eb96b50eed5f8d2db18fba92787f65e1da63 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"基本"</item> <item msgid="4894328801530136615">"高度"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:ä¿å˜ã—ã¾ã—ãŸ"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"ã‚ー長押ã—ã§ã‚¢ã‚¯ã‚»ãƒ³ãƒˆæ–‡å—を表示(øã€Ã¶ãªã©ï¼‰"</string> <string name="tip_dismiss" msgid="7585579046862204381">"戻るã‚ーã§ã‚ーボードを閉ã˜ã¾ã™"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"æ•°å—ã¨è¨˜å·"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"音声入力"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"音声入力ã¯ç¾åœ¨è‹±èªžã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã™ãŒã€æ—¥æœ¬èªžã«ã¯å¯¾å¿œã—ã¦ã„ã¾ã›ã‚“。"</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"音声入力ã¯Googleã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯éŸ³å£°èªè˜æŠ€è¡“を利用ã—ãŸè©¦é¨“段階ã®æ©Ÿèƒ½ã§ã™ã€‚"</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"音声入力をOFFã«ã™ã‚‹ã«ã¯ã€ã‚ーボードã®è¨å®šã‚’é–‹ãã¾ã™ã€‚"</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"音声入力ã™ã‚‹ã«ã¯ã€ãƒžã‚¤ã‚¯ãƒœã‚¿ãƒ³ã‚’押ã™ã‹ç”»é¢ã‚ーボードをスワイプã—ã¦ãã ã•ã„。"</string> + <string name="voice_listening" msgid="467518160751321844">"ãŠè©±ã—ãã ã•ã„"</string> + <string name="voice_working" msgid="6666937792815731889">"処ç†ä¸"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"エラーã§ã™ã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—ãã ã•ã„。"</string> + <string name="voice_network_error" msgid="6649556447401862563">"接続ã§ãã¾ã›ã‚“ã§ã—ãŸ"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"音声ãŒé•·ã™ãŽã¦ã‚¨ãƒ©ãƒ¼ã«ãªã‚Šã¾ã—ãŸã€‚"</string> + <string name="voice_audio_error" msgid="5072707727016414454">"オーディオエラー"</string> + <string name="voice_server_error" msgid="7807129913977261644">"サーãƒãƒ¼ã‚¨ãƒ©ãƒ¼"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"音声ãŒèžãå–ã‚Œã¾ã›ã‚“"</string> + <string name="voice_no_match" msgid="4285117547030179174">"該当ãªã—"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Voice Searchã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã¾ã›ã‚“"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"ヒント:"</b>" 音声入力ã™ã‚‹ã«ã¯ã‚ーボードをスワイプã—ã¾ã™"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"ヒント:"</b>" 次回ã¯å¥èªç‚¹ã¨ã—ã¦ã€Œperiodã€ã€ã€Œcommaã€ã€ã€Œquestion markã€ãªã©ã®éŸ³å£°å…¥åŠ›ã‚’試ã—ã¦ã¿ã¦ãã ã•ã„。"</string> + <string name="cancel" msgid="6830980399865683324">"ã‚ャンセル"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"音声入力"</string> + <string name="auto_submit" msgid="9151008027068358518">"入力後ã«è‡ªå‹•é€ä¿¡ã™ã‚‹"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"検索ã¾ãŸã¯æ¬¡ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã«é€²ã‚€éš›ã€Enterã‚ーãŒè‡ªå‹•çš„ã«æŠ¼ã•ã‚Œã¾ã™ã€‚"</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"ã‚ーボードを開ã"\n</b></font><font size="3">\n</font>"テã‚ストフィールドをタップã—ã¾ã™ã€‚"</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"ã‚ーボードを閉ã˜ã‚‹"\n</b></font><font size="3">\n</font>"[戻る]ã‚ーを押ã—ã¾ã™ã€‚"</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"ã‚ーを長押ã—ã—ã¦é¸æŠžã™ã‚‹"\n</b></font><font size="3">\n</font>"å¥èªç‚¹ã‚ーã¨ã‚¢ã‚¯ã‚»ãƒ³ãƒˆæ–‡å—を表示ã—ã¾ã™ã€‚"</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"入力方法"</string> </resources> diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index fe0da1767969e354be8794c3ea2af5a2bdf419be..1d9e0bd3065c125b5e478a675e9a3bc07ed42020 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"기본"</item> <item msgid="4894328801530136615">"ê³ ê¸‰"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : ì €ìž¥ë¨"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"키를 길게 누르면 악센트(ø, ö 등)ê°€ 표시ë©ë‹ˆë‹¤."</string> <string name="tip_dismiss" msgid="7585579046862204381">"키보드를 ë‹«ìœ¼ë ¤ë©´ ì–¸ì œë“ ì§€ 뒤로 키(↶)를 누르세요."</string> <string name="tip_access_symbols" msgid="6344098517525531652">"ìˆ«ìž ë° ê¸°í˜¸ 액세스"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"ìŒì„± ìž…ë ¥"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"ìŒì„± ìž…ë ¥ì€ í˜„ìž¬ ìžêµì–´ë¡œ 지ì›ë˜ì§€ 않으며 ì˜ì–´ë¡œ ìž‘ë™ë©ë‹ˆë‹¤."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"ìŒì„± ìž…ë ¥ì€ Googleì˜ ë„¤íŠ¸ì›Œí¬í™”ëœ ìŒì„± ì¸ì‹ì„ 사용하는 실험ì 기능입니다."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"ìŒì„± ìž…ë ¥ì„ ì‚¬ìš©í•˜ì§€ ì•Šìœ¼ë ¤ë©´ 키보드 ì„¤ì •ìœ¼ë¡œ ì´ë™í•˜ì„¸ìš”."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"ìŒì„± ìž…ë ¥ì„ ì‚¬ìš©í•˜ë ¤ë©´ 마ì´í¬ ë²„íŠ¼ì„ ëˆ„ë¥´ê±°ë‚˜ 터치 키보드 위로 ì†ê°€ë½ì„ 미ë„러지듯 움ì§ì´ì„¸ìš”."</string> + <string name="voice_listening" msgid="467518160751321844">"지금 시작하세요."</string> + <string name="voice_working" msgid="6666937792815731889">"ì¸ì‹ 중"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. 다시 ì‹œë„í•´ 보세요."</string> + <string name="voice_network_error" msgid="6649556447401862563">"ì—°ê²°í• ìˆ˜ 없습니다."</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"ìŒì„±ì„ 너무 ë§Žì´ ìž…ë ¥í–ˆìŠµë‹ˆë‹¤."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"오디오 ë¬¸ì œ"</string> + <string name="voice_server_error" msgid="7807129913977261644">"서버 오류"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"ìŒì„±ì´ ì¸ì‹ë˜ì§€ 않았습니다."</string> + <string name="voice_no_match" msgid="4285117547030179174">"ì¼ì¹˜í•˜ëŠ” í•ëª© ì—†ìŒ"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"ìŒì„± ê²€ìƒ‰ì´ ì„¤ì¹˜ë˜ì§€ 않았습니다."</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"ë„움ë§:"</b>" 키보드를 스와ì´í”„í•˜ê³ ë§í•˜ì„¸ìš”."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"ë„움ë§:"</b>" ë‹¤ìŒ ë²ˆì—는 \'마침표\', \'쉼표\', \'물ìŒí‘œ\'와 ê°™ì€ êµ¬ë‘ì ì„ ë§í•´ 보세요."</string> + <string name="cancel" msgid="6830980399865683324">"취소"</string> + <string name="ok" msgid="7898366843681727667">"확ì¸"</string> + <string name="enable_voice" msgid="8299503298530853956">"ìŒì„± ìž…ë ¥"</string> + <string name="auto_submit" msgid="9151008027068358518">"ìŒì„±ì„ ìž…ë ¥í•œ ë‹¤ìŒ ìžë™ ì œì¶œ"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"검색하거나 ë‹¤ìŒ ìž…ë ¥ëž€ìœ¼ë¡œ ì´ë™í• ë•Œ ìžë™ìœ¼ë¡œ Enter 키를 누릅니다."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"키보드 열기"\n</b></font><font size="3">\n</font>"아무 í…스트 ìž…ë ¥ëž€ì´ë‚˜ 터치하세요."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"키보드 닫기"\n</b></font><font size="3">\n</font>"\'뒤로\' 키를 누르세요."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"키를 길게 터치하여 옵션 보기"\n</b></font><font size="3">\n</font>"문장 부호 ë° ì•…ì„¼íŠ¸ ê¸°í˜¸ì— ì•¡ì„¸ìŠ¤í•˜ì„¸ìš”."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"ìž…ë ¥ 방법"</string> </resources> diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml index 28e84a504c7c73326afe5dcb89df0911a42478d5..971bc144565471dae2ab2c46fb4a9d9969fa1023 100644 --- a/res/values-nb/strings.xml +++ b/res/values-nb/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Grunnleggende"</item> <item msgid="4894328801530136615">"Avansert"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Lagret"</string> <string name="alternates_for_a" msgid="2566516493365324765">"åæáà âãä"</string> <string name="alternates_for_e" msgid="3900510936875547555">"éèêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Hold en tast nede for Ã¥ se aksenterte tegn (ø, ö, osv.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Trykk tilbakeknappen, ↶, for Ã¥ lukke tastaturet"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"FÃ¥ tilgang til tall og symboler"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Stemmedata"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Stemmedata hÃ¥ndteres foreløpig ikke pÃ¥ ditt sprÃ¥k, men fungerer pÃ¥ engelsk."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Talekommandoer er en eksperimentell funksjon som bruker Googles nettverksbaserte talegjenkjenning."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"GÃ¥ til innstillinger for tastatur for Ã¥ slÃ¥ av stemmedata."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Du bruker talekommandoer ved Ã¥ trykke pÃ¥ mikrofonknappen eller skyve fingeren over tastaturet pÃ¥ skjermen."</string> + <string name="voice_listening" msgid="467518160751321844">"Snakk nÃ¥"</string> + <string name="voice_working" msgid="6666937792815731889">"Arbeider"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Feil. Prøv pÃ¥ nytt."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Kunne ikke koble til"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Feil – for mye tale"</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Lydproblem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Tjenerfeil"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Ingen tale høres"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Ingen treff"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Talesøk ikke installert"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021">"Hint:"<b>" Sveip over tastaturet for Ã¥ snakke"</b></string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hint:"</b>" Neste gang kan du prøve Ã¥ tale inn tegnsettingen ved for eksempel Ã¥ si «punktum», «komma» eller «spørsmÃ¥lstegn»."</string> + <string name="cancel" msgid="6830980399865683324">"Avbryt"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Stemmedata"</string> + <string name="auto_submit" msgid="9151008027068358518">"Send inn automatisk etter tale"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Trykk Enter automatisk ved søk eller flytting til neste felt."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Ã…pne tastaturet"\n</b></font><font size="3">\n</font>"Trykk pÃ¥ et tekstfelt."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Lukke tastaturet"\n</b></font><font size="3">\n</font>"Trykk pÃ¥ tilbaketasten."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Trykk og hold nede en tast for flere valg"\n</b></font><font size="3">\n</font>"FÃ¥ tilgang til skilletegn og aksenter."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".info"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Inndatametode"</string> </resources> diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 085d50ac91dfbadff597bebefe5a661e1d093a7e..beeb0af115fe9829757af48c69257e5d0fcef553 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Basis"</item> <item msgid="4894328801530136615">"Geavanceerd"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Opgeslagen"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Houd een toets ingedrukt om diakritische tekens weer te geven (ø, ö, enzovoort)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Druk op elk gewenst moment op de toets Terug ↶ om het toetsenbord te sluiten"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Toegang tot cijfers en symbolen"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"Alt"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Spraakinvoer"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Spraakinvoer wordt momenteel niet ondersteund in uw taal, maar is wel beschikbaar in het Engels."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Spraakinvoer is een experimentele functie met de spraakherkenning van het Google-netwerk."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Als u spraakinvoer wilt uitschakelen, gaat u naar de toetsenbordinstellingen."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Als u spraakinvoer gebruikt, drukt u op de microfoonknop of schuift u uw vinger over het schermtoetsenbord."</string> + <string name="voice_listening" msgid="467518160751321844">"Nu spreken"</string> + <string name="voice_working" msgid="6666937792815731889">"Wordt uitgevoerd"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Fout. Probeer het opnieuw."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Kan geen verbinding maken"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Fout, te lange spraakinvoer."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Audioprobleem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Serverfout"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Geen spraak te horen"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Geen resultaten gevonden"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Voice Search is niet geïnstalleerd"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Hint:"</b>" schuif over het toetsenbord om te spreken"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Hint:"</b>" spreek de volgende keer interpunctie uit, zoals \'period\' (punt), \'comma\' (komma) of \'question mark\' (vraagteken)."</string> + <string name="cancel" msgid="6830980399865683324">"Annuleren"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Spraakinvoer"</string> + <string name="auto_submit" msgid="9151008027068358518">"Automatisch verzenden na spraak"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Drukt automatisch op Enter tijdens het zoeken of wanneer u naar het volgende veld wilt gaan."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Het toetsenbord openen"\n</b></font><font size="3">\n</font>"Raak een tekstveld aan."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Het toetsenbord sluiten"\n</b></font><font size="3">\n</font>"Druk op de terugtoets."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Een toets blijven aanraken voor opties"\n</b></font><font size="3">\n</font>"Toegang tot interpunctie en diakritische tekens."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Invoermethode"</string> </resources> diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index e3bac3d4c310b4e2566571263736847e43079e4f..2da0207837c39cfe10a0e256848ba0891bebc532 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Podstawowy"</item> <item msgid="4894328801530136615">"Zaawansowany"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Zapisano"</string> <string name="alternates_for_a" msgid="2566516493365324765">"Ä…"</string> <string name="alternates_for_e" msgid="3900510936875547555">"Ä™"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"Å„"</string> <string name="alternates_for_c" msgid="151699780720639892">"ć"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Przytrzymaj klawisz, aby wyÅ›wietlić znaki akcentowane (Ä…, ó itp.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"NaciÅ›nij klawisz cofania ↶, aby zamknąć klawiaturÄ™ w dowolnym momencie"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Przejdź do cyfr i symboli"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Wprowadzanie gÅ‚osowe"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Wprowadzanie gÅ‚osowe obecnie nie jest obsÅ‚ugiwane w Twoim jÄ™zyku, ale dziaÅ‚a w jÄ™zyku angielskim."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Wprowadzanie gÅ‚osowe to funkcja eksperymentalna wykorzystujÄ…ca funkcjÄ™ firmy Google umożliwiajÄ…cÄ… rozpoznawanie mowy przy użyciu sieci."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Aby wyÅ‚Ä…czyć wprowadzanie gÅ‚osowe, przejdź do ustawieÅ„ klawiatury."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Aby skorzystać z wprowadzania gÅ‚osowego, naciÅ›nij przycisk mikrofonu lub przesuÅ„ palcem po klawiaturze ekranowej."</string> + <string name="voice_listening" msgid="467518160751321844">"Mów teraz"</string> + <string name="voice_working" msgid="6666937792815731889">"DziaÅ‚a"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"BÅ‚Ä…d. Spróbuj ponownie."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Nie można nawiÄ…zać poÅ‚Ä…czenia"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"BÅ‚Ä…d, zbyt dÅ‚uga wypowiedź."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problem z dźwiÄ™kiem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"BÅ‚Ä…d serwera"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Nie wykryto mowy"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Nie znaleziono żadnych wyników"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Wyszukiwanie gÅ‚osowe nie jest zainstalowane"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Wskazówka:"</b>" przesuÅ„ palcem po klawiaturze, aby mówić."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Wskazówka:"</b>" nastÄ™pnym razem spróbuj wypowiadać nazwy znaków interpunkcyjnych: „kropkaâ€, „przecinek†lub „pytajnikâ€."</string> + <string name="cancel" msgid="6830980399865683324">"Anuluj"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Wprowadzanie gÅ‚osowe"</string> + <string name="auto_submit" msgid="9151008027068358518">"Automatyczne przesyÅ‚anie uruchamiane gÅ‚osem"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Podczas wyszukiwania lub przechodzenia do nastÄ™pnego pola automatycznie naciÅ›nij klawisz Enter."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Otwórz klawiaturÄ™"\n</b></font><font size="3">\n</font>"Dotknij dowolnego pola tekstowego."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Zamknij klawiaturÄ™"\n</b></font><font size="3">\n</font>"NaciÅ›nij klawisz Wróć."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Dotknij klawisza i przytrzymaj go, aby wyÅ›wietlić opcje"\n</b></font><font size="3">\n</font>"DostÄ™p do znaków przestankowych i akcentowanych."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Metoda wprowadzania"</string> </resources> diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 9ad88f3f6e49e0904b323f0a9972ac3dbcfef7be..ec397b66f3f7878556e6a127eb9169cb600259d4 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Básico"</item> <item msgid="4894328801530136615">"Avançados"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: Guardada"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Mantenha uma tecla premida para ver os acentos (ø, ö, etc.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Prima a tecla de retrocesso ↶ para fechar o teclado a qualquer momento"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Aceder a números e sÃmbolos"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Actualmente, a entrada de voz não é suportada para o seu idioma, mas funciona em inglês."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"A entrada de voz é uma funcionalidade experimental que utiliza o reconhecimento de voz em rede da Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desactivar a entrada de voz, aceda à s definições do teclado."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para utilizar a entrada de voz, prima o botão do microfone ou deslize o dedo no teclado do ecrã."</string> + <string name="voice_listening" msgid="467518160751321844">"Falar agora"</string> + <string name="voice_working" msgid="6666937792815731889">"A executar"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Erro. Tente novamente."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Não foi possÃvel ligar"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Erro, discurso demasiado longo."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problema de áudio"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Erro no servidor"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Nenhuma voz ouvida"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Não foram encontradas correspondências"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Pesquisa de voz não instalada"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Sugestão:"</b>" Deslize no teclado para falar"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Sugestão:"</b>" Da próxima vez, experimente dizer a pontuação como \"ponto final\", \"vÃrgula\" ou \"ponto de interrogação\"."</string> + <string name="cancel" msgid="6830980399865683324">"Cancelar"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Entrada de voz"</string> + <string name="auto_submit" msgid="9151008027068358518">"Enviar automaticamente depois da voz"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Premir automaticamente ENTER ao pesquisar ou avançar para o campo seguinte."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abra o teclado"\n</b></font><font size="3">\n</font>"Toque em qualquer campo de texto."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Feche o teclado"\n</b></font><font size="3">\n</font>"Prima a tecla \"Anterior\"."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Mantenha premida uma tecla para as opções"\n</b></font><font size="3">\n</font>"Aceder a pontuação e acentos."</string> @@ -93,6 +110,7 @@ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string> <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string> <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> + <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> </resources> diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 895a1be0125d423ccd20caf9d5c577c42c37f95e..64042b30b19d470cf6af17a4c4307261d21f02af 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Básico"</item> <item msgid="4894328801530136615">"Avançado"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Salvo"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Segure uma tecla pressionada para ver os acentos (ø, ö, etc.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Apertar a tecla voltar ↶ para fechar o teclado, em qualquer ponto"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Acessar números e sÃmbolos"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Entrada de voz"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"A entrada de voz não é suportada no momento para o seu idioma, mas funciona em inglês."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"A entrada de voz é um recurso experimental que usa o reconhecimento de fala de rede do Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Para desativar a entrada de voz, vá para as configurações do teclado."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Para usar a entrada de voz, pressione o botão com o microfone ou deslize o dedo sobre o teclado na tela."</string> + <string name="voice_listening" msgid="467518160751321844">"Fale agora"</string> + <string name="voice_working" msgid="6666937792815731889">"Trabalhando"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Erro. Tente novamente."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Não foi possÃvel conectar"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Erro, fala muito longa."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Problema com o áudio"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Erro do servidor"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Nenhuma fala ouvida"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Não há resultados compatÃveis"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"A pesquisa por voz não está instalada"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Dica:"</b>" Deslize sobre o teclado para falar"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Dica:"</b>" Da próxima vez, tente falar o nome da pontuação como \"ponto\", \"vÃrgula\" ou \"ponto de interrogação\"."</string> + <string name="cancel" msgid="6830980399865683324">"Cancelar"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Entrada de voz"</string> + <string name="auto_submit" msgid="9151008027068358518">"Enviar automaticamente depois de falar"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Pressione Enter automaticamente ao pesquisar ou ir para o próximo campo."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Abra o teclado"\n</b></font><font size="3">\n</font>"Toque em qualquer campo de texto."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Feche o teclado"\n</b></font><font size="3">\n</font>"Pressione a tecla Voltar."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Toque e mantenha pressionada uma tecla para ver as opções"\n</b></font><font size="3">\n</font>"Acesse a pontuação e os acentos."</string> @@ -93,6 +110,7 @@ <string name="popular_domain_2" msgid="3036812463748402878">".org"</string> <string name="popular_domain_3" msgid="8718639560809452028">".gov"</string> <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> + <string name="inputMethod" msgid="1653630062304567879">"Método de entrada"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> </resources> diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 7443114a3802c700af5d41622fda975420eda096..6e81f7d03f5e18d87cf54e83ec0a5a2af1b57040 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"ОÑновной"</item> <item msgid="4894328801530136615">"РаÑширенный"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Ñохранено"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Удерживайте клавишу, чтобы увидеть варианты Ñ Ð´Ð¸Ð°ÐºÑ€Ð¸Ñ‚Ð¸Ñ‡ÐµÑкими знаками (ø, ö и Ñ‚.д.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Ðажмите клавишу \"Ðазад\" ↶, чтобы закрыть клавиатуру в любой момент"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Открыть цифры и Ñимволы"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ÐБВ"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"ГолоÑовой ввод"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð³Ð¾Ð»Ð¾Ñового ввода не поддерживает ваш Ñзык, но вы можете пользоватьÑÑ ÐµÐ¹ на английÑком."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"ГолоÑовой ввод – ÑкÑÐ¿ÐµÑ€Ð¸Ð¼ÐµÐ½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° оÑнове технологии Ñетевого раÑÐ¿Ð¾Ð·Ð½Ð°Ð²Ð°Ð½Ð¸Ñ Ñ€ÐµÑ‡Ð¸ от Google."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð³Ð¾Ð»Ð¾Ñового ввода отключаетÑÑ Ð² наÑтройках клавиатуры."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Чтобы иÑпользовать голоÑовой ввод, нажмите кнопку микрофона или проведите пальцем по Ñкранной клавиатуре."</string> + <string name="voice_listening" msgid="467518160751321844">"Говорите"</string> + <string name="voice_working" msgid="6666937792815731889">"ВыполнÑетÑÑ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Ошибка. Повторите попытку."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Ошибка подключениÑ"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Слишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ñ„Ñ€Ð°Ð·Ð°"</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Ðеполадка Ñо звуком"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Ошибка Ñервера"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Речи не Ñлышно"</string> + <string name="voice_no_match" msgid="4285117547030179174">"СоответÑтвий не найдено"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"ГолоÑовой поиÑк не уÑтановлен"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Совет"</b>". Проведите пальцем по клавиатуре Ð´Ð»Ñ Ð³Ð¾Ð»Ð¾Ñового ввода."</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Совет"</b>". Ð’ Ñледующий раз проговаривайте знаки препинаниÑ, например \"точка\", \"запÑтаÑ\", \"вопроÑительный знак\"."</string> + <string name="cancel" msgid="6830980399865683324">"Отмена"</string> + <string name="ok" msgid="7898366843681727667">"ОК"</string> + <string name="enable_voice" msgid="8299503298530853956">"ГолоÑовой ввод"</string> + <string name="auto_submit" msgid="9151008027068358518">"ÐвтоматичеÑки отправлÑÑ‚ÑŒ по окончании голоÑового ввода"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"ÐвтоматичеÑки нажимать \"Ввод\" при поиÑке или переходе к Ñледующему полю."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Откройте клавиатуру"\n</b></font><font size="3">\n</font>"Ðажмите на любое текÑтовое поле."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Закрытие клавиатуры"\n</b></font><font size="3">\n</font>"Ðажмите клавишу \"Ðазад\"."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Ðажмите и удерживайте клавишу Ð´Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° параметров"\n</b></font><font size="3">\n</font>"ДоÑтуп к пунктуационным и диакритичеÑким знакам."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"СпоÑоб ввода"</string> </resources> diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index b56a71806ca94057e7a919169c601bd5a10d5b54..8027eb3f7d811ed28a033382316b1d2e113fcc2b 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Grundinställningar"</item> <item msgid="4894328801530136615">"Avancerade"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>: sparat"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"HÃ¥ll nere en tangent om du vill visa accenter (ø, ö, etc.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Tryck pÃ¥ Tillbaka ↶ om du vill stänga tangentbordet"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"För siffror och symboler"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Röstindata"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Röstindata stöds inte pÃ¥ ditt sprÃ¥k än, men tjänsten fungerar pÃ¥ engelska."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Röstinmatning är en funktion pÃ¥ experimentstadiet som använder Googles nätverks taligenkänning."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Om du vill stänga av röstindata öppnar du inställningarna för tangentbordet."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Om du vill använda röstinmatning trycker du pÃ¥ mikrofonknappen eller drar fingret över tangentbordet pÃ¥ skärmen."</string> + <string name="voice_listening" msgid="467518160751321844">"Tala nu"</string> + <string name="voice_working" msgid="6666937792815731889">"Fungerar"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Fel. Försök igen."</string> + <string name="voice_network_error" msgid="6649556447401862563">"Det gick inte att ansluta"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Fel, för mycket tal."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Ljudproblem"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Serverfel"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"Hörde inget tal"</string> + <string name="voice_no_match" msgid="4285117547030179174">"Inga träffar hittades"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Voice Search är inte installerat"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Tips!"</b>" Dra över tangentbordet om du vill tala"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Tips!"</b>" Nästa gÃ¥ng testar du att säga skiljetecknen, som \"punkt\", \"komma\" eller \"frÃ¥getecken\"."</string> + <string name="cancel" msgid="6830980399865683324">"Avbryt"</string> + <string name="ok" msgid="7898366843681727667">"OK"</string> + <string name="enable_voice" msgid="8299503298530853956">"Röstindata"</string> + <string name="auto_submit" msgid="9151008027068358518">"Skicka automatiskt efter röst"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Tryck automatiskt pÃ¥ retur vid sökning eller när du fortsätter till nästa fält."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Öppna tangentbordet"\n</b></font><font size="3">\n</font>"Tryck pÃ¥ ett textfält."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Stäng tangentbordet"\n</b></font><font size="3">\n</font>"Tryck pÃ¥ Tillbaka."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Tryck länge pÃ¥ en tangent om du vill se alternativ"\n</b></font><font size="3">\n</font>"Använda skiljetecken och accenter."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"Indatametod"</string> </resources> diff --git a/res/values-tr/donottranslate.xml b/res/values-tr/donottranslate.xml index f206e4c43888cddb72854b5d498f23e41f88bbbe..2154c16bb0db939b8c2df90f0c569eee8c829dc1 100644 --- a/res/values-tr/donottranslate.xml +++ b/res/values-tr/donottranslate.xml @@ -20,4 +20,4 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- Accented characters related to "g" --> <string name="alternates_for_g">ÄŸ</string> -</resources> +</resources> \ No newline at end of file diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 6f17f69c4f6dc378de8d2d29592282af121e6ba6..069abeb1449949f86927e40e575c097a0e54520e 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"Temel"</item> <item msgid="4894328801530136615">"GeliÅŸmiÅŸ"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g> : Kaydedildi"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"Vurguları görmek için bir tuÅŸu basılı tutun (ø, ö, v.b.)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"Klavyeyi herhangi bir anda kapatmak için geri tuÅŸuna ↶ basın"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"Sayılara ve simgelere eriÅŸin"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"Ses giriÅŸi"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"Ses giriÅŸi, ÅŸu anda sizin diliniz için desteklenmiyor ama Ä°ngilizce dilinde kullanılabilir."</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"Ses giriÅŸi, Google\'ın aÄŸ baÄŸlantılı ses tanıma iÅŸlevini kullanan deneysel bir özelliktir."</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"Ses giriÅŸini kapatmak için klavye ayarlarına gidin."</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"Ses giriÅŸini kullanmak için mikrofon düğmesine basın veya parmağınızı dokunmatik klavye üzerinde kaydırın."</string> + <string name="voice_listening" msgid="467518160751321844">"Åžimdi konuÅŸun"</string> + <string name="voice_working" msgid="6666937792815731889">"Çalışıyor"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"Hata. Lütfen tekrar deneyin."</string> + <string name="voice_network_error" msgid="6649556447401862563">"BaÄŸlanamadı"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"Hata, çok uzun konuÅŸma."</string> + <string name="voice_audio_error" msgid="5072707727016414454">"Ses sorunu"</string> + <string name="voice_server_error" msgid="7807129913977261644">"Sunucu hatası"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"KonuÅŸma duyulmadı"</string> + <string name="voice_no_match" msgid="4285117547030179174">"EÅŸleÅŸme bulunamadı"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"Sesle arama yüklenmedi"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"Ä°pucu:"</b>" KonuÅŸmak için parmağınızı klavye üzerinde kaydırın"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"Ä°pucu:"</b>" Sonraki sefer, \"nokta\", \"virgül\" veya \"soru iÅŸareti\" gibi noktalama iÅŸaretlerini telaffuz etmeyi deneyin."</string> + <string name="cancel" msgid="6830980399865683324">"Ä°ptal"</string> + <string name="ok" msgid="7898366843681727667">"Tamam"</string> + <string name="enable_voice" msgid="8299503298530853956">"Ses giriÅŸi"</string> + <string name="auto_submit" msgid="9151008027068358518">"Sesten sonra otomatik gönder"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"Arama yaparken veya bir sonraki alana giderken enter tuÅŸuna otomatik olarak basın."</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"Klavyeyi açın"\n</b></font><font size="3">\n</font>"Herhangi bir metin alanına dokunun."</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"Klavyeyi kapatın"\n</b></font><font size="3">\n</font>"Geri tuÅŸuna basın."</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"Seçenekler için bir tuÅŸa dokunun ve basılı tutun"\n</b></font><font size="3">\n</font>"Noktalama ve vurgulama iÅŸaretlerine eriÅŸin."</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"GiriÅŸ yöntemi"</string> </resources> diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index f1c041805883d75d76428a8614df9e8366b0dcbd..034f32739a81f0bdec14664edb7e0a58efc3520e 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"基本模å¼"</item> <item msgid="4894328801530136615">"高级模å¼"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已ä¿å˜"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -84,6 +78,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"è¯éŸ³è¾“å…¥"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"è¯éŸ³è¾“入功能当å‰è¿˜ä¸æ”¯æŒæ‚¨çš„è¯è¨€ï¼Œæ‚¨åªèƒ½è¾“入英è¯è¯éŸ³ã€‚"</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"è¯éŸ³è¾“入是一项试验性的功能,它采用了 Google 的网络è¯éŸ³è¯†åˆ«åŠŸèƒ½ã€‚"</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"è¦å…³é—è¯éŸ³è¾“入功能,请转至键盘设置。"</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"è¦ä½¿ç”¨è¯éŸ³è¾“入,请按麦克风按钮或者在å±å¹•é”®ç›˜ä¸Šæ»‘动手指。"</string> + <string name="voice_listening" msgid="467518160751321844">"请开始说è¯"</string> + <string name="voice_working" msgid="6666937792815731889">"æ£åœ¨å¤„ç†"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"出错,请é‡è¯•ã€‚"</string> + <string name="voice_network_error" msgid="6649556447401862563">"æ— æ³•è¿žæŽ¥"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"出错,è¯éŸ³è¿‡é•¿ã€‚"</string> + <string name="voice_audio_error" msgid="5072707727016414454">"音频问题"</string> + <string name="voice_server_error" msgid="7807129913977261644">"æœåŠ¡å™¨å‡ºé”™"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"未å¬åˆ°è¯éŸ³"</string> + <string name="voice_no_match" msgid="4285117547030179174">"未找到匹é…项"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"未安装è¯éŸ³æœç´¢"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"æ示:"</b>"在键盘上滑动手指å¯æ¿€æ´»è¯éŸ³åŠŸèƒ½"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"æ示:"</b>"ç¨åŽï¼Œè¯·å°è¯•ä½¿ç”¨è¯éŸ³è¾“å…¥æ ‡ç‚¹ç¬¦å·ï¼Œå¦‚“å¥å·â€ã€â€œé€—å·â€æˆ–“问å·â€ã€‚"</string> + <string name="cancel" msgid="6830980399865683324">"å–消"</string> + <string name="ok" msgid="7898366843681727667">"确定"</string> + <string name="enable_voice" msgid="8299503298530853956">"è¯éŸ³è¾“å…¥"</string> + <string name="auto_submit" msgid="9151008027068358518">"è¯éŸ³ç»“æŸåŽè‡ªåŠ¨æ交"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"æœç´¢æˆ–转到下一å—段时自动按 Enter。"</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"打开键盘"\n</b></font><font size="3">\n</font>"轻触任æ„文本å—段。"</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"å…³é—键盘"\n</b></font><font size="3">\n</font>"按“返回â€é”®ã€‚"</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>"按ä½æŸä¸ªé”®å¯å¼€å¯å…¶ä»–å—符选项"\n</b></font><font size="3">\n</font>"è®¿é—®æ ‡ç‚¹å’Œé‡éŸ³ç¬¦å·ã€‚"</string> @@ -95,4 +113,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"输入法"</string> </resources> diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 550a735dfb29bd31d0023da9f38c915b725ab548..9603c6b8030f340423c551db5713b59a7a026485 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -47,12 +47,6 @@ <item msgid="1669461741568287396">"基本模å¼"</item> <item msgid="4894328801530136615">"進階模å¼"</item> </string-array> - <string name="prediction_none" msgid="2472795101338047944">"0"</string> - <string name="prediction_basic" msgid="8407291081834155558">"1"</string> - <string name="prediction_full" msgid="3765102052052510268">"2"</string> - <!-- no translation found for prediction_modes_values:0 (579944677836100459) --> - <!-- no translation found for prediction_modes_values:1 (7214414132844804570) --> - <!-- no translation found for prediction_modes_values:2 (6678546276084314171) --> <string name="added_word" msgid="8993883354622484372">"<xliff:g id="WORD">%s</xliff:g>:已儲å˜"</string> <string name="alternates_for_a" msgid="2566516493365324765">"à áâãäåæ"</string> <string name="alternates_for_e" msgid="3900510936875547555">"èéêë"</string> @@ -63,7 +57,6 @@ <string name="alternates_for_n" msgid="6257322556221886400">"ñ"</string> <string name="alternates_for_c" msgid="151699780720639892">"ç"</string> <string name="alternates_for_y" msgid="1722776806607271199">"ýÿ"</string> - <string name="key_i" msgid="6483655742552255124">"i"</string> <string name="tip_long_press" msgid="6101270866284343344">"按ä½æŒ‰éµå¯æŸ¥çœ‹é‡éŸ³ç¬¦è™Ÿ (øã€Ã¶ ç‰)"</string> <string name="tip_dismiss" msgid="7585579046862204381">"隨時å¯ä»¥é€éŽæŒ‰å¾Œé€€éµ ↶ 關閉éµç›¤"</string> <string name="tip_access_symbols" msgid="6344098517525531652">"使用數å—和符號"</string> @@ -84,6 +77,30 @@ <string name="label_phone_key" msgid="4275497665515080551">"123"</string> <string name="label_alpha_key" msgid="8864943487292437456">"ABC"</string> <string name="label_alt_key" msgid="2846315350346694811">"ALT"</string> + <string name="voice_warning_title" msgid="4419354150908395008">"語音輸入"</string> + <string name="voice_warning_locale_not_supported" msgid="637923019716442333">"語音輸入目å‰ä¸æ”¯æ´æ‚¨çš„語言,但是å¯ä»¥è¾¨è˜è‹±æ–‡ã€‚"</string> + <string name="voice_warning_may_not_understand" msgid="4611518823070986445">"èªžéŸ³è¼¸å…¥é€™é …å¯¦é©—åŠŸèƒ½é‹ç”¨äº† Google 的網路語音辨è˜ç³»çµ±ã€‚"</string> + <string name="voice_warning_how_to_turn_off" msgid="5652369578498701761">"è«‹å‰å¾€éµç›¤è¨å®šä¾†é—œé–‰èªžéŸ³è¼¸å…¥ã€‚"</string> + <string name="voice_hint_dialog_message" msgid="6892342981545727994">"如è¦ä½¿ç”¨èªžéŸ³è¼¸å…¥ï¼ŒæŒ‰ä¸‹ [麥克風] 按鈕,或將手指滑éŽèž¢å¹•å°éµç›¤å³å¯ã€‚"</string> + <string name="voice_listening" msgid="467518160751321844">"請說話"</string> + <string name="voice_working" msgid="6666937792815731889">"辨è˜ä¸"</string> + <!-- no translation found for voice_initializing (661962047129906646) --> + <skip /> + <string name="voice_error" msgid="5140896300312186162">"發生錯誤,請å†è©¦ä¸€æ¬¡ã€‚"</string> + <string name="voice_network_error" msgid="6649556447401862563">"無法連線"</string> + <string name="voice_too_much_speech" msgid="5746973620134227376">"錯誤:語音內容éŽé•·ã€‚"</string> + <string name="voice_audio_error" msgid="5072707727016414454">"音訊å•é¡Œ"</string> + <string name="voice_server_error" msgid="7807129913977261644">"伺æœå™¨éŒ¯èª¤"</string> + <string name="voice_speech_timeout" msgid="8461817525075498795">"沒有è½åˆ°ä»»ä½•è²éŸ³"</string> + <string name="voice_no_match" msgid="4285117547030179174">"找ä¸åˆ°ç›¸ç¬¦çš„é …ç›®"</string> + <string name="voice_not_installed" msgid="5552450909753842415">"未安è£èªžéŸ³æœå°‹"</string> + <string name="voice_swipe_hint" msgid="6943546180310682021"><b>"æ示:"</b>"滑éŽéµç›¤å³å¯èªªè©±"</string> + <string name="voice_punctuation_hint" msgid="1611389463237317754"><b>"æ示:"</b>"下次å¯å˜—試說出標點符號,例如「å¥è™Ÿã€ã€ã€Œé€—號ã€æˆ–「å•è™Ÿã€ã€‚"</string> + <string name="cancel" msgid="6830980399865683324">"å–消"</string> + <string name="ok" msgid="7898366843681727667">"確定"</string> + <string name="enable_voice" msgid="8299503298530853956">"語音輸入"</string> + <string name="auto_submit" msgid="9151008027068358518">"說話後自動æ交"</string> + <string name="auto_submit_summary" msgid="4961875269610384226">"æœå°‹æˆ–å‰å¾€ä¸‹ä¸€å€‹æ¬„ä½æ™‚自動按下輸入。"</string> <string name="open_the_keyboard" msgid="2215920976029260466"><font size="17"><b>"é–‹å•Ÿéµç›¤"\n</b></font><font size="3">\n</font>"輕觸任何文å—欄ä½ã€‚"</string> <string name="close_the_keyboard" msgid="6251022259044940103"><font size="17"><b>"關閉éµç›¤"\n</b></font><font size="3">\n</font>"按下 Back éµã€‚"</string> <string name="touch_and_hold" msgid="6154166367273010534"><font size="17"><b>\n"輕觸並按ä½æŒ‰éµé–‹å•Ÿé¸é …"</b></font><font size="3">\n</font>"輸入標點與輕é‡éŸ³ã€‚"</string> @@ -95,4 +112,5 @@ <string name="popular_domain_4" msgid="35359437471311470">".edu"</string> <!-- no translation found for language_selection_title (530749890984542339) --> <skip /> + <string name="inputMethod" msgid="7854532062009028116">"輸入方å¼"</string> </resources> diff --git a/res/values/bools.xml b/res/values/bools.xml index 3a951b2719aa77fe4262abd358fd684429666ee7..ebe2f04e522a41fe2242c34f99d1e61f0314a96f 100644 --- a/res/values/bools.xml +++ b/res/values/bools.xml @@ -23,4 +23,6 @@ <!-- Whether this input method should be used as the default for a locale. Override it for latin languages. --> <bool name="im_is_default">false</bool> + <!-- Whether or not voice input is enabled by default. --> + <bool name="voice_input_default">true</bool> </resources> diff --git a/res/values/donottranslate.xml b/res/values/donottranslate.xml index c6941949edbd30782a9a1483c722f6f4a63ef21f..d9649f3b195d9e036c9fe296dbacb69126f9aad3 100644 --- a/res/values/donottranslate.xml +++ b/res/values/donottranslate.xml @@ -32,6 +32,4 @@ <string name="alternates_for_z"></string> <!-- Accented characters related to "l" --> <string name="alternates_for_l"></string> - <!-- Accented characters related to "g" --> - <string name="alternates_for_g"></string> </resources> diff --git a/res/values/keycodes.xml b/res/values/keycodes.xml index e46e4bc369db768c3b7e994fe47942fa9125f673..8156c0e079c3703c900dbf58ba40a6794d56ef82 100644 --- a/res/values/keycodes.xml +++ b/res/values/keycodes.xml @@ -20,5 +20,5 @@ <resources> <!-- Keycode for F1 (function) key. This one switches between language switch & comma/.com --> - <integer name="key_f1">-102</integer> + <integer name="key_f1">-103</integer> </resources> diff --git a/res/values/strings.xml b/res/values/strings.xml index 3b3965e09f957ba96547582495fbda712eaa3c6a..90cd6d42919865d7e62ac14b00ac40d50d13b38c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -93,13 +93,13 @@ </string-array> <!-- Don't translate --> - <string name="prediction_none" >0</string> + <string name="prediction_none" translatable="false">0</string> <!-- Don't translate --> - <string name="prediction_basic">1</string> + <string name="prediction_basic" translatable="false">1</string> <!-- Don't translate --> - <string name="prediction_full" >2</string> + <string name="prediction_full" translatable="false">2</string> - <string-array name="prediction_modes_values"> + <string-array name="prediction_modes_values" translatable="false"> <item>@string/prediction_none</item> <item>@string/prediction_basic</item> <item>@string/prediction_full</item> @@ -125,13 +125,7 @@ <string name="alternates_for_c">ç</string> <!-- Accented forms of "y" --> <string name="alternates_for_y">ýÿ</string> - - <!-- Label to display on the lower "i" key. - Usually you don't need to modify this value, but if your locale requires some variant - for this character (e.g. \\u131 "Latin Small Letter Dotoless i"), please modify this - value. --> - <string name="key_i">i</string> - + <!-- Tip to long press on keys --> <string name="tip_long_press">Hold a key down to see accents (ø, ö, etc.)</string> <!-- Tip to dismiss keyboard --> @@ -185,6 +179,85 @@ <!-- Label for ALT modifier key. Must be short to fit on key! --> <string name="label_alt_key">ALT</string> + <!-- Voice related labels --> + + <!-- Title of the warning dialog that shows when a user initiates voice input for + the first time. --> + <string name="voice_warning_title">Voice input</string> + + <!-- Message that gets put at the top of the warning dialog if the user is attempting to use + voice input in a currently unsupported locale. Voice input will work for such a user, + but it will only recognize them in English. --> + <string name="voice_warning_locale_not_supported">Voice input is not currently supported for your language, but does work in English.</string> + + <!-- Message of the warning dialog that shows when a user initiates voice input for + the first time, or turns it on in settings. --> + <string name="voice_warning_may_not_understand">Voice input is an experimental feature using Google\'s networked speech recognition.</string> + + <!-- An additional part of the warning dialog for voice input that only shows when the user + actually initiates voice input, rather than just turning it on in settings. --> + <string name="voice_warning_how_to_turn_off">To turn off voice input, go to keyboard settings.</string> + + <!-- Message to show when user clicks the swiping hint (which says + "Swipe across keyboard to speak"). Also shown when enabling settings. --> + <string name="voice_hint_dialog_message">To use voice input, press the microphone button or slide your finger across the on-screen keyboard.</string> + + <!-- Short message to tell the user the system is ready for them to speak. --> + <string name="voice_listening">Speak now</string> + + <!-- Short message shown after the user finishes speaking. --> + <string name="voice_working">Working</string> + + <!-- Short message shown before the user should speak. --> + <string name="voice_initializing"></string> + + <!-- Short message shown when a generic error occurs. --> + <string name="voice_error">Error. Please try again.</string> + + <!-- Short message shown for a network error. --> + <string name="voice_network_error">Couldn\'t connect</string> + + <!-- Short message shown for a network error where the utterance was really long, + in which case we should suggest that the user speak less. --> + <string name="voice_too_much_speech">Error, too much speech.</string> + + <!-- Short message shown for an audio error. --> + <string name="voice_audio_error">Audio problem</string> + + <!-- Short message shown for an error with the voice server. --> + <string name="voice_server_error">Server error</string> + + <!-- Short message shown when no speech is heard. --> + <string name="voice_speech_timeout">No speech heard</string> + + <!-- Short message shown when the server couldn't parse any speech. --> + <string name="voice_no_match">No matches found</string> + + <!-- Short message shown when the user initiates voice and voice + search is not installed. --> + <string name="voice_not_installed">Voice search not installed</string> + + <!-- Short hint shown in candidate view to explain voice input. --> + <string name="voice_swipe_hint"><b>Hint:</b> Swipe across keyboard to speak</string> + + <!-- Short hint shown in candidate view to explain that user can speak punctuation. --> + <string name="voice_punctuation_hint"><b>Hint:</b> Next time, try speaking punctuation like \"period\", \"comma\", or \"question mark\".</string> + + <!-- Label on button to stop recognition. Must be short to fit on button. --> + <string name="cancel">Cancel</string> + + <!-- Label on button when an error occurs --> + <string name="ok">OK</string> + + <!-- Preferences item for enabling speech input --> + <string name="enable_voice">Voice input</string> + + <!-- Press the "enter" key after the user speaks. Option on settings.--> + <string name="auto_submit">Auto submit after voice</string> + + <!-- Press the "enter" key after the user speaks. Summary of option in settings.--> + <string name="auto_submit_summary">Automatically press enter when searching or going to the next field.</string> + <!-- IME Tutorial screen (ROMAN) --><skip /> <!-- appears above image showing the user to click on a TextView to show the IME --> <string name="open_the_keyboard"><font size="17"><b>Open the keyboard\n</b></font><font size="3">\n</font>Touch any text field.</string> @@ -197,7 +270,7 @@ <!-- appears above image showing how to access keyboard settings --> <string name="keyboard_settings"><font size="17"><b>Keyboard settings\n</b></font><font size="3">\n</font>Touch \u0026 hold the <b>\?123\</b> key.</string> - + <!-- popular web domains for the locale - most popular, displayed on the keyboard --> <string name="popular_domain_0">".com"</string> <!-- popular web domains for the locale - item 1, displayed in the popup --> @@ -208,6 +281,9 @@ <string name="popular_domain_3">".gov"</string> <!-- popular web domains for the locale - item 4, displayed in the popup --> <string name="popular_domain_4">".edu"</string> + + <!-- Menu item for launching Input method switcher --> + <string name="inputMethod">Input method</string> <!-- Title for input language selection screen --> <string name="language_selection_title">Select input languages</string> diff --git a/res/xml-de/kbd_qwerty.xml b/res/xml-de/kbd_qwerty.xml index 2da609ca82a379472894adccb9c38ad627c383f0..3fb8f52262237d41ae4a14584d0415698729729f 100755 --- a/res/xml-de/kbd_qwerty.xml +++ b/res/xml-de/kbd_qwerty.xml @@ -165,4 +165,81 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> + + <Row android:keyboardMode="@+id/mode_normal_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-102" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_url_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="15%p"/> + <Key android:keyLabel="/" android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="15%p" android:isRepeatable="true"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_email_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@" android:keyWidth="15%p"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="15%p" android:isRepeatable="true"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_im_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-102" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + </Keyboard> diff --git a/res/xml-fr/kbd_qwerty.xml b/res/xml-fr/kbd_qwerty.xml index 7c1b24bada7bc839bcd4d3ebc6c63136ab9fe88e..fef260d1da5ca75c3485a5f3edd32db5a7f398c3 100644 --- a/res/xml-fr/kbd_qwerty.xml +++ b/res/xml-fr/kbd_qwerty.xml @@ -166,5 +166,81 @@ android:popupKeyboard="@xml/popup_smileys" android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> + + <Row android:keyboardMode="@+id/mode_normal_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-102" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_url_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="15%p"/> + <Key android:keyLabel="/" android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="15%p" android:isRepeatable="true"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_email_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@" android:keyWidth="15%p"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="15%p" android:isRepeatable="true"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + + <Row android:keyboardMode="@+id/mode_im_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-102" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> </Keyboard> - \ No newline at end of file + diff --git a/res/xml/kbd_qwerty.xml b/res/xml/kbd_qwerty.xml index d914f46d28d28bdf834fb27bc34d89f0ec07ffc2..552e7e54406c3265cb87f1ffaa45f33a4db2fcf0 100755 --- a/res/xml/kbd_qwerty.xml +++ b/res/xml/kbd_qwerty.xml @@ -46,7 +46,7 @@ android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="@string/alternates_for_u" /> - <Key android:keyLabel="@string/key_i" + <Key android:codes="105" android:keyLabel="i" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="@string/alternates_for_i" /> @@ -70,14 +70,11 @@ android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="@string/alternates_for_d"/> <Key android:codes="102" android:keyLabel="f"/> - <Key android:codes="103" android:keyLabel="g" - android:popupKeyboard="@xml/kbd_popup_template" - android:popupCharacters="@string/alternates_for_g"/> - /> + <Key android:codes="103" android:keyLabel="g"/> <Key android:codes="104" android:keyLabel="h"/> <Key android:codes="106" android:keyLabel="j"/> <Key android:codes="107" android:keyLabel="k"/> - <Key android:codes="108" android:keyLabel="l" + <Key android:codes="108" android:keyLabel="l" android:popupKeyboard="@xml/kbd_popup_template" android:popupCharacters="@string/alternates_for_l" android:keyEdgeFlags="right"/> @@ -126,6 +123,24 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> + <Row android:keyboardMode="@+id/mode_normal_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-102" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + <Row android:keyboardMode="@+id/mode_url" android:rowEdgeFlags="bottom"> <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" android:popupKeyboard="@xml/kbd_popup_template" @@ -148,6 +163,26 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> + <Row android:keyboardMode="@+id/mode_url_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="15%p"/> + <Key android:keyLabel="/" android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="15%p" android:isRepeatable="true"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + <Row android:keyboardMode="@+id/mode_email" android:rowEdgeFlags="bottom"> <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" android:popupKeyboard="@xml/kbd_popup_template" @@ -170,6 +205,26 @@ android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> + <Row android:keyboardMode="@+id/mode_email_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:keyLabel="\@" android:keyWidth="15%p"/> + <Key android:keyLabel="@string/popular_domain_0" + android:keyOutputText="@string/popular_domain_0" + android:popupKeyboard="@xml/popup_domains" + android:keyWidth="15%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="15%p" android:isRepeatable="true"/> + <Key android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="15%p"/> + <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return" + android:iconPreview="@drawable/sym_keyboard_feedback_return" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> + <Row android:keyboardMode="@+id/mode_im" android:rowEdgeFlags="bottom"> <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" android:popupKeyboard="@xml/kbd_popup_template" @@ -186,5 +241,23 @@ android:popupKeyboard="@xml/popup_smileys" android:keyWidth="20%p" android:keyEdgeFlags="right"/> </Row> + + <Row android:keyboardMode="@+id/mode_im_voice" android:rowEdgeFlags="bottom"> + <Key android:codes="-2" android:keyLabel="@string/label_symbol_key" + android:popupKeyboard="@xml/kbd_popup_template" + android:popupCharacters="_" + android:keyWidth="20%p" android:keyEdgeFlags="left"/> + <Key android:codes="-102" android:keyIcon="@drawable/sym_keyboard_mic" + android:iconPreview="@drawable/sym_keyboard_feedback_mic" + android:keyWidth="10%p"/> + <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space" + android:iconPreview="@drawable/sym_keyboard_feedback_space" + android:keyWidth="40%p" android:isRepeatable="true"/> + <Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_punctuation" + android:keyWidth="10%p"/> + <Key android:keyLabel=":-)" android:keyOutputText=":-) " + android:popupKeyboard="@xml/popup_smileys" + android:keyWidth="20%p" android:keyEdgeFlags="right"/> + </Row> </Keyboard> diff --git a/res/xml/method.xml b/res/xml/method.xml index e5654e96d747d4b341513fdeff6c4a84190971d6..4a807947b92a872bbdd2d6a31d29fe83cba4859e 100644 --- a/res/xml/method.xml +++ b/res/xml/method.xml @@ -21,6 +21,6 @@ <!-- for the Input Method Manager. --> <input-method xmlns:android="http://schemas.android.com/apk/res/android" - android:settingsActivity="com.android.inputmethod.latin.LatinIMESettings" - android:isDefault="@bool/im_is_default" + android:settingsActivity="com.google.android.voicesearch.LatinIMEWithVoiceSettings" + android:isDefault="true" /> diff --git a/res/xml/prefs.xml b/res/xml/prefs.xml index d5075c53a9da862705d38cdfd833688200caa674..74a2bcb20892cdb1c714a444576032152016cc06 100644 --- a/res/xml/prefs.xml +++ b/res/xml/prefs.xml @@ -37,6 +37,12 @@ android:defaultValue="true" /> + <CheckBoxPreference + android:key="enable_voice_input" + android:title="@string/enable_voice" + android:persistent="false" + android:defaultValue="@bool/voice_input_default" + /> <PreferenceScreen android:title="@string/language_selection_title"> <intent diff --git a/src/com/android/inputmethod/latin/CandidateView.java b/src/com/android/inputmethod/latin/CandidateView.java index f397363c3a9700ed906b666855bae0f774d07320..a31714eafb597dba7a5cbb11532bfd1dd7110597 100755 --- a/src/com/android/inputmethod/latin/CandidateView.java +++ b/src/com/android/inputmethod/latin/CandidateView.java @@ -113,7 +113,7 @@ public class CandidateView extends View { public CandidateView(Context context, AttributeSet attrs) { super(context, attrs); mSelectionHighlight = context.getResources().getDrawable( - com.android.internal.R.drawable.list_selector_background_pressed); + R.drawable.list_selector_background_pressed); LayoutInflater inflate = (LayoutInflater) context diff --git a/src/com/android/inputmethod/latin/Hints.java b/src/com/android/inputmethod/latin/Hints.java new file mode 100644 index 0000000000000000000000000000000000000000..109d3f08ec7a85132619e7c09af350625c866753 --- /dev/null +++ b/src/com/android/inputmethod/latin/Hints.java @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.latin; + +import com.android.inputmethod.voice.GoogleSettingsUtil; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.view.inputmethod.InputConnection; + +import java.util.Calendar; +import java.util.HashMap; +import java.util.Map; + +/** + * Logic to determine when to display hints on usage to the user. + */ +public class Hints { + public interface Display { + public void showHint(int viewResource); + } + + private static final String TAG = "Hints"; + private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN = + "voice_hint_num_unique_days_shown"; + private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN = + "voice_hint_last_time_shown"; + private static final String PREF_VOICE_INPUT_LAST_TIME_USED = + "voice_input_last_time_used"; + private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT = + "voice_punctuation_hint_view_count"; + private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7; + private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7; + + private Context mContext; + private Display mDisplay; + private boolean mVoiceResultContainedPunctuation; + private int mSwipeHintMaxDaysToShow; + private int mPunctuationHintMaxDisplays; + + // Only show punctuation hint if voice result did not contain punctuation. + static final Map<CharSequence, String> SPEAKABLE_PUNCTUATION + = new HashMap<CharSequence, String>(); + static { + SPEAKABLE_PUNCTUATION.put(",", "comma"); + SPEAKABLE_PUNCTUATION.put(".", "period"); + SPEAKABLE_PUNCTUATION.put("?", "question mark"); + } + + public Hints(Context context, Display display) { + mContext = context; + mDisplay = display; + + ContentResolver cr = mContext.getContentResolver(); + mSwipeHintMaxDaysToShow = GoogleSettingsUtil.getGservicesInt( + cr, + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS, + DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW); + mPunctuationHintMaxDisplays = GoogleSettingsUtil.getGservicesInt( + cr, + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS, + DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS); + } + + public boolean showSwipeHintIfNecessary(boolean fieldRecommended) { + if (fieldRecommended && shouldShowSwipeHint()) { + showHint(R.layout.voice_swipe_hint); + return true; + } + + return false; + } + + public boolean showPunctuationHintIfNecessary(InputConnection ic) { + if (!mVoiceResultContainedPunctuation + && ic != null + && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT) + < mPunctuationHintMaxDisplays) { + CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0); + if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) { + showHint(R.layout.voice_punctuation_hint); + return true; + } + } + + return false; + } + + public void registerVoiceResult(String text) { + // Update the current time as the last time voice input was used. + SharedPreferences.Editor editor = + PreferenceManager.getDefaultSharedPreferences(mContext).edit(); + editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis()); + editor.commit(); + + mVoiceResultContainedPunctuation = false; + for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) { + if (text.indexOf(s.toString()) >= 0) { + mVoiceResultContainedPunctuation = true; + break; + } + } + } + + private boolean shouldShowSwipeHint() { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + + int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); + + // If we've already shown the hint for enough days, we'll return false. + if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) { + + long lastTimeVoiceWasUsed = sp.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0); + + // If the user has used voice today, we'll return false. (We don't show the hint on + // any day that the user has already used voice.) + if (!isFromToday(lastTimeVoiceWasUsed)) { + return true; + } + } + + return false; + } + + /** + * Determines whether the provided time is from some time today (i.e., this day, month, + * and year). + */ + private boolean isFromToday(long timeInMillis) { + if (timeInMillis == 0) return false; + + Calendar today = Calendar.getInstance(); + today.setTimeInMillis(System.currentTimeMillis()); + + Calendar timestamp = Calendar.getInstance(); + timestamp.setTimeInMillis(timeInMillis); + + return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) && + today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) && + today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH)); + } + + private void showHint(int hintViewResource) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + + int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0); + long lastTimeHintWasShown = sp.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0); + + // If this is the first time the hint is being shown today, increase the saved values + // to represent that. We don't need to increase the last time the hint was shown unless + // it is a different day from the current value. + if (!isFromToday(lastTimeHintWasShown)) { + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1); + editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis()); + editor.commit(); + } + + if (mDisplay != null) { + mDisplay.showHint(hintViewResource); + } + } + + private int getAndIncrementPref(String pref) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); + int value = sp.getInt(pref, 0); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(pref, value + 1); + editor.commit(); + return value; + } +} diff --git a/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/src/com/android/inputmethod/latin/KeyboardSwitcher.java index 03b008e3419a6dabe49479344191f6995525d9d0..aa52c0381076243c2319d1a1cde2115c59decf2a 100644 --- a/src/com/android/inputmethod/latin/KeyboardSwitcher.java +++ b/src/com/android/inputmethod/latin/KeyboardSwitcher.java @@ -48,6 +48,13 @@ public class KeyboardSwitcher { private static final int SYMBOLS_MODE_STATE_SYMBOL = 2; LatinKeyboardView mInputView; + private static final int[] ALPHABET_MODES = { + KEYBOARDMODE_NORMAL, + KEYBOARDMODE_URL, + KEYBOARDMODE_EMAIL, + KEYBOARDMODE_IM}; + + //LatinIME mContext; Context mContext; InputMethodService mInputMethodService; @@ -56,11 +63,17 @@ public class KeyboardSwitcher { private KeyboardId mCurrentId; private Map<KeyboardId, LatinKeyboard> mKeyboards; - - private int mMode; + + /** + * Maps keyboard mode to the equivalent mode with voice. + */ + private Map<Integer, Integer> mModeToVoice; + + private int mMode; /** One of the MODE_XXX values */ private int mImeOptions; private int mTextMode = MODE_TEXT_QWERTY; private boolean mIsSymbols; + private boolean mHasVoice; private boolean mPreferSymbols; private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; @@ -73,6 +86,11 @@ public class KeyboardSwitcher { mKeyboards = new HashMap<KeyboardId, LatinKeyboard>(); mSymbolsId = new KeyboardId(R.xml.kbd_symbols); mSymbolsShiftedId = new KeyboardId(R.xml.kbd_symbols_shift); + mModeToVoice = new HashMap<Integer, Integer>(); + mModeToVoice.put(R.id.mode_normal, R.id.mode_normal_voice); + mModeToVoice.put(R.id.mode_url, R.id.mode_url_voice); + mModeToVoice.put(R.id.mode_email, R.id.mode_email_voice); + mModeToVoice.put(R.id.mode_im, R.id.mode_im_voice); mInputMethodService = ims; } @@ -110,12 +128,12 @@ public class KeyboardSwitcher { */ private static class KeyboardId { public int mXml; - public int mMode; + public int mKeyboardMode; /** A KEYBOARDMODE_XXX value */ public boolean mEnableShiftLock; public KeyboardId(int xml, int mode, boolean enableShiftLock) { this.mXml = xml; - this.mMode = mode; + this.mKeyboardMode = mode; this.mEnableShiftLock = enableShiftLock; } @@ -128,27 +146,40 @@ public class KeyboardSwitcher { } public boolean equals(KeyboardId other) { - return other.mXml == this.mXml && other.mMode == this.mMode; + return other.mXml == this.mXml + && other.mKeyboardMode == this.mKeyboardMode + && other.mEnableShiftLock == this.mEnableShiftLock; } public int hashCode() { - return (mXml + 1) * (mMode + 1) * (mEnableShiftLock ? 2 : 1); + return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1); } } - void setKeyboardMode(int mode, int imeOptions) { + void setVoiceMode(boolean enableVoice) { + setKeyboardMode(mMode, mImeOptions, enableVoice, mIsSymbols); + } + + void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) { mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; mPreferSymbols = mode == MODE_SYMBOLS; - setKeyboardMode(mode == MODE_SYMBOLS ? MODE_TEXT : mode, imeOptions, + setKeyboardMode(mode == MODE_SYMBOLS ? MODE_TEXT : mode, imeOptions, enableVoice, mPreferSymbols); } - void setKeyboardMode(int mode, int imeOptions, boolean isSymbols) { + void setKeyboardMode(int mode, int imeOptions, + boolean enableVoice, boolean isSymbols) { mMode = mode; mImeOptions = imeOptions; + mHasVoice = enableVoice; mIsSymbols = isSymbols; + mInputView.setPreviewEnabled(true); KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); + + if (enableVoice && mModeToVoice.containsKey(id.mKeyboardMode)) { + id.mKeyboardMode = mModeToVoice.get(id.mKeyboardMode); + } LatinKeyboard keyboard = getKeyboard(id); if (mode == MODE_PHONE) { @@ -166,7 +197,6 @@ public class KeyboardSwitcher { keyboard.setShifted(false); keyboard.setShiftLocked(keyboard.isShiftLocked()); keyboard.setImeOptions(mContext.getResources(), mMode, imeOptions); - } private LatinKeyboard getKeyboard(KeyboardId id) { @@ -177,11 +207,16 @@ public class KeyboardSwitcher { conf.locale = mInputLocale; orig.updateConfiguration(conf, null); LatinKeyboard keyboard = new LatinKeyboard( - mContext, id.mXml, id.mMode); - if (id.mMode == KEYBOARDMODE_NORMAL - || id.mMode == KEYBOARDMODE_URL - || id.mMode == KEYBOARDMODE_IM - || id.mMode == KEYBOARDMODE_EMAIL) { + mContext, id.mXml, id.mKeyboardMode); + if (id.mKeyboardMode == KEYBOARDMODE_NORMAL + || id.mKeyboardMode == KEYBOARDMODE_URL + || id.mKeyboardMode == KEYBOARDMODE_IM + || id.mKeyboardMode == KEYBOARDMODE_EMAIL + || id.mKeyboardMode == R.id.mode_normal_voice + || id.mKeyboardMode == R.id.mode_url_voice + || id.mKeyboardMode == R.id.mode_im_voice + || id.mKeyboardMode == R.id.mode_email_voice + ) { keyboard.setExtension(R.xml.kbd_extension); } @@ -241,7 +276,7 @@ public class KeyboardSwitcher { mTextMode = position; } if (isTextMode()) { - setKeyboardMode(MODE_TEXT, mImeOptions); + setKeyboardMode(MODE_TEXT, mImeOptions, mHasVoice); } } @@ -250,11 +285,13 @@ public class KeyboardSwitcher { } boolean isAlphabetMode() { - KeyboardId current = mCurrentId; - return current.mMode == KEYBOARDMODE_NORMAL - || current.mMode == KEYBOARDMODE_URL - || current.mMode == KEYBOARDMODE_EMAIL - || current.mMode == KEYBOARDMODE_IM; + int currentMode = mCurrentId.mKeyboardMode; + for (Integer mode : ALPHABET_MODES) { + if (currentMode == mode || currentMode == mModeToVoice.get(mode)) { + return true; + } + } + return false; } void toggleShift() { @@ -278,7 +315,7 @@ public class KeyboardSwitcher { } void toggleSymbols() { - setKeyboardMode(mMode, mImeOptions, !mIsSymbols); + setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols); if (mIsSymbols && !mPreferSymbols) { mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN; } else { diff --git a/src/com/android/inputmethod/latin/LatinIME.java b/src/com/android/inputmethod/latin/LatinIME.java index 98f47c2c657ffd9f814aa6e110993aeafdf96d3d..cbf3a4a52dfb621133093ec17e6cd05a44201c8b 100644 --- a/src/com/android/inputmethod/latin/LatinIME.java +++ b/src/com/android/inputmethod/latin/LatinIME.java @@ -16,13 +16,7 @@ package com.android.inputmethod.latin; -import java.io.FileDescriptor; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import com.android.inputmethod.latin.UserDictionary; +import com.google.android.collect.Lists; import android.app.AlertDialog; import android.backup.BackupManager; @@ -53,23 +47,42 @@ import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.CompletionInfo; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; +import com.android.inputmethod.voice.EditingUtil; +import com.android.inputmethod.voice.FieldContext; +import com.android.inputmethod.voice.GoogleSettingsUtil; +import com.android.inputmethod.voice.VoiceInput; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + /** * Input method implementation for Qwerty'ish keyboard. */ -public class LatinIME extends InputMethodService +public class LatinIME extends InputMethodService implements KeyboardView.OnKeyboardActionListener, - SharedPreferences.OnSharedPreferenceChangeListener { - + VoiceInput.UiListener, + SharedPreferences.OnSharedPreferenceChangeListener { + private static final String TAG = "LatinIME"; static final boolean DEBUG = false; static final boolean TRACE = false; + static final boolean VOICE_INSTALLED = true; + static final boolean ENABLE_VOICE_BUTTON = true; private static final String PREF_VIBRATE_ON = "vibrate_on"; private static final String PREF_SOUND_ON = "sound_on"; @@ -77,12 +90,53 @@ public class LatinIME extends InputMethodService private static final String PREF_QUICK_FIXES = "quick_fixes"; private static final String PREF_SHOW_SUGGESTIONS = "show_suggestions"; private static final String PREF_AUTO_COMPLETE = "auto_complete"; + private static final String PREF_ENABLE_VOICE = "enable_voice_input"; + private static final String PREF_VOICE_SERVER_URL = "voice_server_url"; + + // Whether or not the user has used voice input before (and thus, whether to show the + // first-run warning dialog or not). + private static final String PREF_HAS_USED_VOICE_INPUT = "has_used_voice_input"; + + // Whether or not the user has used voice input from an unsupported locale UI before. + // For example, the user has a Chinese UI but activates voice input. + private static final String PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE = + "has_used_voice_input_unsupported_locale"; + + // A list of locales which are supported by default for voice input, unless we get a + // different list from Gservices. + public static final String DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES = + "en " + + "en_US " + + "en_GB " + + "en_AU " + + "en_CA " + + "en_IE " + + "en_IN " + + "en_NZ " + + "en_SG " + + "en_ZA "; + + // The private IME option used to indicate that no microphone should be shown for a + // given text field. For instance this is specified by the search dialog when the + // dialog is already showing a voice search button. + private static final String IME_OPTION_NO_MICROPHONE = "nm"; + public static final String PREF_SELECTED_LANGUAGES = "selected_languages"; public static final String PREF_INPUT_LANGUAGE = "input_language"; private static final int MSG_UPDATE_SUGGESTIONS = 0; private static final int MSG_START_TUTORIAL = 1; private static final int MSG_UPDATE_SHIFT_STATE = 2; + private static final int MSG_VOICE_RESULTS = 3; + private static final int MSG_START_LISTENING_AFTER_SWIPE = 4; + + // If we detect a swipe gesture within N ms of typing, then swipe is + // ignored, since it may in fact be two key presses in quick succession. + private static final long MIN_MILLIS_AFTER_TYPING_BEFORE_SWIPE = 1000; + + // If we detect a swipe gesture, and the user types N ms later, cancel the + // swipe since it was probably a false trigger. + private static final long MIN_MILLIS_AFTER_SWIPE_TO_WAIT_FOR_TYPING = 500; // How many continuous deletes at which to start deleting at a higher speed. private static final int DELETE_ACCELERATE_AT = 20; @@ -102,7 +156,7 @@ public class LatinIME extends InputMethodService // Contextual menu positions private static final int POS_SETTINGS = 0; private static final int POS_METHOD = 1; - + private LatinKeyboardView mInputView; private CandidateViewContainer mCandidateViewContainer; private CandidateView mCandidateView; @@ -110,6 +164,7 @@ public class LatinIME extends InputMethodService private CompletionInfo[] mCompletions; private AlertDialog mOptionsDialog; + private AlertDialog mVoiceWarningDialog; KeyboardSwitcher mKeyboardSwitcher; @@ -117,6 +172,8 @@ public class LatinIME extends InputMethodService private ContactsDictionary mContactsDictionary; private ExpandableDictionary mAutoDictionary; + private Hints mHints; + Resources mResources; private String mLocale; @@ -125,6 +182,13 @@ public class LatinIME extends InputMethodService private WordComposer mWord = new WordComposer(); private int mCommittedLength; private boolean mPredicting; + private boolean mRecognizing; + private boolean mAfterVoiceInput; + private boolean mImmediatelyAfterVoiceInput; + private boolean mShowingVoiceSuggestions; + private boolean mImmediatelyAfterVoiceSuggestions; + private boolean mVoiceInputHighlighted; + private boolean mEnableVoiceButton; private CharSequence mBestWord; private boolean mPredictionOn; private boolean mCompletionOn; @@ -133,14 +197,22 @@ public class LatinIME extends InputMethodService private boolean mAutoCorrectEnabled; private boolean mAutoCorrectOn; private boolean mCapsLock; + private boolean mPasswordText; + private boolean mEmailText; private boolean mVibrateOn; private boolean mSoundOn; private boolean mAutoCap; private boolean mQuickFixes; + private boolean mHasUsedVoiceInput; + private boolean mHasUsedVoiceInputUnsupportedLocale; + private boolean mLocaleSupportedForVoiceInput; private boolean mShowSuggestions; + private boolean mSuggestionShouldReplaceCurrentWord; + private boolean mIsShowingHint; private int mCorrectionMode; + private boolean mEnableVoice = true; private int mOrientation; - + // Indicates whether the suggestion strip is to be on in landscape private boolean mJustAccepted; private CharSequence mJustRevertedSeparator; @@ -159,6 +231,17 @@ public class LatinIME extends InputMethodService private String mWordSeparators; private String mSentenceSeparators; + private VoiceInput mVoiceInput; + private VoiceResults mVoiceResults = new VoiceResults(); + private long mSwipeTriggerTimeMillis; + + // For each word, a list of potential replacements, usually from voice. + private Map<String, List<CharSequence>> mWordToSuggestions = new HashMap(); + + private class VoiceResults { + List<String> candidates; + Map<String, List<CharSequence>> alternatives; + } private int mCurrentInputLocale = 0; private String mInputLanguage; private String[] mSelectedLanguageArray; @@ -186,6 +269,13 @@ public class LatinIME extends InputMethodService case MSG_UPDATE_SHIFT_STATE: updateShiftKeyState(getCurrentInputEditorInfo()); break; + case MSG_VOICE_RESULTS: + handleVoiceResults(); + break; + case MSG_START_LISTENING_AFTER_SWIPE: + if (mLastKeyTime < mSwipeTriggerTimeMillis) { + startListening(true); + } } } }; @@ -212,6 +302,19 @@ public class LatinIME extends InputMethodService // register to receive ringer mode changes for silent mode IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION); registerReceiver(mReceiver, filter); + if (VOICE_INSTALLED) { + mVoiceInput = new VoiceInput(this, this); + mHints = new Hints(this, new Hints.Display() { + public void showHint(int viewResource) { + LayoutInflater inflater = (LayoutInflater) getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + View view = inflater.inflate(viewResource, null); + setCandidatesView(view); + setCandidatesViewShown(true); + mIsShowingHint = true; + } + }); + } PreferenceManager.getDefaultSharedPreferences(this) .registerOnSharedPreferenceChangeListener(this); } @@ -228,7 +331,6 @@ public class LatinIME extends InputMethodService mSuggest.close(); } mSuggest = new Suggest(this, R.raw.main); - if (mUserDictionary != null) mUserDictionary.close(); mUserDictionary = new UserDictionary(this); if (mContactsDictionary == null) { mContactsDictionary = new ContactsDictionary(this); @@ -248,10 +350,14 @@ public class LatinIME extends InputMethodService orig.updateConfiguration(conf, orig.getDisplayMetrics()); } - @Override public void onDestroy() { + @Override + public void onDestroy() { mUserDictionary.close(); mContactsDictionary.close(); unregisterReceiver(mReceiver); + if (VOICE_INSTALLED) { + mVoiceInput.destroy(); + } super.onDestroy(); } @@ -262,7 +368,9 @@ public class LatinIME extends InputMethodService } // If orientation changed while predicting, commit the change if (conf.orientation != mOrientation) { - commitTyped(getCurrentInputConnection()); + InputConnection ic = getCurrentInputConnection(); + commitTyped(ic); + if (ic != null) ic.finishComposingText(); // For voice input mOrientation = conf.orientation; } reloadKeyboards(); @@ -276,10 +384,27 @@ public class LatinIME extends InputMethodService mKeyboardSwitcher.setInputView(mInputView); mKeyboardSwitcher.makeKeyboards(true); mInputView.setOnKeyboardActionListener(this); - mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, 0); + mKeyboardSwitcher.setKeyboardMode( + KeyboardSwitcher.MODE_TEXT, 0, + shouldShowVoiceButton(makeFieldContext(), getCurrentInputEditorInfo())); return mInputView; } + @Override + public void onInitializeInterface() { + // Create a new view associated with voice input if the old + // view is stuck in another layout (e.g. if switching from + // portrait to landscape while speaking) + // NOTE: This must be done here because for some reason + // onCreateInputView isn't called after an orientation change while + // speech rec is in progress. + if (mVoiceInput != null && mVoiceInput.getView().getParent() != null) { + mVoiceInput.newView(); + } + + super.onInitializeInterface(); + } + @Override public View onCreateCandidatesView() { mKeyboardSwitcher.makeKeyboards(true); @@ -308,32 +433,54 @@ public class LatinIME extends InputMethodService TextEntryState.newSession(this); + // Most such things we decide below in the switch statement, but we need to know + // now whether this is a password text field, because we need to know now (before + // the switch statement) whether we want to enable the voice button. + mPasswordText = false; + int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; + if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || + variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) { + mPasswordText = true; + } + + mEnableVoiceButton = shouldShowVoiceButton(makeFieldContext(), attribute); + + mAfterVoiceInput = false; + mImmediatelyAfterVoiceInput = false; + mShowingVoiceSuggestions = false; + mImmediatelyAfterVoiceSuggestions = false; + mVoiceInputHighlighted = false; + boolean disableAutoCorrect = false; + mWordToSuggestions.clear(); mInputTypeNoAutoCorrect = false; mPredictionOn = false; mCompletionOn = false; mCompletions = null; mCapsLock = false; - switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) { + mEmailText = false; + switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) { case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_SYMBOLS, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); break; case EditorInfo.TYPE_CLASS_PHONE: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); break; case EditorInfo.TYPE_CLASS_TEXT: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); //startPrediction(); mPredictionOn = true; // Make sure that passwords are not displayed in candidate view - int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ) { mPredictionOn = false; } + if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { + mEmailText = true; + } if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME) { mAutoSpace = false; @@ -343,14 +490,14 @@ public class LatinIME extends InputMethodService if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { mPredictionOn = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { mPredictionOn = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) { mPredictionOn = false; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { @@ -379,17 +526,25 @@ public class LatinIME extends InputMethodService break; default: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, - attribute.imeOptions); + attribute.imeOptions, mEnableVoiceButton); updateShiftKeyState(attribute); } mInputView.closing(); mComposing.setLength(0); mPredicting = false; mDeleteCount = 0; - setCandidatesViewShown(false); - if (mCandidateView != null) mCandidateView.setSuggestions(null, false, false, false); loadSettings(); + setCandidatesViewShown(false); + setSuggestions(null, false, false, false); + + // Override auto correct + if (disableAutoCorrect) { + mAutoCorrectOn = false; + if (mCorrectionMode == Suggest.CORRECTION_FULL) { + mCorrectionMode = Suggest.CORRECTION_BASIC; + } + } // If the dictionary is not big enough, don't auto correct mHasDictionary = mSuggest.hasMainDictionary(); @@ -404,10 +559,31 @@ public class LatinIME extends InputMethodService @Override public void onFinishInput() { super.onFinishInput(); - + + if (mAfterVoiceInput) mVoiceInput.logInputEnded(); + + mVoiceInput.flushLogs(); + if (mInputView != null) { mInputView.closing(); } + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } + } + + @Override + public void onUpdateExtractedText(int token, ExtractedText text) { + super.onUpdateExtractedText(token, text); + InputConnection ic = getCurrentInputConnection(); + if (!mImmediatelyAfterVoiceInput && mAfterVoiceInput && ic != null) { + mVoiceInput.logTextModified(); + + if (mHints.showPunctuationHintIfNecessary(ic)) { + mVoiceInput.logPunctuationHintDisplayed(); + } + } + mImmediatelyAfterVoiceInput = false; } @Override @@ -416,10 +592,22 @@ public class LatinIME extends InputMethodService int candidatesStart, int candidatesEnd) { super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, candidatesStart, candidatesEnd); + + if (DEBUG) { + Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart + + ", ose=" + oldSelEnd + + ", nss=" + newSelStart + + ", nse=" + newSelEnd + + ", cs=" + candidatesStart + + ", ce=" + candidatesEnd); + } + + mSuggestionShouldReplaceCurrentWord = false; // If the current selection in the text view changes, we should // clear whatever candidate text we have. - if (mComposing.length() > 0 && mPredicting && (newSelStart != candidatesEnd - || newSelEnd != candidatesEnd)) { + if ((((mComposing.length() > 0 && mPredicting) || mVoiceInputHighlighted) + && (newSelStart != candidatesEnd + || newSelEnd != candidatesEnd))) { mComposing.setLength(0); mPredicting = false; updateSuggestions(); @@ -428,25 +616,58 @@ public class LatinIME extends InputMethodService if (ic != null) { ic.finishComposingText(); } + mVoiceInputHighlighted = false; } else if (!mPredicting && !mJustAccepted && TextEntryState.getState() == TextEntryState.STATE_ACCEPTED_DEFAULT) { TextEntryState.reset(); } mJustAccepted = false; postUpdateShiftKeyState(); + + if (VOICE_INSTALLED) { + if (mShowingVoiceSuggestions) { + if (mImmediatelyAfterVoiceSuggestions) { + mImmediatelyAfterVoiceSuggestions = false; + } else { + updateSuggestions(); + mShowingVoiceSuggestions = false; + } + } + if (VoiceInput.ENABLE_WORD_CORRECTIONS) { + // If we have alternatives for the current word, then show them. + String word = EditingUtil.getWordAtCursor( + getCurrentInputConnection(), getWordSeparators()); + if (word != null && mWordToSuggestions.containsKey(word.trim())) { + mSuggestionShouldReplaceCurrentWord = true; + final List<CharSequence> suggestions = mWordToSuggestions.get(word.trim()); + + setSuggestions(suggestions, false, true, true); + setCandidatesViewShown(true); + } + } + } } @Override public void hideWindow() { + if (mAfterVoiceInput) mVoiceInput.logInputEnded(); if (TRACE) Debug.stopMethodTracing(); if (mOptionsDialog != null && mOptionsDialog.isShowing()) { mOptionsDialog.dismiss(); mOptionsDialog = null; } + if (mVoiceWarningDialog != null && mVoiceWarningDialog.isShowing()) { + mVoiceInput.logKeyboardWarningDialogDismissed(); + mVoiceWarningDialog.dismiss(); + mVoiceWarningDialog = null; + } if (mTutorial != null) { mTutorial.close(); mTutorial = null; } + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } super.hideWindow(); TextEntryState.endSession(); } @@ -462,7 +683,7 @@ public class LatinIME extends InputMethodService if (mCompletionOn) { mCompletions = completions; if (completions == null) { - mCandidateView.setSuggestions(null, false, false, false); + setSuggestions(null, false, false, false); return; } @@ -472,7 +693,7 @@ public class LatinIME extends InputMethodService if (ci != null) stringList.add(ci.getText()); } //CharSequence typedWord = mWord.getTypedWord(); - mCandidateView.setSuggestions(stringList, true, true, true); + setSuggestions(stringList, true, true, true); mBestWord = null; setCandidatesViewShown(isCandidateStripVisible() || mCompletionOn); } @@ -546,6 +767,20 @@ public class LatinIME extends InputMethodService return super.onKeyUp(keyCode, event); } + private void revertVoiceInput() { + InputConnection ic = getCurrentInputConnection(); + if (ic != null) ic.commitText("", 1); + updateSuggestions(); + mVoiceInputHighlighted = false; + } + + private void commitVoiceInput() { + InputConnection ic = getCurrentInputConnection(); + if (ic != null) ic.finishComposingText(); + updateSuggestions(); + mVoiceInputHighlighted = false; + } + private void reloadKeyboards() { if (mKeyboardSwitcher == null) { mKeyboardSwitcher = new KeyboardSwitcher(this, this); @@ -670,6 +905,11 @@ public class LatinIME extends InputMethodService case Keyboard.KEYCODE_MODE_CHANGE: changeKeyboardMode(); break; + case LatinKeyboardView.KEYCODE_VOICE: + if (VOICE_INSTALLED) { + startListening(false /* was a button press, was not a swipe */); + } + break; default: if (isWordSeparator(primaryCode)) { handleSeparator(primaryCode); @@ -698,6 +938,10 @@ public class LatinIME extends InputMethodService } private void handleBackspace() { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + revertVoiceInput(); + return; + } boolean deleteChar = false; InputConnection ic = getCurrentInputConnection(); if (ic == null) return; @@ -743,6 +987,9 @@ public class LatinIME extends InputMethodService } private void handleCharacter(int primaryCode, int[] keyCodes) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } if (isAlphabet(primaryCode) && isPredictionOn() && !isCursorTouchingWord()) { if (!mPredicting) { mPredicting = true; @@ -778,6 +1025,9 @@ public class LatinIME extends InputMethodService } private void handleSeparator(int primaryCode) { + if (VOICE_INSTALLED && mVoiceInputHighlighted) { + commitVoiceInput(); + } boolean pickedDefault = false; // Handle separator InputConnection ic = getCurrentInputConnection(); @@ -816,9 +1066,12 @@ public class LatinIME extends InputMethodService ic.endBatchEdit(); } } - + private void handleClose() { commitTyped(getCurrentInputConnection()); + if (VOICE_INSTALLED & mRecognizing) { + mVoiceInput.cancel(); + } requestHideSelf(0); mInputView.closing(); TextEntryState.endSession(); @@ -852,14 +1105,205 @@ public class LatinIME extends InputMethodService return isPredictionOn() && mShowSuggestions; } + public void onCancelVoice() { + if (mRecognizing) { + switchToKeyboardView(); + } + } + + private void switchToKeyboardView() { + mHandler.post(new Runnable() { + public void run() { + mRecognizing = false; + if (mInputView != null) { + setInputView(mInputView); + } + updateInputViewShown(); + }}); + } + + private void switchToRecognitionStatusView() { + mHandler.post(new Runnable() { + public void run() { + mRecognizing = true; + setInputView(mVoiceInput.getView()); + updateInputViewShown(); + }}); + } + + private void startListening(boolean swipe) { + if (!mHasUsedVoiceInput || + (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale)) { + // Calls reallyStartListening if user clicks OK, does nothing if user clicks Cancel. + showVoiceWarningDialog(swipe); + } else { + reallyStartListening(swipe); + } + } + + private void reallyStartListening(boolean swipe) { + if (!mHasUsedVoiceInput) { + // The user has started a voice input, so remember that in the + // future (so we don't show the warning dialog after the first run). + SharedPreferences.Editor editor = + PreferenceManager.getDefaultSharedPreferences(this).edit(); + editor.putBoolean(PREF_HAS_USED_VOICE_INPUT, true); + editor.commit(); + mHasUsedVoiceInput = true; + } + + if (!mLocaleSupportedForVoiceInput && !mHasUsedVoiceInputUnsupportedLocale) { + // The user has started a voice input from an unsupported locale, so remember that + // in the future (so we don't show the warning dialog the next time they do this). + SharedPreferences.Editor editor = + PreferenceManager.getDefaultSharedPreferences(this).edit(); + editor.putBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, true); + editor.commit(); + mHasUsedVoiceInputUnsupportedLocale = true; + } + + // Clear N-best suggestions + setSuggestions(null, false, false, true); + + FieldContext context = new FieldContext( + getCurrentInputConnection(), getCurrentInputEditorInfo()); + mVoiceInput.startListening(context, swipe); + switchToRecognitionStatusView(); + } + + private void showVoiceWarningDialog(final boolean swipe) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setCancelable(true); + builder.setIcon(R.drawable.ic_mic_dialog); + builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + mVoiceInput.logKeyboardWarningDialogOk(); + reallyStartListening(swipe); + } + }); + builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + mVoiceInput.logKeyboardWarningDialogCancel(); + } + }); + + if (mLocaleSupportedForVoiceInput) { + String message = getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_warning_how_to_turn_off); + builder.setMessage(message); + } else { + String message = getString(R.string.voice_warning_locale_not_supported) + "\n\n" + + getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_warning_how_to_turn_off); + builder.setMessage(message); + } + + builder.setTitle(R.string.voice_warning_title); + mVoiceWarningDialog = builder.create(); + + Window window = mVoiceWarningDialog.getWindow(); + WindowManager.LayoutParams lp = window.getAttributes(); + lp.token = mInputView.getWindowToken(); + lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; + window.setAttributes(lp); + window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); + mVoiceInput.logKeyboardWarningDialogShown(); + mVoiceWarningDialog.show(); + } + + public void onVoiceResults(List<String> candidates, + Map<String, List<CharSequence>> alternatives) { + if (!mRecognizing) { + return; + } + mVoiceResults.candidates = candidates; + mVoiceResults.alternatives = alternatives; + mHandler.sendMessage(mHandler.obtainMessage(MSG_VOICE_RESULTS)); + } + + private void handleVoiceResults() { + mAfterVoiceInput = true; + mImmediatelyAfterVoiceInput = true; + + InputConnection ic = getCurrentInputConnection(); + if (!isFullscreenMode()) { + // Start listening for updates to the text from typing, etc. + if (ic != null) { + ExtractedTextRequest req = new ExtractedTextRequest(); + ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR); + } + } + + vibrate(); + switchToKeyboardView(); + + final List<CharSequence> nBest = new ArrayList<CharSequence>(); + boolean capitalizeFirstWord = preferCapitalization() + || (mKeyboardSwitcher.isAlphabetMode() && mInputView.isShifted()); + for (String c : mVoiceResults.candidates) { + if (capitalizeFirstWord) { + c = Character.toUpperCase(c.charAt(0)) + c.substring(1, c.length()); + } + nBest.add(c); + } + + if (nBest.size() == 0) { + return; + } + + String bestResult = nBest.get(0).toString(); + + mVoiceInput.logVoiceInputDelivered(); + + mHints.registerVoiceResult(bestResult); + + if (ic != null) ic.beginBatchEdit(); // To avoid extra updates on committing older text + + commitTyped(ic); + EditingUtil.appendText(ic, bestResult); + + if (ic != null) ic.endBatchEdit(); + + // Show N-Best alternates, if there is more than one choice. + if (nBest.size() > 1) { + mImmediatelyAfterVoiceSuggestions = true; + mShowingVoiceSuggestions = true; + setSuggestions(nBest.subList(1, nBest.size()), false, true, true); + setCandidatesViewShown(true); + } + mVoiceInputHighlighted = true; + mWordToSuggestions.putAll(mVoiceResults.alternatives); + + } + + private void setSuggestions( + List<CharSequence> suggestions, + boolean completions, + + boolean typedWordValid, + boolean haveMinimalSuggestion) { + + if (mIsShowingHint) { + setCandidatesView(mCandidateViewContainer); + mIsShowingHint = false; + } + + if (mCandidateView != null) { + mCandidateView.setSuggestions( + suggestions, completions, typedWordValid, haveMinimalSuggestion); + } + } + private void updateSuggestions() { + mSuggestionShouldReplaceCurrentWord = false; + // Check if we have a suggestion engine attached. - if (mSuggest == null || !isPredictionOn()) { + if ((mSuggest == null || !isPredictionOn()) && !mVoiceInputHighlighted) { return; } - + if (!mPredicting) { - mCandidateView.setSuggestions(null, false, false, false); + setSuggestions(null, false, false, false); return; } @@ -876,7 +1320,7 @@ public class LatinIME extends InputMethodService // Don't auto-correct words with multiple capital letter correctionAvailable &= !mWord.isMostlyCaps(); - mCandidateView.setSuggestions(stringList, false, typedWordValid, correctionAvailable); + setSuggestions(stringList, false, typedWordValid, correctionAvailable); if (stringList.size() > 0) { if (correctionAvailable && !typedWordValid && stringList.size() > 1) { mBestWord = stringList.get(1); @@ -903,6 +1347,8 @@ public class LatinIME extends InputMethodService } public void pickSuggestionManually(int index, CharSequence suggestion) { + if (mAfterVoiceInput && mShowingVoiceSuggestions) mVoiceInput.logNBestChoose(index); + if (mCompletionOn && mCompletions != null && index >= 0 && index < mCompletions.length) { CompletionInfo ci = mCompletions[index]; @@ -937,7 +1383,12 @@ public class LatinIME extends InputMethodService } InputConnection ic = getCurrentInputConnection(); if (ic != null) { - ic.commitText(suggestion, 1); + if (mSuggestionShouldReplaceCurrentWord) { + EditingUtil.deleteWordAtCursor(ic, getWordSeparators()); + } + if (!VoiceInput.DELETE_SYMBOL.equals(suggestion)) { + ic.commitText(suggestion, 1); + } } // Add the word to the auto dictionary if it's not a known word if (mAutoDictionary.isValidWord(suggestion) || !mSuggest.isValidWord(suggestion)) { @@ -945,9 +1396,7 @@ public class LatinIME extends InputMethodService } mPredicting = false; mCommittedLength = suggestion.length(); - if (mCandidateView != null) { - mCandidateView.setSuggestions(null, false, false, false); - } + setSuggestions(null, false, false, false); updateShiftKeyState(getCurrentInputEditorInfo()); } @@ -1016,6 +1465,11 @@ public class LatinIME extends InputMethodService } public void swipeRight() { + if (userHasNotTypedRecently() && VOICE_INSTALLED && mEnableVoice && + fieldCanDoVoice(makeFieldContext())) { + startListening(true /* was a swipe */); + } + if (LatinKeyboardView.DEBUG_AUTO_PLAY) { ClipboardManager cm = ((ClipboardManager)getSystemService(CLIPBOARD_SERVICE)); CharSequence text = cm.getText(); @@ -1035,7 +1489,7 @@ public class LatinIME extends InputMethodService int currentKeyboardMode = mKeyboardSwitcher.getKeyboardMode(); reloadKeyboards(); mKeyboardSwitcher.makeKeyboards(true); - mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0); + mKeyboardSwitcher.setKeyboardMode(currentKeyboardMode, 0, mEnableVoiceButton); initSuggest(mInputLanguage); persistInputLanguage(mInputLanguage); updateShiftKeyState(getCurrentInputEditorInfo()); @@ -1068,7 +1522,30 @@ public class LatinIME extends InputMethodService public void onRelease(int primaryCode) { //vibrate(); } + + private FieldContext makeFieldContext() { + return new FieldContext(getCurrentInputConnection(), getCurrentInputEditorInfo()); + } + + private boolean fieldCanDoVoice(FieldContext fieldContext) { + return !mPasswordText + && mVoiceInput != null + && !mVoiceInput.isBlacklistedField(fieldContext); + } + + private boolean fieldIsRecommendedForVoice(FieldContext fieldContext) { + // TODO: Move this logic into the VoiceInput method. + return !mPasswordText && !mEmailText && mVoiceInput.isRecommendedField(fieldContext); + } + private boolean shouldShowVoiceButton(FieldContext fieldContext, EditorInfo attribute) { + return ENABLE_VOICE_BUTTON + && mEnableVoice + && fieldCanDoVoice(fieldContext) + && !(attribute != null && attribute.privateImeOptions != null + && attribute.privateImeOptions.equals(IME_OPTION_NO_MICROPHONE)); + } + // receive ringer mode changes to detect silent mode private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override @@ -1087,6 +1564,26 @@ public class LatinIME extends InputMethodService } } + private boolean userHasNotTypedRecently() { + return (SystemClock.uptimeMillis() - mLastKeyTime) + > MIN_MILLIS_AFTER_TYPING_BEFORE_SWIPE; + } + + /* + * Only trigger a swipe action if the user hasn't typed X millis before + * now, and if they don't type Y millis after the swipe is detected. This + * delays the onset of the swipe action by Y millis. + */ + private void conservativelyTriggerSwipeAction(final Runnable action) { + if (userHasNotTypedRecently()) { + mSwipeTriggerTimeMillis = System.currentTimeMillis(); + mHandler.sendMessageDelayed( + mHandler.obtainMessage(MSG_START_LISTENING_AFTER_SWIPE), + MIN_MILLIS_AFTER_SWIPE_TO_WAIT_FOR_TYPING); + } + } + + private void playKeyClick(int primaryCode) { // if mAudioManager is null, we don't have the ringer state yet // mAudioManager will be set by updateRingerMode @@ -1162,10 +1659,14 @@ public class LatinIME extends InputMethodService } } - private void launchSettings() { + protected void launchSettings() { + launchSettings(LatinIMESettings.class); + } + + protected void launchSettings(Class settingsClass) { handleClose(); Intent intent = new Intent(); - intent.setClass(LatinIME.this, LatinIMESettings.class); + intent.setClass(LatinIME.this, settingsClass); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } @@ -1177,10 +1678,37 @@ public class LatinIME extends InputMethodService mSoundOn = sp.getBoolean(PREF_SOUND_ON, false); mAutoCap = sp.getBoolean(PREF_AUTO_CAP, true); mQuickFixes = sp.getBoolean(PREF_QUICK_FIXES, true); + mHasUsedVoiceInput = sp.getBoolean(PREF_HAS_USED_VOICE_INPUT, false); + mHasUsedVoiceInputUnsupportedLocale = + sp.getBoolean(PREF_HAS_USED_VOICE_INPUT_UNSUPPORTED_LOCALE, false); + + // Get the current list of supported locales and check the current locale against that + // list. We cache this value so as not to check it every time the user starts a voice + // input. Because this method is called by onStartInputView, this should mean that as + // long as the locale doesn't change while the user is keeping the IME open, the + // value should never be stale. + String supportedLocalesString = GoogleSettingsUtil.getGservicesString( + getContentResolver(), + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, + DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); + ArrayList<String> voiceInputSupportedLocales = + Lists.newArrayList(supportedLocalesString.split("\\s+")); + + mLocaleSupportedForVoiceInput = voiceInputSupportedLocales.contains(mLocale); + // If there is no auto text data, then quickfix is forced to "on", so that the other options // will continue to work + if (AutoText.getSize(mInputView) < 1) mQuickFixes = true; mShowSuggestions = sp.getBoolean(PREF_SHOW_SUGGESTIONS, true) & mQuickFixes; + + if (VOICE_INSTALLED) { + boolean enableVoice = sp.getBoolean(PREF_ENABLE_VOICE, true); + if (enableVoice != mEnableVoice && mKeyboardSwitcher != null) { + mKeyboardSwitcher.setVoiceMode(enableVoice); + } + mEnableVoice = enableVoice; + } mAutoCorrectEnabled = sp.getBoolean(PREF_AUTO_COMPLETE, mResources.getBoolean(R.bool.enable_autocorrect)) & mShowSuggestions; updateCorrectionMode(); @@ -1219,7 +1747,7 @@ public class LatinIME extends InputMethodService builder.setIcon(R.drawable.ic_dialog_keyboard); builder.setNegativeButton(android.R.string.cancel, null); CharSequence itemSettings = getString(R.string.english_ime_settings); - CharSequence itemInputMethod = getString(com.android.internal.R.string.inputMethod); + CharSequence itemInputMethod = getString(R.string.inputMethod); builder.setItems(new CharSequence[] { itemSettings, itemInputMethod}, new DialogInterface.OnClickListener() { @@ -1327,6 +1855,3 @@ public class LatinIME extends InputMethodService } } } - - - diff --git a/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java b/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java index c454f120e4870d5fd394f1ce6a485f195ddcb34a..b6a800ebd4f85ac151dc552e21ebe149e8e4e408 100644 --- a/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java +++ b/src/com/android/inputmethod/latin/LatinIMEBackupAgent.java @@ -26,6 +26,6 @@ public class LatinIMEBackupAgent extends BackupHelperAgent { public void onCreate() { addHelper("shared_pref", new SharedPreferencesBackupHelper(this, - "com.android.inputmethod.latin_preferences")); + getPackageName() + "_preferences")); } } diff --git a/src/com/android/inputmethod/latin/LatinIMESettings.java b/src/com/android/inputmethod/latin/LatinIMESettings.java index c8ea309e3e85b6f0f2872c1886434e357b1a7344..4c221b9056d3a79f4754b662543be5d4adc2b6f7 100644 --- a/src/com/android/inputmethod/latin/LatinIMESettings.java +++ b/src/com/android/inputmethod/latin/LatinIMESettings.java @@ -16,23 +16,53 @@ package com.android.inputmethod.latin; +import com.google.android.collect.Lists; + +import android.app.AlertDialog; +import android.app.Dialog; import android.backup.BackupManager; +import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.CheckBoxPreference; +import android.preference.ListPreference; +import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceGroup; +import android.preference.Preference.OnPreferenceClickListener; import android.text.AutoText; +import android.util.Log; + +import com.android.inputmethod.voice.GoogleSettingsUtil; +import com.android.inputmethod.voice.VoiceInput; +import com.android.inputmethod.voice.VoiceInputLogger; + +import java.util.ArrayList; +import java.util.Locale; public class LatinIMESettings extends PreferenceActivity - implements SharedPreferences.OnSharedPreferenceChangeListener { + implements SharedPreferences.OnSharedPreferenceChangeListener, + OnPreferenceClickListener, + DialogInterface.OnDismissListener { private static final String QUICK_FIXES_KEY = "quick_fixes"; private static final String SHOW_SUGGESTIONS_KEY = "show_suggestions"; private static final String PREDICTION_SETTINGS_KEY = "prediction_settings"; + private static final String VOICE_SETTINGS_KEY = "enable_voice_input"; + private static final String VOICE_SERVER_KEY = "voice_server_url"; + + private static final String TAG = "LatinIMESettings"; + + // Dialog ids + private static final int VOICE_INPUT_CONFIRM_DIALOG = 0; private CheckBoxPreference mQuickFixes; private CheckBoxPreference mShowSuggestions; + private CheckBoxPreference mVoicePreference; + + private VoiceInputLogger mLogger; + + private boolean mOkClicked = false; @Override protected void onCreate(Bundle icicle) { @@ -40,8 +70,16 @@ public class LatinIMESettings extends PreferenceActivity addPreferencesFromResource(R.xml.prefs); mQuickFixes = (CheckBoxPreference) findPreference(QUICK_FIXES_KEY); mShowSuggestions = (CheckBoxPreference) findPreference(SHOW_SUGGESTIONS_KEY); - getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener( - this); + mVoicePreference = (CheckBoxPreference) findPreference(VOICE_SETTINGS_KEY); + + SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + prefs.registerOnSharedPreferenceChangeListener(this); + + mVoicePreference.setOnPreferenceClickListener(this); + mVoicePreference.setChecked(prefs.getBoolean( + VOICE_SETTINGS_KEY, getResources().getBoolean(R.bool.voice_input_default))); + + mLogger = VoiceInputLogger.getLogger(this); } @Override @@ -50,10 +88,17 @@ public class LatinIMESettings extends PreferenceActivity int autoTextSize = AutoText.getSize(getListView()); if (autoTextSize < 1) { ((PreferenceGroup) findPreference(PREDICTION_SETTINGS_KEY)) - .removePreference(mQuickFixes); + .removePreference(mQuickFixes); } else { mShowSuggestions.setDependency(QUICK_FIXES_KEY); } + if (!LatinIME.VOICE_INSTALLED + || !VoiceInput.voiceIsAvailable(this)) { + getPreferenceScreen().removePreference(mVoicePreference); + } + + mVoicePreference.setChecked( + getPreferenceManager().getSharedPreferences().getBoolean(VOICE_SETTINGS_KEY, true)); } @Override @@ -67,4 +112,91 @@ public class LatinIMESettings extends PreferenceActivity String key) { (new BackupManager(this)).dataChanged(); } + + public boolean onPreferenceClick(Preference preference) { + if (preference == mVoicePreference) { + if (mVoicePreference.isChecked()) { + mOkClicked = false; + showDialog(VOICE_INPUT_CONFIRM_DIALOG); + } else { + updateVoicePreference(); + } + } + return false; + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case VOICE_INPUT_CONFIRM_DIALOG: + DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + if (whichButton == DialogInterface.BUTTON_NEGATIVE) { + mVoicePreference.setChecked(false); + mLogger.settingsWarningDialogCancel(); + } else if (whichButton == DialogInterface.BUTTON_POSITIVE) { + mOkClicked = true; + mLogger.settingsWarningDialogOk(); + } + updateVoicePreference(); + } + }; + AlertDialog.Builder builder = new AlertDialog.Builder(this) + .setTitle(R.string.voice_warning_title) + .setPositiveButton(android.R.string.ok, listener) + .setNegativeButton(android.R.string.cancel, listener); + + // Get the current list of supported locales and check the current locale against + // that list, to decide whether to put a warning that voice input will not work in + // the current language as part of the pop-up confirmation dialog. + String supportedLocalesString = GoogleSettingsUtil.getGservicesString( + getContentResolver(), + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES, + LatinIME.DEFAULT_VOICE_INPUT_SUPPORTED_LOCALES); + ArrayList<String> voiceInputSupportedLocales = + Lists.newArrayList(supportedLocalesString.split("\\s+")); + boolean localeSupported = voiceInputSupportedLocales.contains( + Locale.getDefault().toString()); + + if (localeSupported) { + String message = getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_hint_dialog_message); + builder.setMessage(message); + } else { + String message = getString(R.string.voice_warning_locale_not_supported) + + "\n\n" + getString(R.string.voice_warning_may_not_understand) + "\n\n" + + getString(R.string.voice_hint_dialog_message); + builder.setMessage(message); + } + + AlertDialog dialog = builder.create(); + dialog.setOnDismissListener(this); + mLogger.settingsWarningDialogShown(); + return dialog; + default: + Log.e(TAG, "unknown dialog " + id); + return null; + } + } + + public void onDismiss(DialogInterface dialog) { + mLogger.settingsWarningDialogDismissed(); + if (!mOkClicked) { + // This assumes that onPreferenceClick gets called first, and this if the user + // agreed after the warning, we set the mOkClicked value to true. + mVoicePreference.setChecked(false); + } + } + + private void updateVoicePreference() { + SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit(); + boolean isChecked = mVoicePreference.isChecked(); + if (isChecked) { + mLogger.voiceInputSettingEnabled(); + } else { + mLogger.voiceInputSettingDisabled(); + } + editor.putBoolean(VOICE_SETTINGS_KEY, isChecked); + editor.commit(); + } } diff --git a/src/com/android/inputmethod/latin/LatinKeyboardView.java b/src/com/android/inputmethod/latin/LatinKeyboardView.java index 163d824e004f288454bada07e54533dffc2e6ec4..ea9ccf0b60bc731743df56f27307dce05f44016f 100644 --- a/src/com/android/inputmethod/latin/LatinKeyboardView.java +++ b/src/com/android/inputmethod/latin/LatinKeyboardView.java @@ -35,8 +35,8 @@ public class LatinKeyboardView extends KeyboardView { static final int KEYCODE_OPTIONS = -100; static final int KEYCODE_SHIFT_LONGPRESS = -101; - static final int KEYCODE_F1 = -102; - + static final int KEYCODE_VOICE = -102; + static final int KEYCODE_F1 = -103; private Keyboard mPhoneKeyboard; public LatinKeyboardView(Context context, AttributeSet attrs) { diff --git a/src/com/android/inputmethod/voice/EditingUtil.java b/src/com/android/inputmethod/voice/EditingUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..6316d8ccf1e7158687ecb21fc03437073987883b --- /dev/null +++ b/src/com/android/inputmethod/voice/EditingUtil.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +/** + * Utility methods to deal with editing text through an InputConnection. + */ +public class EditingUtil { + private EditingUtil() {}; + + /** + * Append newText to the text field represented by connection. + * The new text becomes selected. + */ + public static void appendText(InputConnection connection, String newText) { + if (connection == null) { + return; + } + + // Commit the composing text + connection.finishComposingText(); + + // Add a space if the field already has text. + CharSequence charBeforeCursor = connection.getTextBeforeCursor(1, 0); + if (charBeforeCursor != null + && !charBeforeCursor.equals(" ") + && (charBeforeCursor.length() > 0)) { + newText = " " + newText; + } + + connection.setComposingText(newText, 1); + } + + private static int getCursorPosition(InputConnection connection) { + ExtractedText extracted = connection.getExtractedText( + new ExtractedTextRequest(), 0); + if (extracted == null) { + return -1; + } + return extracted.startOffset + extracted.selectionStart; + } + + private static int getSelectionEnd(InputConnection connection) { + ExtractedText extracted = connection.getExtractedText( + new ExtractedTextRequest(), 0); + if (extracted == null) { + return -1; + } + return extracted.startOffset + extracted.selectionEnd; + } + + /** + * @param connection connection to the current text field. + * @param sep characters which may separate words + * @return the word that surrounds the cursor, including up to one trailing + * separator. For example, if the field contains "he|llo world", where | + * represents the cursor, then "hello " will be returned. + */ + public static String getWordAtCursor( + InputConnection connection, String separators) { + Range range = getWordRangeAtCursor(connection, separators); + return (range == null) ? null : range.word; + } + + /** + * Removes the word surrounding the cursor. Parameters are identical to + * getWordAtCursor. + */ + public static void deleteWordAtCursor( + InputConnection connection, String separators) { + + Range range = getWordRangeAtCursor(connection, separators); + if (range == null) return; + + connection.finishComposingText(); + // Move cursor to beginning of word, to avoid crash when cursor is outside + // of valid range after deleting text. + int newCursor = getCursorPosition(connection) - range.charsBefore; + connection.setSelection(newCursor, newCursor); + connection.deleteSurroundingText(0, range.charsBefore + range.charsAfter); + } + + /** + * Represents a range of text, relative to the current cursor position. + */ + private static class Range { + /** Characters before selection start */ + int charsBefore; + + /** + * Characters after selection start, including one trailing word + * separator. + */ + int charsAfter; + + /** The actual characters that make up a word */ + String word; + + public Range(int charsBefore, int charsAfter, String word) { + if (charsBefore < 0 || charsAfter < 0) { + throw new IndexOutOfBoundsException(); + } + this.charsBefore = charsBefore; + this.charsAfter = charsAfter; + this.word = word; + } + } + + private static Range getWordRangeAtCursor( + InputConnection connection, String sep) { + if (connection == null || sep == null) { + return null; + } + CharSequence before = connection.getTextBeforeCursor(1000, 0); + CharSequence after = connection.getTextAfterCursor(1000, 0); + if (before == null || after == null) { + return null; + } + + // Find first word separator before the cursor + int start = before.length(); + while (--start > 0 && !isWhitespace(before.charAt(start - 1), sep)); + + // Find last word separator after the cursor + int end = -1; + while (++end < after.length() && !isWhitespace(after.charAt(end), sep)); + if (end < after.length() - 1) { + end++; // Include trailing space, if it exists, in word + } + + int cursor = getCursorPosition(connection); + if (start >= 0 && cursor + end <= after.length() + before.length()) { + String word = before.toString().substring(start, before.length()) + + after.toString().substring(0, end); + return new Range(before.length() - start, end, word); + } + + return null; + } + + private static boolean isWhitespace(int code, String whitespace) { + return whitespace.contains(String.valueOf((char) code)); + } +} diff --git a/src/com/android/inputmethod/voice/FieldContext.java b/src/com/android/inputmethod/voice/FieldContext.java new file mode 100644 index 0000000000000000000000000000000000000000..0578af7323f2f950db7700fc5d3fe55c6b558ff4 --- /dev/null +++ b/src/com/android/inputmethod/voice/FieldContext.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.os.Bundle; +import android.util.Log; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.ExtractedText; +import android.view.inputmethod.ExtractedTextRequest; +import android.view.inputmethod.InputConnection; + +/** + * Represents information about a given text field, which can be passed + * to the speech recognizer as context information. + */ +public class FieldContext { + static final String LABEL = "label"; + static final String HINT = "hint"; + static final String PACKAGE_NAME = "packageName"; + static final String FIELD_ID = "fieldId"; + static final String FIELD_NAME = "fieldName"; + static final String SINGLE_LINE = "singleLine"; + static final String INPUT_TYPE = "inputType"; + static final String IME_OPTIONS = "imeOptions"; + + Bundle mFieldInfo; + + public FieldContext(InputConnection conn, EditorInfo info) { + this.mFieldInfo = new Bundle(); + addEditorInfoToBundle(info, mFieldInfo); + addInputConnectionToBundle(conn, mFieldInfo); + Log.i("FieldContext", "Bundle = " + mFieldInfo.toString()); + } + + private static String safeToString(Object o) { + if (o == null) { + return ""; + } + return o.toString(); + } + + private static void addEditorInfoToBundle(EditorInfo info, Bundle bundle) { + if (info == null) { + return; + } + + + bundle.putString(LABEL, safeToString(info.label)); + bundle.putString(HINT, safeToString(info.hintText)); + bundle.putString(PACKAGE_NAME, safeToString(info.packageName)); + bundle.putInt(FIELD_ID, info.fieldId); + bundle.putString(FIELD_NAME, safeToString(info.fieldName)); + bundle.putInt(INPUT_TYPE, info.inputType); + bundle.putInt(IME_OPTIONS, info.imeOptions); + } + + private static void addInputConnectionToBundle( + InputConnection conn, Bundle bundle) { + if (conn == null) { + return; + } + + ExtractedText et = conn.getExtractedText(new ExtractedTextRequest(), 0); + if (et == null) { + return; + } + bundle.putBoolean(SINGLE_LINE, (et.flags & et.FLAG_SINGLE_LINE) > 0); + } + + public Bundle getBundle() { + return mFieldInfo; + } + + public String toString() { + return mFieldInfo.toString(); + } +} diff --git a/src/com/android/inputmethod/voice/GoogleSettingsUtil.java b/src/com/android/inputmethod/voice/GoogleSettingsUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..d238579bab17bee89b8984d139551aa0a804cedd --- /dev/null +++ b/src/com/android/inputmethod/voice/GoogleSettingsUtil.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.ContentResolver; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +/** + * Utility for getting Google-specific settings from GoogleSettings.Partner or + * Gservices. Retrieving such settings may fail on a non-Google Experience + * Device (GED) + */ +public class GoogleSettingsUtil { + /** + * A whitespace-separated list of supported locales for voice input from the keyboard. + */ + public static final String LATIN_IME_VOICE_INPUT_SUPPORTED_LOCALES = + "latin_ime_voice_input_supported_locales"; + + /** + * A whitespace-separated list of recommended app packages for voice input from the + * keyboard. + */ + public static final String LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES = + "latin_ime_voice_input_recommended_packages"; + + /** + * The maximum number of unique days to show the swipe hint for voice input. + */ + public static final String LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS = + "latin_ime_voice_input_swipe_hint_max_days"; + + /** + * The maximum number of times to show the punctuation hint for voice input. + */ + public static final String LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS = + "latin_ime_voice_input_punctuation_hint_max_displays"; + + /** + * Endpointer parameters for voice input from the keyboard. + */ + public static final String LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS = + "latin_ime_speech_minimum_length_millis"; + public static final String LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = + "latin_ime_speech_input_complete_silence_length_millis"; + public static final String LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = + "latin_ime_speech_input_possibly_complete_silence_length_millis"; + + /** + * Min and max volume levels that can be displayed on the "speak now" screen. + */ + public static final String LATIN_IME_MIN_MICROPHONE_LEVEL = + "latin_ime_min_microphone_level"; + public static final String LATIN_IME_MAX_MICROPHONE_LEVEL = + "latin_ime_max_microphone_level"; + + /** + * The number of sentence-level alternates to request of the server. + */ + public static final String LATIN_IME_MAX_VOICE_RESULTS = "latin_ime_max_voice_results"; + + /** + * Uri to use to access gservices settings + */ + private static final Uri GSERVICES_URI = Uri.parse("content://settings/gservices"); + + private static final String TAG = GoogleSettingsUtil.class.getSimpleName(); + + private static final boolean DBG = false; + + /** + * Safely query for a Gservices string setting, which may not be available if this + * is not a Google Experience Device. + * + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if none can be found + * @return The value of the setting, or defaultValue if it couldn't be found + */ + public static String getGservicesString(ContentResolver cr, String key, String defaultValue) { + return getSettingString(GSERVICES_URI, cr, key, defaultValue); + } + + /** + * Safely query for a Gservices int setting, which may not be available if this + * is not a Google Experience Device. + * + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if the setting couldn't be found or parsed + * @return The value of the setting, or defaultValue if it couldn't be found or parsed + */ + public static int getGservicesInt(ContentResolver cr, String key, int defaultValue) { + try { + return Integer.parseInt(getGservicesString(cr, key, String.valueOf(defaultValue))); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + /** + * Safely query for a Gservices float setting, which may not be available if this + * is not a Google Experience Device. + * + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if the setting couldn't be found or parsed + * @return The value of the setting, or defaultValue if it couldn't be found or parsed + */ + public static float getGservicesFloat(ContentResolver cr, String key, float defaultValue) { + try { + return Float.parseFloat(getGservicesString(cr, key, String.valueOf(defaultValue))); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + /** + * A safe way to query for a setting on both Google Experience and + * non-Google Experience devices, (code adapted from maps application + * examples) + * + * @param uri The uri to provide to the content resolver + * @param cr The content resolver to use + * @param key The setting to look up + * @param defaultValue The default value to use if none can be found + * @return The value of the setting, or defaultValue if it couldn't be found + */ + private static String getSettingString(Uri uri, ContentResolver cr, String key, + String defaultValue) { + String value = null; + + Cursor cursor = null; + try { + cursor = cr.query(uri, new String[] { + "value" + }, "name='" + key + "'", null, null); + if ((cursor != null) && cursor.moveToFirst()) { + value = cursor.getString(cursor.getColumnIndexOrThrow("value")); + } + } catch (Throwable t) { + // This happens because we're probably running a non Type 1 aka + // Google Experience device which doesn't have the Google libraries. + if (DBG) { + Log.d(TAG, "Error getting setting from " + uri + " for key " + key + ": " + t); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + if (DBG && value == null) { + Log.i(TAG, "no setting found from " + uri + " for key " + key + ", returning default"); + } + + return (value != null) ? value : defaultValue; + } +} diff --git a/src/com/android/inputmethod/voice/LatinIMEWithVoice.java b/src/com/android/inputmethod/voice/LatinIMEWithVoice.java new file mode 100644 index 0000000000000000000000000000000000000000..ccbf5b6bccc7e4be12859609a49fa4954a85f179 --- /dev/null +++ b/src/com/android/inputmethod/voice/LatinIMEWithVoice.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.Intent; + +import com.android.inputmethod.latin.LatinIME; + +public class LatinIMEWithVoice extends LatinIME { + @Override + protected void launchSettings() { + launchSettings(LatinIMEWithVoiceSettings.class); + } +} diff --git a/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java b/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..13a58e14d61e512207add5a8949f73153710bac7 --- /dev/null +++ b/src/com/android/inputmethod/voice/LatinIMEWithVoiceSettings.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import com.android.inputmethod.latin.LatinIMESettings; + +public class LatinIMEWithVoiceSettings extends LatinIMESettings {} diff --git a/src/com/android/inputmethod/voice/LoggingEvents.java b/src/com/android/inputmethod/voice/LoggingEvents.java new file mode 100644 index 0000000000000000000000000000000000000000..b63229186712ecd07cf3b533c6220c81420fc4ae --- /dev/null +++ b/src/com/android/inputmethod/voice/LoggingEvents.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2010 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +/** + * Logging event constants used for Voice Search and VoiceIME. These are the keys and values of + * extras to be specified in logging broadcast intents to the {@link LoggingReceiver}. + * + * This class is duplicated between VoiceSearch and LatinIME. Please keep both versions + * in sync. + */ +public class LoggingEvents { + // The name of the broadcast intent for logging. + public static final String ACTION_LOG_EVENT = "com.google.android.voicesearch.LOG_EVENT"; + + // The extra key used for the name of the app being logged. + public static final String EXTRA_APP_NAME = "app_name"; + + // The extra key used for the event value. The possible event values depend on the + // app being logged for, and are defined in the subclasses below. + public static final String EXTRA_EVENT = "extra_event"; + + // The extra key used (with a boolean value of 'true') as a way to trigger a flush + // of the log events to the server. + public static final String EXTRA_FLUSH = "flush"; + + /** + * Logging event constants for VoiceIME. Below are the extra values for + * {@link LoggingEvents#EXTRA_EVENT}, clustered with keys to additional extras + * for some events that need to be included as additional fields in the event. + */ + public class VoiceIme { + // The app name to be used for logging VoiceIME events. + public static final String APP_NAME = "voiceime"; + + public static final int KEYBOARD_WARNING_DIALOG_SHOWN = 0; + + public static final int KEYBOARD_WARNING_DIALOG_DISMISSED = 1; + + public static final int KEYBOARD_WARNING_DIALOG_OK = 2; + + public static final int KEYBOARD_WARNING_DIALOG_CANCEL = 3; + + public static final int SETTINGS_WARNING_DIALOG_SHOWN = 4; + + public static final int SETTINGS_WARNING_DIALOG_DISMISSED = 5; + + public static final int SETTINGS_WARNING_DIALOG_OK = 6; + + public static final int SETTINGS_WARNING_DIALOG_CANCEL = 7; + + public static final int SWIPE_HINT_DISPLAYED = 8; + + public static final int PUNCTUATION_HINT_DISPLAYED = 9; + + public static final int CANCEL_DURING_LISTENING = 10; + + public static final int CANCEL_DURING_WORKING = 11; + + public static final int CANCEL_DURING_ERROR = 12; + + public static final int ERROR = 13; + public static final String EXTRA_ERROR_CODE = "code"; // value should be int + + public static final int START = 14; + public static final String EXTRA_START_LOCALE = "locale"; // value should be String + public static final String EXTRA_START_SWIPE = "swipe"; // value should be boolean + + public static final int VOICE_INPUT_DELIVERED = 15; + + public static final int N_BEST_CHOOSE = 16; + public static final String EXTRA_N_BEST_CHOOSE_INDEX = "index"; // value should be int + + public static final int TEXT_MODIFIED = 17; + + public static final int INPUT_ENDED = 18; + + public static final int VOICE_INPUT_SETTING_ENABLED = 19; + + public static final int VOICE_INPUT_SETTING_DISABLED = 20; + } +} diff --git a/src/com/android/inputmethod/voice/RecognitionView.java b/src/com/android/inputmethod/voice/RecognitionView.java new file mode 100644 index 0000000000000000000000000000000000000000..97acb115266a2846b1665c06ec8da1bfaa451450 --- /dev/null +++ b/src/com/android/inputmethod/voice/RecognitionView.java @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.CornerPathEffect; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PathEffect; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.util.TypedValue; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup.MarginLayoutParams; +import android.widget.ImageView; +import android.widget.TextView; + +import com.android.inputmethod.latin.R; +import com.android.inputmethod.voice.GoogleSettingsUtil; + +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ShortBuffer; +import java.util.ArrayList; +import java.util.List; + +/** + * The user interface for the "Speak now" and "working" states. + * Displays a recognition dialog (with waveform, voice meter, etc.), + * plays beeps, shows errors, etc. + */ +public class RecognitionView { + private static final String TAG = "RecognitionView"; + + // If there's a significant delay between starting up voice search and the + // onset of audio recording, show the "initializing" screen first. If not, + // jump directly to the "speak now" screen to avoid flashing "initializing" + // quickly. + private static final boolean EXPECT_RECORDING_DELAY = true; + + private Handler mUiHandler; // Reference to UI thread + private View mView; + private Context mContext; + + private ImageView mImage; + private TextView mText; + private View mButton; + private TextView mButtonText; + private View mProgress; + + private Drawable mInitializing; + private Drawable mError; + private List<Drawable> mSpeakNow; + + private float mVolume = 0.0f; + private int mLevel = 0; + + private enum State {LISTENING, WORKING, READY} + private State mState = State.READY; + + private float mMinMicrophoneLevel; + private float mMaxMicrophoneLevel; + + /** Updates the microphone icon to show user their volume.*/ + private Runnable mUpdateVolumeRunnable = new Runnable() { + public void run() { + if (mState != State.LISTENING) { + return; + } + + final float min = mMinMicrophoneLevel; + final float max = mMaxMicrophoneLevel; + final int maxLevel = mSpeakNow.size() - 1; + + int index = (int) ((mVolume - min) / (max - min) * maxLevel); + final int level = Math.min(Math.max(0, index), maxLevel); + + if (level != mLevel) { + mImage.setImageDrawable(mSpeakNow.get(level)); + mLevel = level; + } + mUiHandler.postDelayed(mUpdateVolumeRunnable, 50); + } + }; + + public RecognitionView(Context context, OnClickListener clickListener) { + mUiHandler = new Handler(); + + LayoutInflater inflater = (LayoutInflater) context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mView = inflater.inflate(R.layout.recognition_status, null); + + ContentResolver cr = context.getContentResolver(); + mMinMicrophoneLevel = GoogleSettingsUtil.getGservicesFloat( + cr, GoogleSettingsUtil.LATIN_IME_MIN_MICROPHONE_LEVEL, 15.f); + mMaxMicrophoneLevel = GoogleSettingsUtil.getGservicesFloat( + cr, GoogleSettingsUtil.LATIN_IME_MAX_MICROPHONE_LEVEL, 30.f); + + // Pre-load volume level images + Resources r = context.getResources(); + + mSpeakNow = new ArrayList<Drawable>(); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level0)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level1)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level2)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level3)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level4)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level5)); + mSpeakNow.add(r.getDrawable(R.drawable.speak_now_level6)); + + mInitializing = r.getDrawable(R.drawable.mic_slash); + mError = r.getDrawable(R.drawable.caution); + + mImage = (ImageView) mView.findViewById(R.id.image); + mButton = mView.findViewById(R.id.button); + mButton.setOnClickListener(clickListener); + mText = (TextView) mView.findViewById(R.id.text); + mButtonText = (TextView) mView.findViewById(R.id.button_text); + mProgress = mView.findViewById(R.id.progress); + + mContext = context; + } + + public View getView() { + return mView; + } + + public void showInitializing() { + mUiHandler.post(new Runnable() { + public void run() { + mText.setText(R.string.voice_initializing); + mImage.setImageDrawable(mInitializing); + mButtonText.setText(mContext.getText(R.string.cancel)); + } + }); + } + + public void showStartState() { + if (EXPECT_RECORDING_DELAY) { + showInitializing(); + } else { + showListening(); + } + } + + public void showListening() { + mState = State.LISTENING; + mUiHandler.post(new Runnable() { + public void run() { + mText.setText(R.string.voice_listening); + mImage.setImageDrawable(mSpeakNow.get(0)); + mButtonText.setText(mContext.getText(R.string.cancel)); + } + }); + mUiHandler.postDelayed(mUpdateVolumeRunnable, 50); + } + + public void updateVoiceMeter(final float rmsdB) { + mVolume = rmsdB; + } + + public void showError(final String message) { + mState = State.READY; + mUiHandler.post(new Runnable() { + public void run() { + exitWorking(); + mText.setText(message); + mImage.setImageDrawable(mError); + mButtonText.setText(mContext.getText(R.string.ok)); + } + }); + } + + public void showWorking( + final ByteArrayOutputStream waveBuffer, + final int speechStartPosition, + final int speechEndPosition) { + + mState = State.WORKING; + + mUiHandler.post(new Runnable() { + public void run() { + mText.setText(R.string.voice_working); + mImage.setVisibility(View.GONE); + mProgress.setVisibility(View.VISIBLE); + final ShortBuffer buf = ByteBuffer.wrap(waveBuffer.toByteArray()) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + buf.position(0); + waveBuffer.reset(); + showWave(buf, speechStartPosition / 2, speechEndPosition / 2); + } + }); + } + + /** + * @return an average abs of the specified buffer. + */ + private static int getAverageAbs(ShortBuffer buffer, int start, int i, int npw) { + int from = start + i * npw; + int end = from + npw; + int total = 0; + for (int x = from; x < end; x++) { + total += Math.abs(buffer.get(x)); + } + return total / npw; + } + + + /** + * Shows waveform of input audio. + * + * Copied from version in VoiceSearch's RecognitionActivity. + * + * TODO: adjust stroke width based on the size of data. + * TODO: use dip rather than pixels. + */ + private void showWave(ShortBuffer waveBuffer, int startPosition, int endPosition) { + final int w = ((View) mImage.getParent()).getWidth(); + final int h = mImage.getHeight(); + if (w <= 0 || h <= 0) { + // view is not visible this time. Skip drawing. + return; + } + final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + final Canvas c = new Canvas(b); + final Paint paint = new Paint(); + paint.setColor(0xFFFFFFFF); // 0xAARRGGBB + paint.setAntiAlias(true); + paint.setStyle(Paint.Style.STROKE); + paint.setAlpha(0x90); + + final PathEffect effect = new CornerPathEffect(3); + paint.setPathEffect(effect); + + final int numSamples = waveBuffer.remaining(); + int endIndex; + if (endPosition == 0) { + endIndex = numSamples; + } else { + endIndex = Math.min(endPosition, numSamples); + } + + int startIndex = startPosition - 2000; // include 250ms before speech + if (startIndex < 0) { + startIndex = 0; + } + final int numSamplePerWave = 200; // 8KHz 25ms = 200 samples + final float scale = 10.0f / 65536.0f; + + final int count = (endIndex - startIndex) / numSamplePerWave; + final float deltaX = 1.0f * w / count; + int yMax = h / 2 - 10; + Path path = new Path(); + c.translate(0, yMax); + float x = 0; + path.moveTo(x, 0); + yMax -= 10; + for (int i = 0; i < count; i++) { + final int avabs = getAverageAbs(waveBuffer, startIndex, i , numSamplePerWave); + int sign = ( (i & 01) == 0) ? -1 : 1; + final float y = Math.min(yMax, avabs * h * scale) * sign; + path.lineTo(x, y); + x += deltaX; + path.lineTo(x, y); + } + if (deltaX > 4) { + paint.setStrokeWidth(3); + } else { + paint.setStrokeWidth(Math.max(1, (int) (deltaX -.05))); + } + c.drawPath(path, paint); + mImage.setImageBitmap(b); + mImage.setVisibility(View.VISIBLE); + MarginLayoutParams mProgressParams = (MarginLayoutParams)mProgress.getLayoutParams(); + mProgressParams.topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + -h / 2 - 18, mContext.getResources().getDisplayMetrics()); + + // Tweak the padding manually to fill out the whole view horizontally. + // TODO: Do this in the xml layout instead. + ((View) mImage.getParent()).setPadding(4, ((View) mImage.getParent()).getPaddingTop(), 3, + ((View) mImage.getParent()).getPaddingBottom()); + mProgress.setLayoutParams(mProgressParams); + } + + + public void finish() { + mState = State.READY; + mUiHandler.post(new Runnable() { + public void run() { + exitWorking(); + } + }); + showStartState(); + } + + private void exitWorking() { + mProgress.setVisibility(View.GONE); + mImage.setVisibility(View.VISIBLE); + } +} diff --git a/src/com/android/inputmethod/voice/VoiceInput.java b/src/com/android/inputmethod/voice/VoiceInput.java new file mode 100644 index 0000000000000000000000000000000000000000..2f45b654a57f382aa885fe8f116b7a11c16dbbf4 --- /dev/null +++ b/src/com/android/inputmethod/voice/VoiceInput.java @@ -0,0 +1,551 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Log; +import android.speech.IRecognitionListener; +import android.speech.RecognitionServiceUtil; +import android.speech.RecognizerIntent; +import android.speech.RecognitionResult; +import android.view.View; +import android.view.View.OnClickListener; +import com.android.inputmethod.latin.R; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Speech recognition input, including both user interface and a background + * process to stream audio to the network recognizer. This class supplies a + * View (getView()), which it updates as recognition occurs. The user of this + * class is responsible for making the view visible to the user, as well as + * handling various events returned through UiListener. + */ +public class VoiceInput implements OnClickListener { + private static final String TAG = "VoiceInput"; + private static final String EXTRA_RECOGNITION_CONTEXT = + "android.speech.extras.RECOGNITION_CONTEXT"; + private static final String EXTRA_CALLING_PACKAGE = "calling_package"; + + private static final String DEFAULT_RECOMMENDED_PACKAGES = + "com.android.mms " + + "com.google.android.gm " + + "com.google.android.talk " + + "com.google.android.apps.googlevoice " + + "com.android.email " + + "com.android.browser "; + + // WARNING! Before enabling this, fix the problem with calling getExtractedText() in + // landscape view. It causes Extracted text updates to be rejected due to a token mismatch + public static boolean ENABLE_WORD_CORRECTIONS = false; + + private static Boolean sVoiceIsAvailable = null; + + // Dummy word suggestion which means "delete current word" + public static final String DELETE_SYMBOL = " \u00D7 "; // times symbol + + private Whitelist mRecommendedList; + private Whitelist mBlacklist; + + private VoiceInputLogger mLogger; + + // Names of a few intent extras defined in VoiceSearch's RecognitionService. + // These let us tweak the endpointer parameters. + private static final String EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS = + "android.speech.extras.SPEECH_INPUT_MINIMUM_LENGTH_MILLIS"; + private static final String EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS = + "android.speech.extras.SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS"; + private static final String EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS = + "android.speech.extras.SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS"; + + // The usual endpointer default value for input complete silence length is 0.5 seconds, + // but that's used for things like voice search. For dictation-like voice input like this, + // we go with a more liberal value of 1 second. This value will only be used if a value + // is not provided from Gservices. + private static final String INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS = "1000"; + + // Used to record part of that state for logging purposes. + public static final int DEFAULT = 0; + public static final int LISTENING = 1; + public static final int WORKING = 2; + public static final int ERROR = 3; + + private int mState = DEFAULT; + + /** + * Events relating to the recognition UI. You must implement these. + */ + public interface UiListener { + + /** + * @param recognitionResults a set of transcripts for what the user + * spoke, sorted by likelihood. + */ + public void onVoiceResults( + List<String> recognitionResults, + Map<String, List<CharSequence>> alternatives); + + /** + * Called when the user cancels speech recognition. + */ + public void onCancelVoice(); + } + + private RecognitionServiceUtil.Connection mRecognitionConnection; + private IRecognitionListener mRecognitionListener; + private RecognitionView mRecognitionView; + private UiListener mUiListener; + private Context mContext; + private ScheduledThreadPoolExecutor mExecutor; + + /** + * @param context the service or activity in which we're runing. + * @param uiHandler object to receive events from VoiceInput. + */ + public VoiceInput(Context context, UiListener uiHandler) { + mLogger = VoiceInputLogger.getLogger(context); + mRecognitionListener = new IMERecognitionListener(); + mRecognitionConnection = new RecognitionServiceUtil.Connection() { + public synchronized void onServiceConnected( + ComponentName name, IBinder service) { + super.onServiceConnected(name, service); + } + }; + mUiListener = uiHandler; + mContext = context; + newView(); + + String recommendedPackages = GoogleSettingsUtil.getGservicesString( + context.getContentResolver(), + GoogleSettingsUtil.LATIN_IME_VOICE_INPUT_RECOMMENDED_PACKAGES, + DEFAULT_RECOMMENDED_PACKAGES); + + mRecommendedList = new Whitelist(); + for (String recommendedPackage : recommendedPackages.split("\\s+")) { + mRecommendedList.addApp(recommendedPackage); + } + + mBlacklist = new Whitelist(); + mBlacklist.addApp("com.android.setupwizard"); + + mExecutor = new ScheduledThreadPoolExecutor(1); + bindIfNecessary(); + } + + /** + * @return true if field is blacklisted for voice + */ + public boolean isBlacklistedField(FieldContext context) { + return mBlacklist.matches(context); + } + + /** + * Used to decide whether to show voice input hints for this field, etc. + * + * @return true if field is recommended for voice + */ + public boolean isRecommendedField(FieldContext context) { + return mRecommendedList.matches(context); + } + + /** + * @return true if the speech service is available on the platform. + */ + public static boolean voiceIsAvailable(Context context) { + if (sVoiceIsAvailable != null) { + return sVoiceIsAvailable; + } + + RecognitionServiceUtil.Connection recognitionConnection = + new RecognitionServiceUtil.Connection(); + boolean bound = context.bindService( + makeIntent(), recognitionConnection, Context.BIND_AUTO_CREATE); + context.unbindService(recognitionConnection); + sVoiceIsAvailable = bound; + return bound; + } + + /** + * Start listening for speech from the user. This will grab the microphone + * and start updating the view provided by getView(). It is the caller's + * responsibility to ensure that the view is visible to the user at this stage. + * + * @param context the same FieldContext supplied to voiceIsEnabled() + * @param swipe whether this voice input was started by swipe, for logging purposes + */ + public void startListening(FieldContext context, boolean swipe) { + mState = DEFAULT; + + Locale locale = Locale.getDefault(); + String localeString = locale.getLanguage() + "-" + locale.getCountry(); + + mLogger.start(localeString, swipe); + + mState = LISTENING; + + if (mRecognitionConnection.mService == null) { + mRecognitionView.showInitializing(); + } else { + mRecognitionView.showStartState(); + } + + if (!bindIfNecessary()) { + mState = ERROR; + + // We use CLIENT_ERROR to signify voice search is not available on the device. + onError(RecognitionResult.CLIENT_ERROR, false); + cancel(); + } + + if (mRecognitionConnection.mService != null) { + try { + Intent intent = makeIntent(); + intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, ""); + intent.putExtra(EXTRA_RECOGNITION_CONTEXT, context.getBundle()); + intent.putExtra(EXTRA_CALLING_PACKAGE, "VoiceIME"); + intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, + GoogleSettingsUtil.getGservicesInt( + mContext.getContentResolver(), + GoogleSettingsUtil.LATIN_IME_MAX_VOICE_RESULTS, + 1)); + + // Get endpointer params from Gservices. + // TODO: Consider caching these values for improved performance on slower devices. + ContentResolver cr = mContext.getContentResolver(); + putEndpointerExtra( + cr, + intent, + GoogleSettingsUtil.LATIN_IME_SPEECH_MINIMUM_LENGTH_MILLIS, + EXTRA_SPEECH_MINIMUM_LENGTH_MILLIS, + null /* rely on endpointer default */); + putEndpointerExtra( + cr, + intent, + GoogleSettingsUtil.LATIN_IME_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, + EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, + INPUT_COMPLETE_SILENCE_LENGTH_DEFAULT_VALUE_MILLIS + /* our default value is different from the endpointer's */); + putEndpointerExtra( + cr, + intent, + GoogleSettingsUtil. + LATIN_IME_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, + EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, + null /* rely on endpointer default */); + + mRecognitionConnection.mService.startListening( + intent, mRecognitionListener); + } catch (RemoteException e) { + Log.e(TAG, "Could not start listening", e); + onError(-1 /* no specific error, just show default error */, false); + } + } + } + + /** + * Gets the value of the provided Gservices key, attempts to parse it into a long, + * and if successful, puts the long value as an extra in the provided intent. + */ + private void putEndpointerExtra(ContentResolver cr, Intent i, + String gservicesKey, String intentExtraKey, String defaultValue) { + long l = -1; + String s = GoogleSettingsUtil.getGservicesString(cr, gservicesKey, defaultValue); + if (s != null) { + try { + l = Long.valueOf(s); + } catch (NumberFormatException e) { + Log.e(TAG, "could not parse value for " + gservicesKey + ": " + s); + } + } + + if (l != -1) i.putExtra(intentExtraKey, l); + } + + public void destroy() { + if (mRecognitionConnection.mService != null) { + //mContext.unbindService(mRecognitionConnection); + } + } + + /** + * Creates a new instance of the view that is returned by {@link #getView()} + * Clients should use this when a previously returned view is stuck in a + * layout that is being thrown away and a new one is need to show to the + * user. + */ + public void newView() { + mRecognitionView = new RecognitionView(mContext, this); + } + + /** + * @return a view that shows the recognition flow--e.g., "Speak now" and + * "working" dialogs. + */ + public View getView() { + return mRecognitionView.getView(); + } + + /** + * Handle the cancel button. + */ + public void onClick(View view) { + switch(view.getId()) { + case R.id.button: + cancel(); + break; + } + } + + public void logTextModified() { + mLogger.textModified(); + } + + public void logKeyboardWarningDialogShown() { + mLogger.keyboardWarningDialogShown(); + } + + public void logKeyboardWarningDialogDismissed() { + mLogger.keyboardWarningDialogDismissed(); + } + + public void logKeyboardWarningDialogOk() { + mLogger.keyboardWarningDialogOk(); + } + + public void logKeyboardWarningDialogCancel() { + mLogger.keyboardWarningDialogCancel(); + } + + public void logSwipeHintDisplayed() { + mLogger.swipeHintDisplayed(); + } + + public void logPunctuationHintDisplayed() { + mLogger.punctuationHintDisplayed(); + } + + public void logVoiceInputDelivered() { + mLogger.voiceInputDelivered(); + } + + public void logNBestChoose(int index) { + mLogger.nBestChoose(index); + } + + public void logInputEnded() { + mLogger.inputEnded(); + } + + public void flushLogs() { + mLogger.flush(); + } + + private static Intent makeIntent() { + Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + + // On Cupcake, use VoiceIMEHelper since VoiceSearch doesn't support. + // On Donut, always use VoiceSearch, since VoiceIMEHelper and + // VoiceSearch may conflict. + if (Build.VERSION.RELEASE.equals("1.5")) { + intent = intent.setClassName( + "com.google.android.voiceservice", + "com.google.android.voiceservice.IMERecognitionService"); + } else { + intent = intent.setClassName( + "com.google.android.voicesearch", + "com.google.android.voicesearch.RecognitionService"); + } + + return intent; + } + + /** + * Bind to the recognition service if necessary. + * @return true if we are bound or binding to the service, false if + * the recognition service is unavailable. + */ + private boolean bindIfNecessary() { + if (mRecognitionConnection.mService != null) { + return true; + } + return mContext.bindService( + makeIntent(), mRecognitionConnection, Context.BIND_AUTO_CREATE); + } + + /** + * Cancel in-progress speech recognition. + */ + public void cancel() { + switch (mState) { + case LISTENING: + mLogger.cancelDuringListening(); + break; + case WORKING: + mLogger.cancelDuringWorking(); + break; + case ERROR: + mLogger.cancelDuringError(); + break; + } + mState = DEFAULT; + + // Remove all pending tasks (e.g., timers to cancel voice input) + for (Runnable runnable : mExecutor.getQueue()) { + mExecutor.remove(runnable); + } + + if (mRecognitionConnection.mService != null) { + try { + mRecognitionConnection.mService.cancel(); + } catch (RemoteException e) { + Log.e(TAG, "Exception on cancel", e); + } + } + mUiListener.onCancelVoice(); + mRecognitionView.finish(); + } + + private int getErrorStringId(int errorType, boolean endpointed) { + switch (errorType) { + // We use CLIENT_ERROR to signify that voice search is not available on the device. + case RecognitionResult.CLIENT_ERROR: + return R.string.voice_not_installed; + case RecognitionResult.NETWORK_ERROR: + return R.string.voice_network_error; + case RecognitionResult.NETWORK_TIMEOUT: + return endpointed ? + R.string.voice_network_error : R.string.voice_too_much_speech; + case RecognitionResult.AUDIO_ERROR: + return R.string.voice_audio_error; + case RecognitionResult.SERVER_ERROR: + return R.string.voice_server_error; + case RecognitionResult.SPEECH_TIMEOUT: + return R.string.voice_speech_timeout; + case RecognitionResult.NO_MATCH: + return R.string.voice_no_match; + default: return R.string.voice_error; + } + } + + private void onError(int errorType, boolean endpointed) { + Log.i(TAG, "error " + errorType); + mLogger.error(errorType); + onError(mContext.getString(getErrorStringId(errorType, endpointed))); + } + + private void onError(String error) { + mState = ERROR; + mRecognitionView.showError(error); + // Wait a couple seconds and then automatically dismiss message. + mExecutor.schedule(new Runnable() { + public void run() { + cancel(); + }}, 2000, TimeUnit.MILLISECONDS); + } + + private class IMERecognitionListener extends IRecognitionListener.Stub { + // Waveform data + final ByteArrayOutputStream mWaveBuffer = new ByteArrayOutputStream(); + int mSpeechStart; + private boolean mEndpointed = false; + + public void onReadyForSpeech(Bundle noiseParams) { + mRecognitionView.showListening(); + } + + public void onBeginningOfSpeech() { + mEndpointed = false; + mSpeechStart = mWaveBuffer.size(); + } + + public void onRmsChanged(float rmsdB) { + mRecognitionView.updateVoiceMeter(rmsdB); + } + + public void onBufferReceived(byte[] buf) { + try { + mWaveBuffer.write(buf); + } catch (IOException e) {} + } + + public void onEndOfSpeech() { + mEndpointed = true; + mState = WORKING; + mRecognitionView.showWorking(mWaveBuffer, mSpeechStart, mWaveBuffer.size()); + } + + public void onError(int errorType) { + mState = ERROR; + VoiceInput.this.onError(errorType, mEndpointed); + } + + public void onResults(List<RecognitionResult> results, long token) { + mState = DEFAULT; + List<String> resultsAsText = new ArrayList<String>(); + for (RecognitionResult result : results) { + resultsAsText.add(result.mText); + } + + Map<String, List<CharSequence>> alternatives = + new HashMap<String, List<CharSequence>>(); + if (resultsAsText.size() >= 2 && ENABLE_WORD_CORRECTIONS) { + String[][] words = new String[resultsAsText.size()][]; + for (int i = 0; i < words.length; i++) { + words[i] = resultsAsText.get(i).split(" "); + } + + for (int key = 0; key < words[0].length; key++) { + alternatives.put(words[0][key], new ArrayList<CharSequence>()); + for (int alt = 1; alt < words.length; alt++) { + int keyBegin = key * words[alt].length / words[0].length; + int keyEnd = (key + 1) * words[alt].length / words[0].length; + + for (int i = keyBegin; i < Math.min(words[alt].length, keyEnd); i++) { + List<CharSequence> altList = alternatives.get(words[0][key]); + if (!altList.contains(words[alt][i]) && altList.size() < 6) { + altList.add(words[alt][i]); + } + } + } + } + } + + if (resultsAsText.size() > 5) { + resultsAsText = resultsAsText.subList(0, 5); + } + mUiListener.onVoiceResults(resultsAsText, alternatives); + mRecognitionView.finish(); + + destroy(); + } + } +} diff --git a/src/com/android/inputmethod/voice/VoiceInputLogger.java b/src/com/android/inputmethod/voice/VoiceInputLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..07d4d1c8c60212565b18a9ea199d71bddb12325d --- /dev/null +++ b/src/com/android/inputmethod/voice/VoiceInputLogger.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.content.Context; +import android.content.Intent; + +/** + * Provides the logging facility for voice input events. This fires broadcasts back to + * the voice search app which then logs on our behalf. + * + * Note that debug console logging does not occur in this class. If you want to + * see console output of these logging events, there is a boolean switch to turn + * on on the VoiceSearch side. + */ +public class VoiceInputLogger { + private static final String TAG = VoiceInputLogger.class.getSimpleName(); + + private static VoiceInputLogger sVoiceInputLogger; + + private final Context mContext; + + // The base intent used to form all broadcast intents to the logger + // in VoiceSearch. + private final Intent mBaseIntent; + + /** + * Returns the singleton of the logger. + * + * @param contextHint a hint context used when creating the logger instance. + * Ignored if the singleton instance already exists. + */ + public static synchronized VoiceInputLogger getLogger(Context contextHint) { + if (sVoiceInputLogger == null) { + sVoiceInputLogger = new VoiceInputLogger(contextHint); + } + return sVoiceInputLogger; + } + + public VoiceInputLogger(Context context) { + mContext = context; + + mBaseIntent = new Intent(LoggingEvents.ACTION_LOG_EVENT); + mBaseIntent.putExtra(LoggingEvents.EXTRA_APP_NAME, LoggingEvents.VoiceIme.APP_NAME); + } + + private Intent newLoggingBroadcast(int event) { + Intent i = new Intent(mBaseIntent); + i.putExtra(LoggingEvents.EXTRA_EVENT, event); + return i; + } + + public void flush() { + Intent i = new Intent(mBaseIntent); + i.putExtra(LoggingEvents.EXTRA_FLUSH, true); + mContext.sendBroadcast(i); + } + + public void keyboardWarningDialogShown() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_SHOWN)); + } + + public void keyboardWarningDialogDismissed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_DISMISSED)); + } + + public void keyboardWarningDialogOk() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_OK)); + } + + public void keyboardWarningDialogCancel() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.KEYBOARD_WARNING_DIALOG_CANCEL)); + } + + public void settingsWarningDialogShown() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_SHOWN)); + } + + public void settingsWarningDialogDismissed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_DISMISSED)); + } + + public void settingsWarningDialogOk() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_OK)); + } + + public void settingsWarningDialogCancel() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.SETTINGS_WARNING_DIALOG_CANCEL)); + } + + public void swipeHintDisplayed() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.SWIPE_HINT_DISPLAYED)); + } + + public void cancelDuringListening() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_LISTENING)); + } + + public void cancelDuringWorking() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_WORKING)); + } + + public void cancelDuringError() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.CANCEL_DURING_ERROR)); + } + + public void punctuationHintDisplayed() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.PUNCTUATION_HINT_DISPLAYED)); + } + + public void error(int code) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.ERROR); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_ERROR_CODE, code); + mContext.sendBroadcast(i); + } + + public void start(String locale, boolean swipe) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.START); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_LOCALE, locale); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_START_SWIPE, swipe); + mContext.sendBroadcast(i); + } + + public void voiceInputDelivered() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.VOICE_INPUT_DELIVERED)); + } + + public void textModified() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.TEXT_MODIFIED)); + } + + public void nBestChoose(int index) { + Intent i = newLoggingBroadcast(LoggingEvents.VoiceIme.N_BEST_CHOOSE); + i.putExtra(LoggingEvents.VoiceIme.EXTRA_N_BEST_CHOOSE_INDEX, index); + mContext.sendBroadcast(i); + } + + public void inputEnded() { + mContext.sendBroadcast(newLoggingBroadcast(LoggingEvents.VoiceIme.INPUT_ENDED)); + } + + public void voiceInputSettingEnabled() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_ENABLED)); + } + + public void voiceInputSettingDisabled() { + mContext.sendBroadcast(newLoggingBroadcast( + LoggingEvents.VoiceIme.VOICE_INPUT_SETTING_DISABLED)); + } +} diff --git a/src/com/android/inputmethod/voice/WaveformImage.java b/src/com/android/inputmethod/voice/WaveformImage.java new file mode 100644 index 0000000000000000000000000000000000000000..08d87c8f30dd1f761cd55e9da9d54b0da19f94ab --- /dev/null +++ b/src/com/android/inputmethod/voice/WaveformImage.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008-2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; + +import java.io.ByteArrayOutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.ShortBuffer; + +/** + * Utility class to draw a waveform into a bitmap, given a byte array + * that represents the waveform as a sequence of 16-bit integers. + * Adapted from RecognitionActivity.java. + */ +public class WaveformImage { + private static final int SAMPLING_RATE = 8000; + + private WaveformImage() {} + + public static Bitmap drawWaveform( + ByteArrayOutputStream waveBuffer, int w, int h, int start, int end) { + final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); + final Canvas c = new Canvas(b); + final Paint paint = new Paint(); + paint.setColor(0xFFFFFFFF); // 0xRRGGBBAA + paint.setAntiAlias(true); + paint.setStrokeWidth(0); + + final ShortBuffer buf = ByteBuffer + .wrap(waveBuffer.toByteArray()) + .order(ByteOrder.nativeOrder()) + .asShortBuffer(); + buf.position(0); + + final int numSamples = waveBuffer.size() / 2; + final int delay = (SAMPLING_RATE * 100 / 1000); + int endIndex = end / 2 + delay; + if (end == 0 || endIndex >= numSamples) { + endIndex = numSamples; + } + int index = start / 2 - delay; + if (index < 0) { + index = 0; + } + final int size = endIndex - index; + int numSamplePerPixel = 32; + int delta = size / (numSamplePerPixel * w); + if (delta == 0) { + numSamplePerPixel = size / w; + delta = 1; + } + + final float scale = 3.5f / 65536.0f; + // do one less column to make sure we won't read past + // the buffer. + try { + for (int i = 0; i < w - 1 ; i++) { + final float x = i; + for (int j = 0; j < numSamplePerPixel; j++) { + final short s = buf.get(index); + final float y = (h / 2) - (s * h * scale); + c.drawPoint(x, y, paint); + index += delta; + } + } + } catch (IndexOutOfBoundsException e) { + // this can happen, but we don't care + } + + return b; + } +} diff --git a/src/com/android/inputmethod/voice/Whitelist.java b/src/com/android/inputmethod/voice/Whitelist.java new file mode 100644 index 0000000000000000000000000000000000000000..167b688caf2bc84d37b608aa408447dfac565142 --- /dev/null +++ b/src/com/android/inputmethod/voice/Whitelist.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.voice; + +import android.os.Bundle; +import java.util.ArrayList; +import java.util.List; + +/** + * A set of text fields where speech has been explicitly enabled. + */ +public class Whitelist { + private List<Bundle> mConditions; + + public Whitelist() { + mConditions = new ArrayList<Bundle>(); + } + + public Whitelist(List<Bundle> conditions) { + this.mConditions = conditions; + } + + public void addApp(String app) { + Bundle bundle = new Bundle(); + bundle.putString("packageName", app); + mConditions.add(bundle); + } + + /** + * @return true if the field is a member of the whitelist. + */ + public boolean matches(FieldContext context) { + for (Bundle condition : mConditions) { + if (matches(condition, context.getBundle())) { + return true; + } + } + return false; + } + + /** + * @return true of all values in condition are matched by a value + * in target. + */ + private boolean matches(Bundle condition, Bundle target) { + for (String key : condition.keySet()) { + if (!condition.getString(key).equals(target.getString(key))) { + return false; + } + } + return true; + } +} diff --git a/src/com/google/android/voicesearch/LatinIMEWithVoice.java b/src/com/google/android/voicesearch/LatinIMEWithVoice.java new file mode 100644 index 0000000000000000000000000000000000000000..8a339d14a4a2e62738d38e38ea6cf68a1518ba34 --- /dev/null +++ b/src/com/google/android/voicesearch/LatinIMEWithVoice.java @@ -0,0 +1,29 @@ +/* + * + * Copyright (C) 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations under +* the License. +*/ + +package com.google.android.voicesearch; + +import android.content.Intent; + +import com.android.inputmethod.latin.LatinIME; + +public class LatinIMEWithVoice extends LatinIME { + @Override + protected void launchSettings() { + launchSettings(LatinIMEWithVoiceSettings.class); + } +} diff --git a/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java b/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..a53cebfd906f5eca32b05c83a95f349a452cfca6 --- /dev/null +++ b/src/com/google/android/voicesearch/LatinIMEWithVoiceSettings.java @@ -0,0 +1,5 @@ +package com.google.android.voicesearch; + +import com.android.inputmethod.latin.LatinIMESettings; + +public class LatinIMEWithVoiceSettings extends LatinIMESettings {}