1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of 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, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.samplespellcheckerservice; 18 19 import android.os.Build; 20 import android.service.textservice.SpellCheckerService; 21 import android.util.Log; 22 import android.view.textservice.SentenceSuggestionsInfo; 23 import android.view.textservice.SuggestionsInfo; 24 import android.view.textservice.TextInfo; 25 26 import java.util.ArrayList; 27 28 public class SampleSpellCheckerService extends SpellCheckerService { 29 private static final String TAG = SampleSpellCheckerService.class.getSimpleName(); 30 private static final boolean DBG = true; 31 32 @Override createSession()33 public Session createSession() { 34 return new AndroidSpellCheckerSession(); 35 } 36 37 private static class AndroidSpellCheckerSession extends Session { 38 isSentenceSpellCheckApiSupported()39 private boolean isSentenceSpellCheckApiSupported() { 40 // Note that the sentence level spell check APIs work on Jelly Bean or later. 41 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN; 42 } 43 44 private String mLocale; 45 @Override onCreate()46 public void onCreate() { 47 mLocale = getLocale(); 48 } 49 50 /** 51 * This method should have a concrete implementation in all spell checker services. 52 * Please note that the default implementation of 53 * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} 54 * calls up this method. You may want to override 55 * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} 56 * by your own implementation if you'd like to provide an optimized implementation for 57 * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)}. 58 */ 59 @Override onGetSuggestions(TextInfo textInfo, int suggestionsLimit)60 public SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit) { 61 if (DBG) { 62 Log.d(TAG, "onGetSuggestions: " + textInfo.getText()); 63 } 64 final String input = textInfo.getText(); 65 final int length = input.length(); 66 // Just a fake logic: 67 // length <= 3 for short words that we assume are in the fake dictionary 68 // length > 20 for too long words that we assume can't be recognized (such as CJK words) 69 final int flags = length <= 3 ? SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY 70 : length <= 20 ? SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO : 0; 71 return new SuggestionsInfo(flags, 72 new String[] {"aaa", "bbb", "Candidate for " + input, mLocale}); 73 } 74 75 /** 76 * Please consider providing your own implementation of sentence level spell checking. 77 * Please note that this sample implementation is just a mock to demonstrate how a sentence 78 * level spell checker returns the result. 79 * If you don't override this method, the framework converts queries of 80 * {@link SpellCheckerService.Session#onGetSentenceSuggestionsMultiple(TextInfo[], int)} 81 * to queries of 82 * {@link SpellCheckerService.Session#onGetSuggestionsMultiple(TextInfo[], int, boolean)} 83 * by the default implementation. 84 */ 85 @Override onGetSentenceSuggestionsMultiple( TextInfo[] textInfos, int suggestionsLimit)86 public SentenceSuggestionsInfo[] onGetSentenceSuggestionsMultiple( 87 TextInfo[] textInfos, int suggestionsLimit) { 88 if (!isSentenceSpellCheckApiSupported()) { 89 Log.e(TAG, "Sentence spell check is not supported on this platform, " 90 + "but accidentially called."); 91 return null; 92 } 93 final ArrayList<SentenceSuggestionsInfo> retval = 94 new ArrayList<SentenceSuggestionsInfo>(); 95 for (int i = 0; i < textInfos.length; ++i) { 96 final TextInfo ti = textInfos[i]; 97 if (DBG) { 98 Log.d(TAG, "onGetSentenceSuggestionsMultiple: " + ti.getText()); 99 } 100 final String input = ti.getText(); 101 final int length = input.length(); 102 final SuggestionsInfo[] sis; 103 final int[] lengths; 104 final int[] offsets; 105 if (input.equalsIgnoreCase("I wold like to here form you")) { 106 // Return sentence level suggestion for this fixed input 107 final int flags0 = SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO; 108 final int flags1 = SuggestionsInfo.RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS 109 | SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO; 110 final int flags2 = flags1; 111 final SuggestionsInfo si0 = new SuggestionsInfo( 112 flags0, new String[] { "would" }); 113 final SuggestionsInfo si1 = new SuggestionsInfo( 114 flags1, new String[] { "hear" }); 115 final SuggestionsInfo si2 = new SuggestionsInfo( 116 flags2, new String[] { "from" }); 117 sis = new SuggestionsInfo[] {si0, si1, si2}; 118 offsets = new int[] { 2, 15, 20 }; 119 lengths = new int[] { 4, 4, 4 }; 120 } else { 121 // Just a mock logic: 122 // length <= 3 for short words that we assume are in the fake dictionary 123 // length > 20 for too long words that we assume can't be recognized 124 // (such as CJK words) 125 final int flags = length <= 3 ? SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY 126 : length <= 20 ? SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO : 0; 127 final SuggestionsInfo si = new SuggestionsInfo(flags, 128 new String[] {"aaa", "bbb", "Candidate for " + input, mLocale}); 129 sis = new SuggestionsInfo[] { si }; 130 offsets = new int[] { 0 }; 131 lengths = new int[] { ti.getText().length() }; 132 } 133 final SentenceSuggestionsInfo ssi = 134 new SentenceSuggestionsInfo(sis, lengths, offsets); 135 retval.add(ssi); 136 } 137 return retval.toArray(new SentenceSuggestionsInfo[0]); 138 } 139 } 140 } 141