/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/Hints.java

http://eyes-free.googlecode.com/ · Java · 187 lines · 126 code · 31 blank · 30 comment · 19 complexity · 3323079f18d86f65c8ca4a8e8e4d2ccc MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.googlecode.eyesfree.inputmethod.latin;
  17. import android.content.ContentResolver;
  18. import android.content.Context;
  19. import android.content.SharedPreferences;
  20. import android.preference.PreferenceManager;
  21. import android.view.inputmethod.InputConnection;
  22. import com.googlecode.eyesfree.inputmethod.voice.SettingsUtil;
  23. import java.util.Calendar;
  24. import java.util.HashMap;
  25. import java.util.Map;
  26. /**
  27. * Logic to determine when to display hints on usage to the user.
  28. */
  29. public class Hints {
  30. public interface Display {
  31. public void showHint(int viewResource);
  32. }
  33. private static final String PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN =
  34. "voice_hint_num_unique_days_shown";
  35. private static final String PREF_VOICE_HINT_LAST_TIME_SHOWN =
  36. "voice_hint_last_time_shown";
  37. private static final String PREF_VOICE_INPUT_LAST_TIME_USED =
  38. "voice_input_last_time_used";
  39. private static final String PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT =
  40. "voice_punctuation_hint_view_count";
  41. private static final int DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW = 7;
  42. private static final int DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS = 7;
  43. private Context mContext;
  44. private Display mDisplay;
  45. private boolean mVoiceResultContainedPunctuation;
  46. private int mSwipeHintMaxDaysToShow;
  47. private int mPunctuationHintMaxDisplays;
  48. // Only show punctuation hint if voice result did not contain punctuation.
  49. static final Map<CharSequence, String> SPEAKABLE_PUNCTUATION
  50. = new HashMap<CharSequence, String>();
  51. static {
  52. SPEAKABLE_PUNCTUATION.put(",", "comma");
  53. SPEAKABLE_PUNCTUATION.put(".", "period");
  54. SPEAKABLE_PUNCTUATION.put("?", "question mark");
  55. }
  56. public Hints(Context context, Display display) {
  57. mContext = context;
  58. mDisplay = display;
  59. ContentResolver cr = mContext.getContentResolver();
  60. mSwipeHintMaxDaysToShow = SettingsUtil.getSettingsInt(
  61. cr,
  62. SettingsUtil.LATIN_IME_VOICE_INPUT_SWIPE_HINT_MAX_DAYS,
  63. DEFAULT_SWIPE_HINT_MAX_DAYS_TO_SHOW);
  64. mPunctuationHintMaxDisplays = SettingsUtil.getSettingsInt(
  65. cr,
  66. SettingsUtil.LATIN_IME_VOICE_INPUT_PUNCTUATION_HINT_MAX_DISPLAYS,
  67. DEFAULT_PUNCTUATION_HINT_MAX_DISPLAYS);
  68. }
  69. public boolean showSwipeHintIfNecessary(boolean fieldRecommended) {
  70. if (fieldRecommended && shouldShowSwipeHint()) {
  71. showHint(R.layout.voice_swipe_hint);
  72. return true;
  73. }
  74. return false;
  75. }
  76. public boolean showPunctuationHintIfNecessary(InputConnection ic) {
  77. if (!mVoiceResultContainedPunctuation
  78. && ic != null
  79. && getAndIncrementPref(PREF_VOICE_PUNCTUATION_HINT_VIEW_COUNT)
  80. < mPunctuationHintMaxDisplays) {
  81. CharSequence charBeforeCursor = ic.getTextBeforeCursor(1, 0);
  82. if (SPEAKABLE_PUNCTUATION.containsKey(charBeforeCursor)) {
  83. showHint(R.layout.voice_punctuation_hint);
  84. return true;
  85. }
  86. }
  87. return false;
  88. }
  89. public void registerVoiceResult(String text) {
  90. // Update the current time as the last time voice input was used.
  91. SharedPreferences.Editor editor =
  92. PreferenceManager.getDefaultSharedPreferences(mContext).edit();
  93. editor.putLong(PREF_VOICE_INPUT_LAST_TIME_USED, System.currentTimeMillis());
  94. SharedPreferencesCompat.apply(editor);
  95. mVoiceResultContainedPunctuation = false;
  96. for (CharSequence s : SPEAKABLE_PUNCTUATION.keySet()) {
  97. if (text.indexOf(s.toString()) >= 0) {
  98. mVoiceResultContainedPunctuation = true;
  99. break;
  100. }
  101. }
  102. }
  103. private boolean shouldShowSwipeHint() {
  104. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
  105. int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
  106. // If we've already shown the hint for enough days, we'll return false.
  107. if (numUniqueDaysShown < mSwipeHintMaxDaysToShow) {
  108. long lastTimeVoiceWasUsed = sp.getLong(PREF_VOICE_INPUT_LAST_TIME_USED, 0);
  109. // If the user has used voice today, we'll return false. (We don't show the hint on
  110. // any day that the user has already used voice.)
  111. if (!isFromToday(lastTimeVoiceWasUsed)) {
  112. return true;
  113. }
  114. }
  115. return false;
  116. }
  117. /**
  118. * Determines whether the provided time is from some time today (i.e., this day, month,
  119. * and year).
  120. */
  121. private boolean isFromToday(long timeInMillis) {
  122. if (timeInMillis == 0) return false;
  123. Calendar today = Calendar.getInstance();
  124. today.setTimeInMillis(System.currentTimeMillis());
  125. Calendar timestamp = Calendar.getInstance();
  126. timestamp.setTimeInMillis(timeInMillis);
  127. return (today.get(Calendar.YEAR) == timestamp.get(Calendar.YEAR) &&
  128. today.get(Calendar.DAY_OF_MONTH) == timestamp.get(Calendar.DAY_OF_MONTH) &&
  129. today.get(Calendar.MONTH) == timestamp.get(Calendar.MONTH));
  130. }
  131. private void showHint(int hintViewResource) {
  132. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
  133. int numUniqueDaysShown = sp.getInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, 0);
  134. long lastTimeHintWasShown = sp.getLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, 0);
  135. // If this is the first time the hint is being shown today, increase the saved values
  136. // to represent that. We don't need to increase the last time the hint was shown unless
  137. // it is a different day from the current value.
  138. if (!isFromToday(lastTimeHintWasShown)) {
  139. SharedPreferences.Editor editor = sp.edit();
  140. editor.putInt(PREF_VOICE_HINT_NUM_UNIQUE_DAYS_SHOWN, numUniqueDaysShown + 1);
  141. editor.putLong(PREF_VOICE_HINT_LAST_TIME_SHOWN, System.currentTimeMillis());
  142. SharedPreferencesCompat.apply(editor);
  143. }
  144. if (mDisplay != null) {
  145. mDisplay.showHint(hintViewResource);
  146. }
  147. }
  148. private int getAndIncrementPref(String pref) {
  149. SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
  150. int value = sp.getInt(pref, 0);
  151. SharedPreferences.Editor editor = sp.edit();
  152. editor.putInt(pref, value + 1);
  153. SharedPreferencesCompat.apply(editor);
  154. return value;
  155. }
  156. }