164c64e7c25e6efe31fa53369ec49db442b68ff9amah/* 264c64e7c25e6efe31fa53369ec49db442b68ff9amah * Copyright (C) 2010 The Android Open Source Project 364c64e7c25e6efe31fa53369ec49db442b68ff9amah * 464c64e7c25e6efe31fa53369ec49db442b68ff9amah * Licensed under the Apache License, Version 2.0 (the "License"); 564c64e7c25e6efe31fa53369ec49db442b68ff9amah * you may not use this file except in compliance with the License. 664c64e7c25e6efe31fa53369ec49db442b68ff9amah * You may obtain a copy of the License at 764c64e7c25e6efe31fa53369ec49db442b68ff9amah * 864c64e7c25e6efe31fa53369ec49db442b68ff9amah * http://www.apache.org/licenses/LICENSE-2.0 964c64e7c25e6efe31fa53369ec49db442b68ff9amah * 1064c64e7c25e6efe31fa53369ec49db442b68ff9amah * Unless required by applicable law or agreed to in writing, software 1164c64e7c25e6efe31fa53369ec49db442b68ff9amah * distributed under the License is distributed on an "AS IS" BASIS, 1264c64e7c25e6efe31fa53369ec49db442b68ff9amah * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1364c64e7c25e6efe31fa53369ec49db442b68ff9amah * See the License for the specific language governing permissions and 1464c64e7c25e6efe31fa53369ec49db442b68ff9amah * limitations under the License. 1564c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 1664c64e7c25e6efe31fa53369ec49db442b68ff9amahpackage com.android.voicedialer; 1764c64e7c25e6efe31fa53369ec49db442b68ff9amah 1864c64e7c25e6efe31fa53369ec49db442b68ff9amah 1964c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.content.ContentUris; 2064c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.content.Context; 2164c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.content.Intent; 2264c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.content.pm.PackageManager; 2364c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.content.pm.ResolveInfo; 2464c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.content.res.Resources; 2564c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.net.Uri; 2664c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.provider.ContactsContract.CommonDataKinds.Phone; 2764c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.speech.srec.Recognizer; 2864c64e7c25e6efe31fa53369ec49db442b68ff9amahimport android.util.Log; 2985a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa 3064c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.File; 3164c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.FileFilter; 3264c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.FileInputStream; 3364c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.FileOutputStream; 3464c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.IOException; 3564c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.ObjectInputStream; 3664c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.io.ObjectOutputStream; 3764c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.net.URISyntaxException; 3864c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.util.ArrayList; 3964c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.util.HashMap; 4064c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.util.HashSet; 4164c64e7c25e6efe31fa53369ec49db442b68ff9amahimport java.util.List; 4264c64e7c25e6efe31fa53369ec49db442b68ff9amah/** 4364c64e7c25e6efe31fa53369ec49db442b68ff9amah * This is a RecognizerEngine that processes commands to make phone calls and 4464c64e7c25e6efe31fa53369ec49db442b68ff9amah * open applications. 4564c64e7c25e6efe31fa53369ec49db442b68ff9amah * <ul> 467a55150b308ed03d41091e4c3ac693d6eb0ab145mah * <li>setupGrammar 4764c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>Scans contacts and determine if the Grammar g2g file is stale. 4864c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>If so, create and rebuild the Grammar, 4964c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>Else create and load the Grammar from the file. 5064c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>onRecognitionSuccess is called when we get results from the recognizer, 5164c64e7c25e6efe31fa53369ec49db442b68ff9amah * it will process the results, which will pass a list of intents to 5264c64e7c25e6efe31fa53369ec49db442b68ff9amah * the {@RecognizerClient}. It will accept the following types of commands: 5364c64e7c25e6efe31fa53369ec49db442b68ff9amah * "call" a particular contact 5464c64e7c25e6efe31fa53369ec49db442b68ff9amah * "dial a particular number 5564c64e7c25e6efe31fa53369ec49db442b68ff9amah * "open" a particular application 5664c64e7c25e6efe31fa53369ec49db442b68ff9amah * "redial" the last number called 5764c64e7c25e6efe31fa53369ec49db442b68ff9amah * "voicemail" to call voicemail 5864c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>Pass a list of {@link Intent} corresponding to the recognition results 5964c64e7c25e6efe31fa53369ec49db442b68ff9amah * to the {@link RecognizerClient}, which notifies the user. 6064c64e7c25e6efe31fa53369ec49db442b68ff9amah * </ul> 6164c64e7c25e6efe31fa53369ec49db442b68ff9amah * Notes: 6264c64e7c25e6efe31fa53369ec49db442b68ff9amah * <ul> 6364c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>Audio many be read from a file. 6464c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>A directory tree of audio files may be stepped through. 6564c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>A contact list may be read from a file. 6664c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>A {@link RecognizerLogger} may generate a set of log files from 6764c64e7c25e6efe31fa53369ec49db442b68ff9amah * a recognition session. 6864c64e7c25e6efe31fa53369ec49db442b68ff9amah * <li>A static instance of this class is held and reused by the 6964c64e7c25e6efe31fa53369ec49db442b68ff9amah * {@link VoiceDialerActivity}, which saves setup time. 7064c64e7c25e6efe31fa53369ec49db442b68ff9amah * </ul> 7164c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 7264c64e7c25e6efe31fa53369ec49db442b68ff9amahpublic class CommandRecognizerEngine extends RecognizerEngine { 7364c64e7c25e6efe31fa53369ec49db442b68ff9amah 7464c64e7c25e6efe31fa53369ec49db442b68ff9amah private static final String OPEN_ENTRIES = "openentries.txt"; 757a55150b308ed03d41091e4c3ac693d6eb0ab145mah public static final String PHONE_TYPE_EXTRA = "phone_type"; 767a55150b308ed03d41091e4c3ac693d6eb0ab145mah private static final int MINIMUM_CONFIDENCE = 100; 7764c64e7c25e6efe31fa53369ec49db442b68ff9amah private File mContactsFile; 787a55150b308ed03d41091e4c3ac693d6eb0ab145mah private boolean mMinimizeResults; 795f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon private boolean mAllowOpenEntries; 804a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon private HashMap<String,String> mOpenEntries; 815f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon 8264c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 8364c64e7c25e6efe31fa53369ec49db442b68ff9amah * Constructor. 8464c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 8564c64e7c25e6efe31fa53369ec49db442b68ff9amah public CommandRecognizerEngine() { 867a55150b308ed03d41091e4c3ac693d6eb0ab145mah mContactsFile = null; 877a55150b308ed03d41091e4c3ac693d6eb0ab145mah mMinimizeResults = false; 885f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon mAllowOpenEntries = true; 8964c64e7c25e6efe31fa53369ec49db442b68ff9amah } 9064c64e7c25e6efe31fa53369ec49db442b68ff9amah 9164c64e7c25e6efe31fa53369ec49db442b68ff9amah public void setContactsFile(File contactsFile) { 924a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon if (contactsFile != mContactsFile) { 934a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mContactsFile = contactsFile; 944a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // if we change the contacts file, then we need to recreate the grammar. 954a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon if (mSrecGrammar != null) { 964a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mSrecGrammar.destroy(); 974a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mSrecGrammar = null; 984a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mOpenEntries = null; 994a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon } 10064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 10164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 10264c64e7c25e6efe31fa53369ec49db442b68ff9amah 1037a55150b308ed03d41091e4c3ac693d6eb0ab145mah public void setMinimizeResults(boolean minimizeResults) { 1047a55150b308ed03d41091e4c3ac693d6eb0ab145mah mMinimizeResults = minimizeResults; 1057a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 1067a55150b308ed03d41091e4c3ac693d6eb0ab145mah 1075f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon public void setAllowOpenEntries(boolean allowOpenEntries) { 1085f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon if (mAllowOpenEntries != allowOpenEntries) { 1095f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon // if we change this setting, then we need to recreate the grammar. 1105f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon if (mSrecGrammar != null) { 1115f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon mSrecGrammar.destroy(); 1125f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon mSrecGrammar = null; 1134a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mOpenEntries = null; 1145f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon } 1155f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon } 1165f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon mAllowOpenEntries = allowOpenEntries; 1175f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon } 1185f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon 11964c64e7c25e6efe31fa53369ec49db442b68ff9amah protected void setupGrammar() throws IOException, InterruptedException { 12064c64e7c25e6efe31fa53369ec49db442b68ff9amah // fetch the contact list 121d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "start getVoiceContacts"); 122d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "contactsFile is " + (mContactsFile == null ? 12364c64e7c25e6efe31fa53369ec49db442b68ff9amah "null" : "not null")); 12464c64e7c25e6efe31fa53369ec49db442b68ff9amah List<VoiceContact> contacts = mContactsFile != null ? 12564c64e7c25e6efe31fa53369ec49db442b68ff9amah VoiceContact.getVoiceContactsFromFile(mContactsFile) : 12664c64e7c25e6efe31fa53369ec49db442b68ff9amah VoiceContact.getVoiceContacts(mActivity); 12764c64e7c25e6efe31fa53369ec49db442b68ff9amah 12864c64e7c25e6efe31fa53369ec49db442b68ff9amah // log contacts if requested 12964c64e7c25e6efe31fa53369ec49db442b68ff9amah if (mLogger != null) mLogger.logContacts(contacts); 13064c64e7c25e6efe31fa53369ec49db442b68ff9amah // generate g2g grammar file name 13164c64e7c25e6efe31fa53369ec49db442b68ff9amah File g2g = mActivity.getFileStreamPath("voicedialer." + 13264c64e7c25e6efe31fa53369ec49db442b68ff9amah Integer.toHexString(contacts.hashCode()) + ".g2g"); 13364c64e7c25e6efe31fa53369ec49db442b68ff9amah 13464c64e7c25e6efe31fa53369ec49db442b68ff9amah // rebuild g2g file if current one is out of date 13564c64e7c25e6efe31fa53369ec49db442b68ff9amah if (!g2g.exists()) { 13664c64e7c25e6efe31fa53369ec49db442b68ff9amah // clean up existing Grammar and old file 13764c64e7c25e6efe31fa53369ec49db442b68ff9amah deleteAllG2GFiles(mActivity); 13864c64e7c25e6efe31fa53369ec49db442b68ff9amah if (mSrecGrammar != null) { 13964c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.destroy(); 14064c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar = null; 14164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 14264c64e7c25e6efe31fa53369ec49db442b68ff9amah 14364c64e7c25e6efe31fa53369ec49db442b68ff9amah // load the empty Grammar 144d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "start new Grammar"); 14564c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar = mSrec.new Grammar(SREC_DIR + "/grammars/VoiceDialer.g2g"); 14664c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.setupRecognizer(); 14764c64e7c25e6efe31fa53369ec49db442b68ff9amah 14864c64e7c25e6efe31fa53369ec49db442b68ff9amah // reset slots 149d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "start grammar.resetAllSlots"); 15064c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.resetAllSlots(); 15164c64e7c25e6efe31fa53369ec49db442b68ff9amah 15264c64e7c25e6efe31fa53369ec49db442b68ff9amah // add names to the grammar 15364c64e7c25e6efe31fa53369ec49db442b68ff9amah addNameEntriesToGrammar(contacts); 15464c64e7c25e6efe31fa53369ec49db442b68ff9amah 1555f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon if (mAllowOpenEntries) { 1565f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon // add open entries to the grammar 1575f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon addOpenEntriesToGrammar(); 1585f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon } 15978d0235501ca19dd38e2ab12ed60c3fa86199fceMartin Hibdon 16064c64e7c25e6efe31fa53369ec49db442b68ff9amah // compile the grammar 161d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "start grammar.compile"); 16264c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.compile(); 16364c64e7c25e6efe31fa53369ec49db442b68ff9amah 16464c64e7c25e6efe31fa53369ec49db442b68ff9amah // update g2g file 165d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "start grammar.save " + g2g.getPath()); 16664c64e7c25e6efe31fa53369ec49db442b68ff9amah g2g.getParentFile().mkdirs(); 16764c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.save(g2g.getPath()); 16864c64e7c25e6efe31fa53369ec49db442b68ff9amah } 16964c64e7c25e6efe31fa53369ec49db442b68ff9amah 17064c64e7c25e6efe31fa53369ec49db442b68ff9amah // g2g file exists, but is not loaded 17164c64e7c25e6efe31fa53369ec49db442b68ff9amah else if (mSrecGrammar == null) { 172d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "start new Grammar loading " + g2g); 17364c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar = mSrec.new Grammar(g2g.getPath()); 17464c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.setupRecognizer(); 17564c64e7c25e6efe31fa53369ec49db442b68ff9amah } 1764a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon if (mOpenEntries == null && mAllowOpenEntries) { 1774a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // make sure to load the openEntries mapping table. 1784a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon loadOpenEntriesTable(); 1794a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon } 1804a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon 18164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 18264c64e7c25e6efe31fa53369ec49db442b68ff9amah 18364c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 18485a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa * Number of phone ids appended to a grammer in {@link #addNameEntriesToGrammar(List)}. 18585a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa */ 18685a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa private static final int PHONE_ID_COUNT = 7; 18785a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa 18885a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa /** 18964c64e7c25e6efe31fa53369ec49db442b68ff9amah * Add a list of names to the grammar 19064c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param contacts list of VoiceContacts to be added. 19164c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 19264c64e7c25e6efe31fa53369ec49db442b68ff9amah private void addNameEntriesToGrammar(List<VoiceContact> contacts) 19364c64e7c25e6efe31fa53369ec49db442b68ff9amah throws InterruptedException { 194d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "addNameEntriesToGrammar " + contacts.size()); 19564c64e7c25e6efe31fa53369ec49db442b68ff9amah 19664c64e7c25e6efe31fa53369ec49db442b68ff9amah HashSet<String> entries = new HashSet<String>(); 19785a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa StringBuilder sb = new StringBuilder(); 19864c64e7c25e6efe31fa53369ec49db442b68ff9amah int count = 0; 19964c64e7c25e6efe31fa53369ec49db442b68ff9amah for (VoiceContact contact : contacts) { 20064c64e7c25e6efe31fa53369ec49db442b68ff9amah if (Thread.interrupted()) throw new InterruptedException(); 20164c64e7c25e6efe31fa53369ec49db442b68ff9amah String name = scrubName(contact.mName); 20264c64e7c25e6efe31fa53369ec49db442b68ff9amah if (name.length() == 0 || !entries.add(name)) continue; 20364c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.setLength(0); 20485a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa // The number of ids appended here must be same as PHONE_ID_COUNT. 20564c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append("V='"); 20664c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(contact.mContactId).append(' '); 20764c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(contact.mPrimaryId).append(' '); 20864c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(contact.mHomeId).append(' '); 20964c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(contact.mMobileId).append(' '); 21064c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(contact.mWorkId).append(' '); 21185a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa sb.append(contact.mOtherId).append(' '); 21285a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa sb.append(contact.mFallbackId); 21364c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append("'"); 21464c64e7c25e6efe31fa53369ec49db442b68ff9amah try { 21564c64e7c25e6efe31fa53369ec49db442b68ff9amah mSrecGrammar.addWordToSlot("@Names", name, null, 1, sb.toString()); 21664c64e7c25e6efe31fa53369ec49db442b68ff9amah } catch (Exception e) { 21764c64e7c25e6efe31fa53369ec49db442b68ff9amah Log.e(TAG, "Cannot load all contacts to voice recognizer, loaded " + 21864c64e7c25e6efe31fa53369ec49db442b68ff9amah count, e); 21964c64e7c25e6efe31fa53369ec49db442b68ff9amah break; 22064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 22164c64e7c25e6efe31fa53369ec49db442b68ff9amah 22264c64e7c25e6efe31fa53369ec49db442b68ff9amah count++; 22364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 22464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 22564c64e7c25e6efe31fa53369ec49db442b68ff9amah 22664c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 22764c64e7c25e6efe31fa53369ec49db442b68ff9amah * add a list of application labels to the 'open x' grammar 22864c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 2294a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon private void loadOpenEntriesTable() throws InterruptedException, IOException { 230d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "addOpenEntriesToGrammar"); 23164c64e7c25e6efe31fa53369ec49db442b68ff9amah 23264c64e7c25e6efe31fa53369ec49db442b68ff9amah // fill this 23364c64e7c25e6efe31fa53369ec49db442b68ff9amah File oe = mActivity.getFileStreamPath(OPEN_ENTRIES); 23464c64e7c25e6efe31fa53369ec49db442b68ff9amah 23564c64e7c25e6efe31fa53369ec49db442b68ff9amah // build and write list of entries 23664c64e7c25e6efe31fa53369ec49db442b68ff9amah if (!oe.exists()) { 2374a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mOpenEntries = new HashMap<String, String>(); 23864c64e7c25e6efe31fa53369ec49db442b68ff9amah 23964c64e7c25e6efe31fa53369ec49db442b68ff9amah // build a list of 'open' entries 24064c64e7c25e6efe31fa53369ec49db442b68ff9amah PackageManager pm = mActivity.getPackageManager(); 24164c64e7c25e6efe31fa53369ec49db442b68ff9amah List<ResolveInfo> riList = pm.queryIntentActivities( 24264c64e7c25e6efe31fa53369ec49db442b68ff9amah new Intent(Intent.ACTION_MAIN). 24364c64e7c25e6efe31fa53369ec49db442b68ff9amah addCategory("android.intent.category.VOICE_LAUNCH"), 24464c64e7c25e6efe31fa53369ec49db442b68ff9amah PackageManager.GET_ACTIVITIES); 24564c64e7c25e6efe31fa53369ec49db442b68ff9amah if (Thread.interrupted()) throw new InterruptedException(); 24664c64e7c25e6efe31fa53369ec49db442b68ff9amah riList.addAll(pm.queryIntentActivities( 24764c64e7c25e6efe31fa53369ec49db442b68ff9amah new Intent(Intent.ACTION_MAIN). 24864c64e7c25e6efe31fa53369ec49db442b68ff9amah addCategory("android.intent.category.LAUNCHER"), 24964c64e7c25e6efe31fa53369ec49db442b68ff9amah PackageManager.GET_ACTIVITIES)); 25064c64e7c25e6efe31fa53369ec49db442b68ff9amah String voiceDialerClassName = mActivity.getComponentName().getClassName(); 25164c64e7c25e6efe31fa53369ec49db442b68ff9amah 25264c64e7c25e6efe31fa53369ec49db442b68ff9amah // scan list, adding complete phrases, as well as individual words 25364c64e7c25e6efe31fa53369ec49db442b68ff9amah for (ResolveInfo ri : riList) { 25464c64e7c25e6efe31fa53369ec49db442b68ff9amah if (Thread.interrupted()) throw new InterruptedException(); 25564c64e7c25e6efe31fa53369ec49db442b68ff9amah 25664c64e7c25e6efe31fa53369ec49db442b68ff9amah // skip self 25764c64e7c25e6efe31fa53369ec49db442b68ff9amah if (voiceDialerClassName.equals(ri.activityInfo.name)) continue; 25864c64e7c25e6efe31fa53369ec49db442b68ff9amah 25964c64e7c25e6efe31fa53369ec49db442b68ff9amah // fetch a scrubbed window label 26064c64e7c25e6efe31fa53369ec49db442b68ff9amah String label = scrubName(ri.loadLabel(pm).toString()); 26164c64e7c25e6efe31fa53369ec49db442b68ff9amah if (label.length() == 0) continue; 26264c64e7c25e6efe31fa53369ec49db442b68ff9amah 26364c64e7c25e6efe31fa53369ec49db442b68ff9amah // insert it into the result list 2644a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon addClassName(mOpenEntries, label, 26527d520022f552e3e4b17b00d6ec4db9306fe7deaMartin Hibdon ri.activityInfo.packageName, ri.activityInfo.name); 26664c64e7c25e6efe31fa53369ec49db442b68ff9amah 26764c64e7c25e6efe31fa53369ec49db442b68ff9amah // split it into individual words, and insert them 26864c64e7c25e6efe31fa53369ec49db442b68ff9amah String[] words = label.split(" "); 26964c64e7c25e6efe31fa53369ec49db442b68ff9amah if (words.length > 1) { 27064c64e7c25e6efe31fa53369ec49db442b68ff9amah for (String word : words) { 27164c64e7c25e6efe31fa53369ec49db442b68ff9amah word = word.trim(); 27264c64e7c25e6efe31fa53369ec49db442b68ff9amah // words must be three characters long, or two if capitalized 27364c64e7c25e6efe31fa53369ec49db442b68ff9amah int len = word.length(); 27464c64e7c25e6efe31fa53369ec49db442b68ff9amah if (len <= 1) continue; 27564c64e7c25e6efe31fa53369ec49db442b68ff9amah if (len == 2 && !(Character.isUpperCase(word.charAt(0)) && 27664c64e7c25e6efe31fa53369ec49db442b68ff9amah Character.isUpperCase(word.charAt(1)))) continue; 27764c64e7c25e6efe31fa53369ec49db442b68ff9amah if ("and".equalsIgnoreCase(word) || 27864c64e7c25e6efe31fa53369ec49db442b68ff9amah "the".equalsIgnoreCase(word)) continue; 27964c64e7c25e6efe31fa53369ec49db442b68ff9amah // add the word 2804a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon addClassName(mOpenEntries, word, 28127d520022f552e3e4b17b00d6ec4db9306fe7deaMartin Hibdon ri.activityInfo.packageName, ri.activityInfo.name); 28264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 28364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 28464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 28564c64e7c25e6efe31fa53369ec49db442b68ff9amah 28664c64e7c25e6efe31fa53369ec49db442b68ff9amah // write list 287d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "addOpenEntriesToGrammar writing " + oe); 28864c64e7c25e6efe31fa53369ec49db442b68ff9amah try { 28964c64e7c25e6efe31fa53369ec49db442b68ff9amah FileOutputStream fos = new FileOutputStream(oe); 29064c64e7c25e6efe31fa53369ec49db442b68ff9amah try { 29164c64e7c25e6efe31fa53369ec49db442b68ff9amah ObjectOutputStream oos = new ObjectOutputStream(fos); 2924a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon oos.writeObject(mOpenEntries); 29364c64e7c25e6efe31fa53369ec49db442b68ff9amah oos.close(); 29464c64e7c25e6efe31fa53369ec49db442b68ff9amah } finally { 29564c64e7c25e6efe31fa53369ec49db442b68ff9amah fos.close(); 29664c64e7c25e6efe31fa53369ec49db442b68ff9amah } 29764c64e7c25e6efe31fa53369ec49db442b68ff9amah } catch (IOException ioe) { 29864c64e7c25e6efe31fa53369ec49db442b68ff9amah deleteCachedGrammarFiles(mActivity); 29964c64e7c25e6efe31fa53369ec49db442b68ff9amah throw ioe; 30064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 30164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 30264c64e7c25e6efe31fa53369ec49db442b68ff9amah 30364c64e7c25e6efe31fa53369ec49db442b68ff9amah // read the list 30464c64e7c25e6efe31fa53369ec49db442b68ff9amah else { 305d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "addOpenEntriesToGrammar reading " + oe); 30664c64e7c25e6efe31fa53369ec49db442b68ff9amah try { 30764c64e7c25e6efe31fa53369ec49db442b68ff9amah FileInputStream fis = new FileInputStream(oe); 30864c64e7c25e6efe31fa53369ec49db442b68ff9amah try { 30964c64e7c25e6efe31fa53369ec49db442b68ff9amah ObjectInputStream ois = new ObjectInputStream(fis); 3104a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mOpenEntries = (HashMap<String, String>)ois.readObject(); 31164c64e7c25e6efe31fa53369ec49db442b68ff9amah ois.close(); 31264c64e7c25e6efe31fa53369ec49db442b68ff9amah } finally { 31364c64e7c25e6efe31fa53369ec49db442b68ff9amah fis.close(); 31464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 31564c64e7c25e6efe31fa53369ec49db442b68ff9amah } catch (Exception e) { 31664c64e7c25e6efe31fa53369ec49db442b68ff9amah deleteCachedGrammarFiles(mActivity); 31764c64e7c25e6efe31fa53369ec49db442b68ff9amah throw new IOException(e.toString()); 31864c64e7c25e6efe31fa53369ec49db442b68ff9amah } 31964c64e7c25e6efe31fa53369ec49db442b68ff9amah } 3204a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon } 3214a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon 3224a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon private void addOpenEntriesToGrammar() throws InterruptedException, IOException { 3234a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // load up our open entries table 3244a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon loadOpenEntriesTable(); 32564c64e7c25e6efe31fa53369ec49db442b68ff9amah 32664c64e7c25e6efe31fa53369ec49db442b68ff9amah // add list of 'open' entries to the grammar 3274a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon for (String label : mOpenEntries.keySet()) { 32864c64e7c25e6efe31fa53369ec49db442b68ff9amah if (Thread.interrupted()) throw new InterruptedException(); 3294a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String entry = mOpenEntries.get(label); 33064c64e7c25e6efe31fa53369ec49db442b68ff9amah // don't add if too many results 33164c64e7c25e6efe31fa53369ec49db442b68ff9amah int count = 0; 33264c64e7c25e6efe31fa53369ec49db442b68ff9amah for (int i = 0; 0 != (i = entry.indexOf(' ', i) + 1); count++) ; 33364c64e7c25e6efe31fa53369ec49db442b68ff9amah if (count > RESULT_LIMIT) continue; 33464c64e7c25e6efe31fa53369ec49db442b68ff9amah // add the word to the grammar 3354a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // See Bug: 2457238. 3364a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // We used to store the entire list of components into the grammar. 3374a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // Unfortuantely, the recognizer has a fixed limit on the length of 3384a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // the "semantic" string, which is easy to overflow. So now, 3394a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // the we store our own mapping table between words and component 3404a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // names, and the entries in the grammar have the same value 3414a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // for literal and semantic. 3424a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon mSrecGrammar.addWordToSlot("@Opens", label, null, 1, "V='" + label + "'"); 34364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 34464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 34564c64e7c25e6efe31fa53369ec49db442b68ff9amah 34664c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 34764c64e7c25e6efe31fa53369ec49db442b68ff9amah * Add a className to a hash table of class name lists. 34864c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param openEntries HashMap of lists of class names. 34964c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param label a label or word corresponding to the list of classes. 35064c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param className class name to add 35164c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 35264c64e7c25e6efe31fa53369ec49db442b68ff9amah private static void addClassName(HashMap<String,String> openEntries, 35327d520022f552e3e4b17b00d6ec4db9306fe7deaMartin Hibdon String label, String packageName, String className) { 3544a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String component = packageName + "/" + className; 35564c64e7c25e6efe31fa53369ec49db442b68ff9amah String labelLowerCase = label.toLowerCase(); 35664c64e7c25e6efe31fa53369ec49db442b68ff9amah String classList = openEntries.get(labelLowerCase); 35764c64e7c25e6efe31fa53369ec49db442b68ff9amah 35864c64e7c25e6efe31fa53369ec49db442b68ff9amah // first item in the list 35964c64e7c25e6efe31fa53369ec49db442b68ff9amah if (classList == null) { 3604a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon openEntries.put(labelLowerCase, component); 36164c64e7c25e6efe31fa53369ec49db442b68ff9amah return; 36264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 36364c64e7c25e6efe31fa53369ec49db442b68ff9amah // already in list 3644a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon int index = classList.indexOf(component); 3654a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon int after = index + component.length(); 36664c64e7c25e6efe31fa53369ec49db442b68ff9amah if (index != -1 && (index == 0 || classList.charAt(index - 1) == ' ') && 36764c64e7c25e6efe31fa53369ec49db442b68ff9amah (after == classList.length() || classList.charAt(after) == ' ')) return; 36864c64e7c25e6efe31fa53369ec49db442b68ff9amah 36964c64e7c25e6efe31fa53369ec49db442b68ff9amah // add it to the end 3704a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon openEntries.put(labelLowerCase, classList + ' ' + component); 37164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 37264c64e7c25e6efe31fa53369ec49db442b68ff9amah 37364c64e7c25e6efe31fa53369ec49db442b68ff9amah // map letters in Latin1 Supplement to basic ascii 37464c64e7c25e6efe31fa53369ec49db442b68ff9amah // from http://en.wikipedia.org/wiki/Latin-1_Supplement_unicode_block 37564c64e7c25e6efe31fa53369ec49db442b68ff9amah // not all letters map well, including Eth and Thorn 37664c64e7c25e6efe31fa53369ec49db442b68ff9amah // TODO: this should really be all handled in the pronunciation engine 37764c64e7c25e6efe31fa53369ec49db442b68ff9amah private final static char[] mLatin1Letters = 37864c64e7c25e6efe31fa53369ec49db442b68ff9amah "AAAAAAACEEEEIIIIDNOOOOO OUUUUYDsaaaaaaaceeeeiiiidnooooo ouuuuydy". 37964c64e7c25e6efe31fa53369ec49db442b68ff9amah toCharArray(); 38064c64e7c25e6efe31fa53369ec49db442b68ff9amah private final static int mLatin1Base = 0x00c0; 38164c64e7c25e6efe31fa53369ec49db442b68ff9amah 38264c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 38364c64e7c25e6efe31fa53369ec49db442b68ff9amah * Reformat a raw name from the contact list into a form a 38464c64e7c25e6efe31fa53369ec49db442b68ff9amah * {@link Recognizer.Grammar} can digest. 38564c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param name the raw name. 38664c64e7c25e6efe31fa53369ec49db442b68ff9amah * @return the reformatted name. 38764c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 38864c64e7c25e6efe31fa53369ec49db442b68ff9amah private static String scrubName(String name) { 38964c64e7c25e6efe31fa53369ec49db442b68ff9amah // replace '&' with ' and ' 39064c64e7c25e6efe31fa53369ec49db442b68ff9amah name = name.replace("&", " and "); 39164c64e7c25e6efe31fa53369ec49db442b68ff9amah 39264c64e7c25e6efe31fa53369ec49db442b68ff9amah // replace '@' with ' at ' 39364c64e7c25e6efe31fa53369ec49db442b68ff9amah name = name.replace("@", " at "); 39464c64e7c25e6efe31fa53369ec49db442b68ff9amah 39564c64e7c25e6efe31fa53369ec49db442b68ff9amah // remove '(...)' 39664c64e7c25e6efe31fa53369ec49db442b68ff9amah while (true) { 39764c64e7c25e6efe31fa53369ec49db442b68ff9amah int i = name.indexOf('('); 39864c64e7c25e6efe31fa53369ec49db442b68ff9amah if (i == -1) break; 39964c64e7c25e6efe31fa53369ec49db442b68ff9amah int j = name.indexOf(')', i); 40064c64e7c25e6efe31fa53369ec49db442b68ff9amah if (j == -1) break; 40164c64e7c25e6efe31fa53369ec49db442b68ff9amah name = name.substring(0, i) + " " + name.substring(j + 1); 40264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 40364c64e7c25e6efe31fa53369ec49db442b68ff9amah 40464c64e7c25e6efe31fa53369ec49db442b68ff9amah // map letters of Latin1 Supplement to basic ascii 40564c64e7c25e6efe31fa53369ec49db442b68ff9amah char[] nm = null; 40664c64e7c25e6efe31fa53369ec49db442b68ff9amah for (int i = name.length() - 1; i >= 0; i--) { 40764c64e7c25e6efe31fa53369ec49db442b68ff9amah char ch = name.charAt(i); 40864c64e7c25e6efe31fa53369ec49db442b68ff9amah if (ch < ' ' || '~' < ch) { 40964c64e7c25e6efe31fa53369ec49db442b68ff9amah if (nm == null) nm = name.toCharArray(); 41064c64e7c25e6efe31fa53369ec49db442b68ff9amah nm[i] = mLatin1Base <= ch && ch < mLatin1Base + mLatin1Letters.length ? 41164c64e7c25e6efe31fa53369ec49db442b68ff9amah mLatin1Letters[ch - mLatin1Base] : ' '; 41264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 41364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 41464c64e7c25e6efe31fa53369ec49db442b68ff9amah if (nm != null) { 41564c64e7c25e6efe31fa53369ec49db442b68ff9amah name = new String(nm); 41664c64e7c25e6efe31fa53369ec49db442b68ff9amah } 41764c64e7c25e6efe31fa53369ec49db442b68ff9amah 41864c64e7c25e6efe31fa53369ec49db442b68ff9amah // if '.' followed by alnum, replace with ' dot ' 41964c64e7c25e6efe31fa53369ec49db442b68ff9amah while (true) { 42064c64e7c25e6efe31fa53369ec49db442b68ff9amah int i = name.indexOf('.'); 42164c64e7c25e6efe31fa53369ec49db442b68ff9amah if (i == -1 || 42264c64e7c25e6efe31fa53369ec49db442b68ff9amah i + 1 >= name.length() || 42364c64e7c25e6efe31fa53369ec49db442b68ff9amah !Character.isLetterOrDigit(name.charAt(i + 1))) break; 42464c64e7c25e6efe31fa53369ec49db442b68ff9amah name = name.substring(0, i) + " dot " + name.substring(i + 1); 42564c64e7c25e6efe31fa53369ec49db442b68ff9amah } 42664c64e7c25e6efe31fa53369ec49db442b68ff9amah 42764c64e7c25e6efe31fa53369ec49db442b68ff9amah // trim 42864c64e7c25e6efe31fa53369ec49db442b68ff9amah name = name.trim(); 42964c64e7c25e6efe31fa53369ec49db442b68ff9amah 43064c64e7c25e6efe31fa53369ec49db442b68ff9amah // ensure at least one alphanumeric character, or the pron engine will fail 43164c64e7c25e6efe31fa53369ec49db442b68ff9amah for (int i = name.length() - 1; true; i--) { 43264c64e7c25e6efe31fa53369ec49db442b68ff9amah if (i < 0) return ""; 43364c64e7c25e6efe31fa53369ec49db442b68ff9amah char ch = name.charAt(i); 43464c64e7c25e6efe31fa53369ec49db442b68ff9amah if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || ('0' <= ch && ch <= '9')) { 43564c64e7c25e6efe31fa53369ec49db442b68ff9amah break; 43664c64e7c25e6efe31fa53369ec49db442b68ff9amah } 43764c64e7c25e6efe31fa53369ec49db442b68ff9amah } 43864c64e7c25e6efe31fa53369ec49db442b68ff9amah 43964c64e7c25e6efe31fa53369ec49db442b68ff9amah return name; 44064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 44164c64e7c25e6efe31fa53369ec49db442b68ff9amah 44264c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 44364c64e7c25e6efe31fa53369ec49db442b68ff9amah * Delete all g2g files in the directory indicated by {@link File}, 44464c64e7c25e6efe31fa53369ec49db442b68ff9amah * which is typically /data/data/com.android.voicedialer/files. 44564c64e7c25e6efe31fa53369ec49db442b68ff9amah * There should only be one g2g file at any one time, with a hashcode 44664c64e7c25e6efe31fa53369ec49db442b68ff9amah * embedded in it's name, but if stale ones are present, this will delete 44764c64e7c25e6efe31fa53369ec49db442b68ff9amah * them all. 44864c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param context fetch directory for the stuffed and compiled g2g file. 44964c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 45064c64e7c25e6efe31fa53369ec49db442b68ff9amah private static void deleteAllG2GFiles(Context context) { 45164c64e7c25e6efe31fa53369ec49db442b68ff9amah FileFilter ff = new FileFilter() { 45264c64e7c25e6efe31fa53369ec49db442b68ff9amah public boolean accept(File f) { 45364c64e7c25e6efe31fa53369ec49db442b68ff9amah String name = f.getName(); 45464c64e7c25e6efe31fa53369ec49db442b68ff9amah return name.endsWith(".g2g"); 45564c64e7c25e6efe31fa53369ec49db442b68ff9amah } 45664c64e7c25e6efe31fa53369ec49db442b68ff9amah }; 45764c64e7c25e6efe31fa53369ec49db442b68ff9amah File[] files = context.getFilesDir().listFiles(ff); 45864c64e7c25e6efe31fa53369ec49db442b68ff9amah if (files != null) { 45964c64e7c25e6efe31fa53369ec49db442b68ff9amah for (File file : files) { 460d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "deleteAllG2GFiles " + file); 46164c64e7c25e6efe31fa53369ec49db442b68ff9amah file.delete(); 46264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 46364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 46464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 46564c64e7c25e6efe31fa53369ec49db442b68ff9amah 46664c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 46764c64e7c25e6efe31fa53369ec49db442b68ff9amah * Delete G2G and OpenEntries files, to force regeneration of the g2g file 46864c64e7c25e6efe31fa53369ec49db442b68ff9amah * from scratch. 46964c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param context fetch directory for file. 47064c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 47164c64e7c25e6efe31fa53369ec49db442b68ff9amah public static void deleteCachedGrammarFiles(Context context) { 47264c64e7c25e6efe31fa53369ec49db442b68ff9amah deleteAllG2GFiles(context); 47364c64e7c25e6efe31fa53369ec49db442b68ff9amah File oe = context.getFileStreamPath(OPEN_ENTRIES); 474d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.v(TAG, "deleteCachedGrammarFiles " + oe); 47564c64e7c25e6efe31fa53369ec49db442b68ff9amah if (oe.exists()) oe.delete(); 47664c64e7c25e6efe31fa53369ec49db442b68ff9amah } 47764c64e7c25e6efe31fa53369ec49db442b68ff9amah 47864c64e7c25e6efe31fa53369ec49db442b68ff9amah // NANP number formats 47964c64e7c25e6efe31fa53369ec49db442b68ff9amah private final static String mNanpFormats = 48064c64e7c25e6efe31fa53369ec49db442b68ff9amah "xxx xxx xxxx\n" + 48164c64e7c25e6efe31fa53369ec49db442b68ff9amah "xxx xxxx\n" + 48264c64e7c25e6efe31fa53369ec49db442b68ff9amah "x11\n"; 48364c64e7c25e6efe31fa53369ec49db442b68ff9amah 48464c64e7c25e6efe31fa53369ec49db442b68ff9amah // a list of country codes 48564c64e7c25e6efe31fa53369ec49db442b68ff9amah private final static String mPlusFormats = 48664c64e7c25e6efe31fa53369ec49db442b68ff9amah 48764c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 48864c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 1: nanp (north american numbering plan), us, canada, caribbean 48964c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 49064c64e7c25e6efe31fa53369ec49db442b68ff9amah 49164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+1 xxx xxx xxxx\n" + // nanp 49264c64e7c25e6efe31fa53369ec49db442b68ff9amah 49364c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 49464c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 2: africa, some atlantic and indian ocean islands 49564c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 49664c64e7c25e6efe31fa53369ec49db442b68ff9amah 49764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+20 x xxx xxxx\n" + // Egypt 49864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+20 1x xxx xxxx\n" + // Egypt 49964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+20 xx xxx xxxx\n" + // Egypt 50064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+20 xxx xxx xxxx\n" + // Egypt 50164c64e7c25e6efe31fa53369ec49db442b68ff9amah 50264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+212 xxxx xxxx\n" + // Morocco 50364c64e7c25e6efe31fa53369ec49db442b68ff9amah 50464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+213 xx xx xx xx\n" + // Algeria 50564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+213 xx xxx xxxx\n" + // Algeria 50664c64e7c25e6efe31fa53369ec49db442b68ff9amah 50764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+216 xx xxx xxx\n" + // Tunisia 50864c64e7c25e6efe31fa53369ec49db442b68ff9amah 50964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+218 xx xxx xxx\n" + // Libya 51064c64e7c25e6efe31fa53369ec49db442b68ff9amah 51164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+22x \n" + 51264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+23x \n" + 51364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+24x \n" + 51464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+25x \n" + 51564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+26x \n" + 51664c64e7c25e6efe31fa53369ec49db442b68ff9amah 51764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+27 xx xxx xxxx\n" + // South africa 51864c64e7c25e6efe31fa53369ec49db442b68ff9amah 51964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+290 x xxx\n" + // Saint Helena, Tristan da Cunha 52064c64e7c25e6efe31fa53369ec49db442b68ff9amah 52164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+291 x xxx xxx\n" + // Eritrea 52264c64e7c25e6efe31fa53369ec49db442b68ff9amah 52364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+297 xxx xxxx\n" + // Aruba 52464c64e7c25e6efe31fa53369ec49db442b68ff9amah 52564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+298 xxx xxx\n" + // Faroe Islands 52664c64e7c25e6efe31fa53369ec49db442b68ff9amah 52764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+299 xxx xxx\n" + // Greenland 52864c64e7c25e6efe31fa53369ec49db442b68ff9amah 52964c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 53064c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 3: europe, southern and small countries 53164c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 53264c64e7c25e6efe31fa53369ec49db442b68ff9amah 53364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+30 xxx xxx xxxx\n" + // Greece 53464c64e7c25e6efe31fa53369ec49db442b68ff9amah 53564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+31 6 xxxx xxxx\n" + // Netherlands 53664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+31 xx xxx xxxx\n" + // Netherlands 53764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+31 xxx xx xxxx\n" + // Netherlands 53864c64e7c25e6efe31fa53369ec49db442b68ff9amah 53964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+32 2 xxx xx xx\n" + // Belgium 54064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+32 3 xxx xx xx\n" + // Belgium 54164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+32 4xx xx xx xx\n" + // Belgium 54264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+32 9 xxx xx xx\n" + // Belgium 54364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+32 xx xx xx xx\n" + // Belgium 54464c64e7c25e6efe31fa53369ec49db442b68ff9amah 54564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+33 xxx xxx xxx\n" + // France 54664c64e7c25e6efe31fa53369ec49db442b68ff9amah 54764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+34 xxx xxx xxx\n" + // Spain 54864c64e7c25e6efe31fa53369ec49db442b68ff9amah 54964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+351 3xx xxx xxx\n" + // Portugal 55064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+351 7xx xxx xxx\n" + // Portugal 55164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+351 8xx xxx xxx\n" + // Portugal 55264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+351 xx xxx xxxx\n" + // Portugal 55364c64e7c25e6efe31fa53369ec49db442b68ff9amah 55464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+352 xx xxxx\n" + // Luxembourg 55564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+352 6x1 xxx xxx\n" + // Luxembourg 55664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+352 \n" + // Luxembourg 55764c64e7c25e6efe31fa53369ec49db442b68ff9amah 55864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+353 xxx xxxx\n" + // Ireland 55964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+353 xxxx xxxx\n" + // Ireland 56064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+353 xx xxx xxxx\n" + // Ireland 56164c64e7c25e6efe31fa53369ec49db442b68ff9amah 56264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+354 3xx xxx xxx\n" + // Iceland 56364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+354 xxx xxxx\n" + // Iceland 56464c64e7c25e6efe31fa53369ec49db442b68ff9amah 56564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+355 6x xxx xxxx\n" + // Albania 56664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+355 xxx xxxx\n" + // Albania 56764c64e7c25e6efe31fa53369ec49db442b68ff9amah 56864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+356 xx xx xx xx\n" + // Malta 56964c64e7c25e6efe31fa53369ec49db442b68ff9amah 57064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+357 xx xx xx xx\n" + // Cyprus 57164c64e7c25e6efe31fa53369ec49db442b68ff9amah 57264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+358 \n" + // Finland 57364c64e7c25e6efe31fa53369ec49db442b68ff9amah 57464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+359 \n" + // Bulgaria 57564c64e7c25e6efe31fa53369ec49db442b68ff9amah 57664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 1 xxx xxxx\n" + // Hungary 57764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 20 xxx xxxx\n" + // Hungary 57864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 21 xxx xxxx\n" + // Hungary 57964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 30 xxx xxxx\n" + // Hungary 58064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 70 xxx xxxx\n" + // Hungary 58164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 71 xxx xxxx\n" + // Hungary 58264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+36 xx xxx xxx\n" + // Hungary 58364c64e7c25e6efe31fa53369ec49db442b68ff9amah 58464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+370 6x xxx xxx\n" + // Lithuania 58564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+370 xxx xx xxx\n" + // Lithuania 58664c64e7c25e6efe31fa53369ec49db442b68ff9amah 58764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+371 xxxx xxxx\n" + // Latvia 58864c64e7c25e6efe31fa53369ec49db442b68ff9amah 58964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+372 5 xxx xxxx\n" + // Estonia 59064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+372 xxx xxxx\n" + // Estonia 59164c64e7c25e6efe31fa53369ec49db442b68ff9amah 59264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+373 6xx xx xxx\n" + // Moldova 59364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+373 7xx xx xxx\n" + // Moldova 59464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+373 xxx xxxxx\n" + // Moldova 59564c64e7c25e6efe31fa53369ec49db442b68ff9amah 59664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+374 xx xxx xxx\n" + // Armenia 59764c64e7c25e6efe31fa53369ec49db442b68ff9amah 59864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+375 xx xxx xxxx\n" + // Belarus 59964c64e7c25e6efe31fa53369ec49db442b68ff9amah 60064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+376 xx xx xx\n" + // Andorra 60164c64e7c25e6efe31fa53369ec49db442b68ff9amah 60264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+377 xxxx xxxx\n" + // Monaco 60364c64e7c25e6efe31fa53369ec49db442b68ff9amah 60464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+378 xxx xxx xxxx\n" + // San Marino 60564c64e7c25e6efe31fa53369ec49db442b68ff9amah 60664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+380 xxx xx xx xx\n" + // Ukraine 60764c64e7c25e6efe31fa53369ec49db442b68ff9amah 60864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+381 xx xxx xxxx\n" + // Serbia 60964c64e7c25e6efe31fa53369ec49db442b68ff9amah 61064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+382 xx xxx xxxx\n" + // Montenegro 61164c64e7c25e6efe31fa53369ec49db442b68ff9amah 61264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+385 xx xxx xxxx\n" + // Croatia 61364c64e7c25e6efe31fa53369ec49db442b68ff9amah 61464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+386 x xxx xxxx\n" + // Slovenia 61564c64e7c25e6efe31fa53369ec49db442b68ff9amah 61664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+387 xx xx xx xx\n" + // Bosnia and herzegovina 61764c64e7c25e6efe31fa53369ec49db442b68ff9amah 61864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+389 2 xxx xx xx\n" + // Macedonia 61964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+389 xx xx xx xx\n" + // Macedonia 62064c64e7c25e6efe31fa53369ec49db442b68ff9amah 62164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+39 xxx xxx xxx\n" + // Italy 62264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+39 3xx xxx xxxx\n" + // Italy 62364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+39 xx xxxx xxxx\n" + // Italy 62464c64e7c25e6efe31fa53369ec49db442b68ff9amah 62564c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 62664c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 4: europe, northern countries 62764c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 62864c64e7c25e6efe31fa53369ec49db442b68ff9amah 62964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+40 xxx xxx xxx\n" + // Romania 63064c64e7c25e6efe31fa53369ec49db442b68ff9amah 63164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+41 xx xxx xx xx\n" + // Switzerland 63264c64e7c25e6efe31fa53369ec49db442b68ff9amah 63364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+420 xxx xxx xxx\n" + // Czech republic 63464c64e7c25e6efe31fa53369ec49db442b68ff9amah 63564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+421 xxx xxx xxx\n" + // Slovakia 63664c64e7c25e6efe31fa53369ec49db442b68ff9amah 63764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+421 xxx xxx xxxx\n" + // Liechtenstein 63864c64e7c25e6efe31fa53369ec49db442b68ff9amah 63964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+43 \n" + // Austria 64064c64e7c25e6efe31fa53369ec49db442b68ff9amah 64164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+44 xxx xxx xxxx\n" + // UK 64264c64e7c25e6efe31fa53369ec49db442b68ff9amah 64364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+45 xx xx xx xx\n" + // Denmark 64464c64e7c25e6efe31fa53369ec49db442b68ff9amah 64564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+46 \n" + // Sweden 64664c64e7c25e6efe31fa53369ec49db442b68ff9amah 64764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+47 xxxx xxxx\n" + // Norway 64864c64e7c25e6efe31fa53369ec49db442b68ff9amah 64964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+48 xx xxx xxxx\n" + // Poland 65064c64e7c25e6efe31fa53369ec49db442b68ff9amah 65164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+49 1xx xxxx xxx\n" + // Germany 65264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+49 1xx xxxx xxxx\n" + // Germany 65364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+49 \n" + // Germany 65464c64e7c25e6efe31fa53369ec49db442b68ff9amah 65564c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 65664c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 5: latin america 65764c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 65864c64e7c25e6efe31fa53369ec49db442b68ff9amah 65964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+50x \n" + 66064c64e7c25e6efe31fa53369ec49db442b68ff9amah 66164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+51 9xx xxx xxx\n" + // Peru 66264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+51 1 xxx xxxx\n" + // Peru 66364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+51 xx xx xxxx\n" + // Peru 66464c64e7c25e6efe31fa53369ec49db442b68ff9amah 66564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+52 1 xxx xxx xxxx\n" + // Mexico 66664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+52 xxx xxx xxxx\n" + // Mexico 66764c64e7c25e6efe31fa53369ec49db442b68ff9amah 66864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+53 xxxx xxxx\n" + // Cuba 66964c64e7c25e6efe31fa53369ec49db442b68ff9amah 67064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+54 9 11 xxxx xxxx\n" + // Argentina 67164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+54 9 xxx xxx xxxx\n" + // Argentina 67264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+54 11 xxxx xxxx\n" + // Argentina 67364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+54 xxx xxx xxxx\n" + // Argentina 67464c64e7c25e6efe31fa53369ec49db442b68ff9amah 67564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+55 xx xxxx xxxx\n" + // Brazil 67664c64e7c25e6efe31fa53369ec49db442b68ff9amah 67764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+56 2 xxxxxx\n" + // Chile 67864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+56 9 xxxx xxxx\n" + // Chile 67964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+56 xx xxxxxx\n" + // Chile 68064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+56 xx xxxxxxx\n" + // Chile 68164c64e7c25e6efe31fa53369ec49db442b68ff9amah 68264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+57 x xxx xxxx\n" + // Columbia 68364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+57 3xx xxx xxxx\n" + // Columbia 68464c64e7c25e6efe31fa53369ec49db442b68ff9amah 68564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+58 xxx xxx xxxx\n" + // Venezuela 68664c64e7c25e6efe31fa53369ec49db442b68ff9amah 68764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+59x \n" + 68864c64e7c25e6efe31fa53369ec49db442b68ff9amah 68964c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 69064c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 6: southeast asia and oceania 69164c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 69264c64e7c25e6efe31fa53369ec49db442b68ff9amah 69364c64e7c25e6efe31fa53369ec49db442b68ff9amah // TODO is this right? 69464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 3 xxxx xxxx\n" + // Malaysia 69564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 8x xxxxxx\n" + // Malaysia 69664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 x xxx xxxx\n" + // Malaysia 69764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 14 x xxx xxxx\n" + // Malaysia 69864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 1x xxx xxxx\n" + // Malaysia 69964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 x xxxx xxxx\n" + // Malaysia 70064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+60 \n" + // Malaysia 70164c64e7c25e6efe31fa53369ec49db442b68ff9amah 70264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+61 4xx xxx xxx\n" + // Australia 70364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+61 x xxxx xxxx\n" + // Australia 70464c64e7c25e6efe31fa53369ec49db442b68ff9amah 70564c64e7c25e6efe31fa53369ec49db442b68ff9amah // TODO: is this right? 70664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+62 8xx xxxx xxxx\n" + // Indonesia 70764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+62 21 xxxxx\n" + // Indonesia 70864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+62 xx xxxxxx\n" + // Indonesia 70964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+62 xx xxx xxxx\n" + // Indonesia 71064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+62 xx xxxx xxxx\n" + // Indonesia 71164c64e7c25e6efe31fa53369ec49db442b68ff9amah 71264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+63 2 xxx xxxx\n" + // Phillipines 71364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+63 xx xxx xxxx\n" + // Phillipines 71464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+63 9xx xxx xxxx\n" + // Phillipines 71564c64e7c25e6efe31fa53369ec49db442b68ff9amah 71664c64e7c25e6efe31fa53369ec49db442b68ff9amah // TODO: is this right? 71764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+64 2 xxx xxxx\n" + // New Zealand 71864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+64 2 xxx xxxx x\n" + // New Zealand 71964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+64 2 xxx xxxx xx\n" + // New Zealand 72064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+64 x xxx xxxx\n" + // New Zealand 72164c64e7c25e6efe31fa53369ec49db442b68ff9amah 72264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+65 xxxx xxxx\n" + // Singapore 72364c64e7c25e6efe31fa53369ec49db442b68ff9amah 72464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+66 8 xxxx xxxx\n" + // Thailand 72564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+66 2 xxx xxxx\n" + // Thailand 72664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+66 xx xx xxxx\n" + // Thailand 72764c64e7c25e6efe31fa53369ec49db442b68ff9amah 72864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+67x \n" + 72964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+68x \n" + 73064c64e7c25e6efe31fa53369ec49db442b68ff9amah 73164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+690 x xxx\n" + // Tokelau 73264c64e7c25e6efe31fa53369ec49db442b68ff9amah 73364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+691 xxx xxxx\n" + // Micronesia 73464c64e7c25e6efe31fa53369ec49db442b68ff9amah 73564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+692 xxx xxxx\n" + // marshall Islands 73664c64e7c25e6efe31fa53369ec49db442b68ff9amah 73764c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 73864c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 7: russia and kazakstan 73964c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 74064c64e7c25e6efe31fa53369ec49db442b68ff9amah 74164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+7 6xx xx xxxxx\n" + // Kazakstan 74264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+7 7xx 2 xxxxxx\n" + // Kazakstan 74364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+7 7xx xx xxxxx\n" + // Kazakstan 74464c64e7c25e6efe31fa53369ec49db442b68ff9amah 74564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+7 xxx xxx xx xx\n" + // Russia 74664c64e7c25e6efe31fa53369ec49db442b68ff9amah 74764c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 74864c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 8: east asia 74964c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 75064c64e7c25e6efe31fa53369ec49db442b68ff9amah 75164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+81 3 xxxx xxxx\n" + // Japan 75264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+81 6 xxxx xxxx\n" + // Japan 75364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+81 xx xxx xxxx\n" + // Japan 75464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+81 x0 xxxx xxxx\n" + // Japan 75564c64e7c25e6efe31fa53369ec49db442b68ff9amah 75664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+82 2 xxx xxxx\n" + // South korea 75764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+82 2 xxxx xxxx\n" + // South korea 75864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+82 xx xxxx xxxx\n" + // South korea 75964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+82 xx xxx xxxx\n" + // South korea 76064c64e7c25e6efe31fa53369ec49db442b68ff9amah 76164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+84 4 xxxx xxxx\n" + // Vietnam 76264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+84 xx xxxx xxx\n" + // Vietnam 76364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+84 xx xxxx xxxx\n" + // Vietnam 76464c64e7c25e6efe31fa53369ec49db442b68ff9amah 76564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+850 \n" + // North Korea 76664c64e7c25e6efe31fa53369ec49db442b68ff9amah 76764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+852 xxxx xxxx\n" + // Hong Kong 76864c64e7c25e6efe31fa53369ec49db442b68ff9amah 76964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+853 xxxx xxxx\n" + // Macau 77064c64e7c25e6efe31fa53369ec49db442b68ff9amah 77164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+855 1x xxx xxx\n" + // Cambodia 77264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+855 9x xxx xxx\n" + // Cambodia 77364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+855 xx xx xx xx\n" + // Cambodia 77464c64e7c25e6efe31fa53369ec49db442b68ff9amah 77564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+856 20 x xxx xxx\n" + // Laos 77664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+856 xx xxx xxx\n" + // Laos 77764c64e7c25e6efe31fa53369ec49db442b68ff9amah 77864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+852 xxxx xxxx\n" + // Hong kong 77964c64e7c25e6efe31fa53369ec49db442b68ff9amah 78064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+86 10 xxxx xxxx\n" + // China 78164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+86 2x xxxx xxxx\n" + // China 78264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+86 xxx xxx xxxx\n" + // China 78364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+86 xxx xxxx xxxx\n" + // China 78464c64e7c25e6efe31fa53369ec49db442b68ff9amah 78564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+880 xx xxxx xxxx\n" + // Bangladesh 78664c64e7c25e6efe31fa53369ec49db442b68ff9amah 78764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+886 \n" + // Taiwan 78864c64e7c25e6efe31fa53369ec49db442b68ff9amah 78964c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 79064c64e7c25e6efe31fa53369ec49db442b68ff9amah // zone 9: south asia, west asia, central asia, middle east 79164c64e7c25e6efe31fa53369ec49db442b68ff9amah //////////////////////////////////////////////////////////// 79264c64e7c25e6efe31fa53369ec49db442b68ff9amah 79364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+90 xxx xxx xxxx\n" + // Turkey 79464c64e7c25e6efe31fa53369ec49db442b68ff9amah 79564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+91 9x xx xxxxxx\n" + // India 79664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+91 xx xxxx xxxx\n" + // India 79764c64e7c25e6efe31fa53369ec49db442b68ff9amah 79864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+92 xx xxx xxxx\n" + // Pakistan 79964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+92 3xx xxx xxxx\n" + // Pakistan 80064c64e7c25e6efe31fa53369ec49db442b68ff9amah 80164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+93 70 xxx xxx\n" + // Afghanistan 80264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+93 xx xxx xxxx\n" + // Afghanistan 80364c64e7c25e6efe31fa53369ec49db442b68ff9amah 80464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+94 xx xxx xxxx\n" + // Sri Lanka 80564c64e7c25e6efe31fa53369ec49db442b68ff9amah 80664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+95 1 xxx xxx\n" + // Burma 80764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+95 2 xxx xxx\n" + // Burma 80864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+95 xx xxxxx\n" + // Burma 80964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+95 9 xxx xxxx\n" + // Burma 81064c64e7c25e6efe31fa53369ec49db442b68ff9amah 81164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+960 xxx xxxx\n" + // Maldives 81264c64e7c25e6efe31fa53369ec49db442b68ff9amah 81364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+961 x xxx xxx\n" + // Lebanon 81464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+961 xx xxx xxx\n" + // Lebanon 81564c64e7c25e6efe31fa53369ec49db442b68ff9amah 81664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+962 7 xxxx xxxx\n" + // Jordan 81764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+962 x xxx xxxx\n" + // Jordan 81864c64e7c25e6efe31fa53369ec49db442b68ff9amah 81964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+963 11 xxx xxxx\n" + // Syria 82064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+963 xx xxx xxx\n" + // Syria 82164c64e7c25e6efe31fa53369ec49db442b68ff9amah 82264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+964 \n" + // Iraq 82364c64e7c25e6efe31fa53369ec49db442b68ff9amah 82464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+965 xxxx xxxx\n" + // Kuwait 82564c64e7c25e6efe31fa53369ec49db442b68ff9amah 82664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+966 5x xxx xxxx\n" + // Saudi Arabia 82764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+966 x xxx xxxx\n" + // Saudi Arabia 82864c64e7c25e6efe31fa53369ec49db442b68ff9amah 82964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+967 7xx xxx xxx\n" + // Yemen 83064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+967 x xxx xxx\n" + // Yemen 83164c64e7c25e6efe31fa53369ec49db442b68ff9amah 83264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+968 xxxx xxxx\n" + // Oman 83364c64e7c25e6efe31fa53369ec49db442b68ff9amah 83464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+970 5x xxx xxxx\n" + // Palestinian Authority 83564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+970 x xxx xxxx\n" + // Palestinian Authority 83664c64e7c25e6efe31fa53369ec49db442b68ff9amah 83764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+971 5x xxx xxxx\n" + // United Arab Emirates 83864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+971 x xxx xxxx\n" + // United Arab Emirates 83964c64e7c25e6efe31fa53369ec49db442b68ff9amah 84064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+972 5x xxx xxxx\n" + // Israel 84164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+972 x xxx xxxx\n" + // Israel 84264c64e7c25e6efe31fa53369ec49db442b68ff9amah 84364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+973 xxxx xxxx\n" + // Bahrain 84464c64e7c25e6efe31fa53369ec49db442b68ff9amah 84564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+974 xxx xxxx\n" + // Qatar 84664c64e7c25e6efe31fa53369ec49db442b68ff9amah 84764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+975 1x xxx xxx\n" + // Bhutan 84864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+975 x xxx xxx\n" + // Bhutan 84964c64e7c25e6efe31fa53369ec49db442b68ff9amah 85064c64e7c25e6efe31fa53369ec49db442b68ff9amah "+976 \n" + // Mongolia 85164c64e7c25e6efe31fa53369ec49db442b68ff9amah 85264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+977 xxxx xxxx\n" + // Nepal 85364c64e7c25e6efe31fa53369ec49db442b68ff9amah "+977 98 xxxx xxxx\n" + // Nepal 85464c64e7c25e6efe31fa53369ec49db442b68ff9amah 85564c64e7c25e6efe31fa53369ec49db442b68ff9amah "+98 xxx xxx xxxx\n" + // Iran 85664c64e7c25e6efe31fa53369ec49db442b68ff9amah 85764c64e7c25e6efe31fa53369ec49db442b68ff9amah "+992 xxx xxx xxx\n" + // Tajikistan 85864c64e7c25e6efe31fa53369ec49db442b68ff9amah 85964c64e7c25e6efe31fa53369ec49db442b68ff9amah "+993 xxxx xxxx\n" + // Turkmenistan 86064c64e7c25e6efe31fa53369ec49db442b68ff9amah 86164c64e7c25e6efe31fa53369ec49db442b68ff9amah "+994 xx xxx xxxx\n" + // Azerbaijan 86264c64e7c25e6efe31fa53369ec49db442b68ff9amah "+994 xxx xxxxx\n" + // Azerbaijan 86364c64e7c25e6efe31fa53369ec49db442b68ff9amah 86464c64e7c25e6efe31fa53369ec49db442b68ff9amah "+995 xx xxx xxx\n" + // Georgia 86564c64e7c25e6efe31fa53369ec49db442b68ff9amah 86664c64e7c25e6efe31fa53369ec49db442b68ff9amah "+996 xxx xxx xxx\n" + // Kyrgyzstan 86764c64e7c25e6efe31fa53369ec49db442b68ff9amah 86864c64e7c25e6efe31fa53369ec49db442b68ff9amah "+998 xx xxx xxxx\n"; // Uzbekistan 86964c64e7c25e6efe31fa53369ec49db442b68ff9amah 87064c64e7c25e6efe31fa53369ec49db442b68ff9amah 87164c64e7c25e6efe31fa53369ec49db442b68ff9amah // TODO: need to handle variable number notation 87264c64e7c25e6efe31fa53369ec49db442b68ff9amah private static String formatNumber(String formats, String number) { 87364c64e7c25e6efe31fa53369ec49db442b68ff9amah number = number.trim(); 87464c64e7c25e6efe31fa53369ec49db442b68ff9amah final int nlen = number.length(); 87564c64e7c25e6efe31fa53369ec49db442b68ff9amah final int formatslen = formats.length(); 87664c64e7c25e6efe31fa53369ec49db442b68ff9amah StringBuffer sb = new StringBuffer(); 87764c64e7c25e6efe31fa53369ec49db442b68ff9amah 87864c64e7c25e6efe31fa53369ec49db442b68ff9amah // loop over country codes 87964c64e7c25e6efe31fa53369ec49db442b68ff9amah for (int f = 0; f < formatslen; ) { 88064c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.setLength(0); 88164c64e7c25e6efe31fa53369ec49db442b68ff9amah int n = 0; 88264c64e7c25e6efe31fa53369ec49db442b68ff9amah 88364c64e7c25e6efe31fa53369ec49db442b68ff9amah // loop over letters of pattern 88464c64e7c25e6efe31fa53369ec49db442b68ff9amah while (true) { 88564c64e7c25e6efe31fa53369ec49db442b68ff9amah final char fch = formats.charAt(f); 88664c64e7c25e6efe31fa53369ec49db442b68ff9amah if (fch == '\n' && n >= nlen) return sb.toString(); 88764c64e7c25e6efe31fa53369ec49db442b68ff9amah if (fch == '\n' || n >= nlen) break; 88864c64e7c25e6efe31fa53369ec49db442b68ff9amah final char nch = number.charAt(n); 88964c64e7c25e6efe31fa53369ec49db442b68ff9amah // pattern matches number 89064c64e7c25e6efe31fa53369ec49db442b68ff9amah if (fch == nch || (fch == 'x' && Character.isDigit(nch))) { 89164c64e7c25e6efe31fa53369ec49db442b68ff9amah f++; 89264c64e7c25e6efe31fa53369ec49db442b68ff9amah n++; 89364c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(nch); 89464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 89564c64e7c25e6efe31fa53369ec49db442b68ff9amah // don't match ' ' in pattern, but insert into result 89664c64e7c25e6efe31fa53369ec49db442b68ff9amah else if (fch == ' ') { 89764c64e7c25e6efe31fa53369ec49db442b68ff9amah f++; 89864c64e7c25e6efe31fa53369ec49db442b68ff9amah sb.append(' '); 89964c64e7c25e6efe31fa53369ec49db442b68ff9amah // ' ' at end -> match all the rest 90064c64e7c25e6efe31fa53369ec49db442b68ff9amah if (formats.charAt(f) == '\n') { 90164c64e7c25e6efe31fa53369ec49db442b68ff9amah return sb.append(number, n, nlen).toString(); 90264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 90364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 90464c64e7c25e6efe31fa53369ec49db442b68ff9amah // match failed 90564c64e7c25e6efe31fa53369ec49db442b68ff9amah else break; 90664c64e7c25e6efe31fa53369ec49db442b68ff9amah } 90764c64e7c25e6efe31fa53369ec49db442b68ff9amah 90864c64e7c25e6efe31fa53369ec49db442b68ff9amah // step to the next pattern 90964c64e7c25e6efe31fa53369ec49db442b68ff9amah f = formats.indexOf('\n', f) + 1; 91064c64e7c25e6efe31fa53369ec49db442b68ff9amah if (f == 0) break; 91164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 91264c64e7c25e6efe31fa53369ec49db442b68ff9amah 91364c64e7c25e6efe31fa53369ec49db442b68ff9amah return null; 91464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 91564c64e7c25e6efe31fa53369ec49db442b68ff9amah 91664c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 91764c64e7c25e6efe31fa53369ec49db442b68ff9amah * Format a phone number string. 91864c64e7c25e6efe31fa53369ec49db442b68ff9amah * At some point, PhoneNumberUtils.formatNumber will handle this. 91964c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param num phone number string. 92064c64e7c25e6efe31fa53369ec49db442b68ff9amah * @return formatted phone number string. 92164c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 92264c64e7c25e6efe31fa53369ec49db442b68ff9amah private static String formatNumber(String num) { 92364c64e7c25e6efe31fa53369ec49db442b68ff9amah String fmt = null; 92464c64e7c25e6efe31fa53369ec49db442b68ff9amah 92564c64e7c25e6efe31fa53369ec49db442b68ff9amah fmt = formatNumber(mPlusFormats, num); 92664c64e7c25e6efe31fa53369ec49db442b68ff9amah if (fmt != null) return fmt; 92764c64e7c25e6efe31fa53369ec49db442b68ff9amah 92864c64e7c25e6efe31fa53369ec49db442b68ff9amah fmt = formatNumber(mNanpFormats, num); 92964c64e7c25e6efe31fa53369ec49db442b68ff9amah if (fmt != null) return fmt; 93064c64e7c25e6efe31fa53369ec49db442b68ff9amah 93164c64e7c25e6efe31fa53369ec49db442b68ff9amah return null; 93264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 93364c64e7c25e6efe31fa53369ec49db442b68ff9amah 93464c64e7c25e6efe31fa53369ec49db442b68ff9amah /** 93564c64e7c25e6efe31fa53369ec49db442b68ff9amah * Called when recognition succeeds. It receives a list 93664c64e7c25e6efe31fa53369ec49db442b68ff9amah * of results, builds a corresponding list of Intents, and 93764c64e7c25e6efe31fa53369ec49db442b68ff9amah * passes them to the {@link RecognizerClient}, which selects and 93864c64e7c25e6efe31fa53369ec49db442b68ff9amah * performs a corresponding action. 93964c64e7c25e6efe31fa53369ec49db442b68ff9amah * @param recognizerClient the client that will be sent the results 94064c64e7c25e6efe31fa53369ec49db442b68ff9amah */ 94164c64e7c25e6efe31fa53369ec49db442b68ff9amah protected void onRecognitionSuccess(RecognizerClient recognizerClient) 94264c64e7c25e6efe31fa53369ec49db442b68ff9amah throws InterruptedException { 943d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "onRecognitionSuccess"); 94464c64e7c25e6efe31fa53369ec49db442b68ff9amah 94564c64e7c25e6efe31fa53369ec49db442b68ff9amah if (mLogger != null) mLogger.logNbestHeader(); 94664c64e7c25e6efe31fa53369ec49db442b68ff9amah 94764c64e7c25e6efe31fa53369ec49db442b68ff9amah ArrayList<Intent> intents = new ArrayList<Intent>(); 94864c64e7c25e6efe31fa53369ec49db442b68ff9amah 9497a55150b308ed03d41091e4c3ac693d6eb0ab145mah int highestConfidence = 0; 9507a55150b308ed03d41091e4c3ac693d6eb0ab145mah int examineLimit = RESULT_LIMIT; 9517a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (mMinimizeResults) { 9527a55150b308ed03d41091e4c3ac693d6eb0ab145mah examineLimit = 1; 9537a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 95464c64e7c25e6efe31fa53369ec49db442b68ff9amah for (int result = 0; result < mSrec.getResultCount() && 9557a55150b308ed03d41091e4c3ac693d6eb0ab145mah intents.size() < examineLimit; result++) { 95664c64e7c25e6efe31fa53369ec49db442b68ff9amah 95764c64e7c25e6efe31fa53369ec49db442b68ff9amah // parse the semanticMeaning string and build an Intent 95864c64e7c25e6efe31fa53369ec49db442b68ff9amah String conf = mSrec.getResult(result, Recognizer.KEY_CONFIDENCE); 95964c64e7c25e6efe31fa53369ec49db442b68ff9amah String literal = mSrec.getResult(result, Recognizer.KEY_LITERAL); 96064c64e7c25e6efe31fa53369ec49db442b68ff9amah String semantic = mSrec.getResult(result, Recognizer.KEY_MEANING); 96164c64e7c25e6efe31fa53369ec49db442b68ff9amah String msg = "conf=" + conf + " lit=" + literal + " sem=" + semantic; 962d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, msg); 9637a55150b308ed03d41091e4c3ac693d6eb0ab145mah int confInt = Integer.parseInt(conf); 9647a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (highestConfidence < confInt) highestConfidence = confInt; 9657a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (confInt < MINIMUM_CONFIDENCE || confInt * 2 < highestConfidence) { 966d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "confidence too low, dropping"); 9677a55150b308ed03d41091e4c3ac693d6eb0ab145mah break; 9687a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 96964c64e7c25e6efe31fa53369ec49db442b68ff9amah if (mLogger != null) mLogger.logLine(msg); 97064c64e7c25e6efe31fa53369ec49db442b68ff9amah String[] commands = semantic.trim().split(" "); 97164c64e7c25e6efe31fa53369ec49db442b68ff9amah 97264c64e7c25e6efe31fa53369ec49db442b68ff9amah // DIAL 650 867 5309 97364c64e7c25e6efe31fa53369ec49db442b68ff9amah // DIAL 867 5309 97464c64e7c25e6efe31fa53369ec49db442b68ff9amah // DIAL 911 9757a55150b308ed03d41091e4c3ac693d6eb0ab145mah if ("DIAL".equalsIgnoreCase(commands[0])) { 97664c64e7c25e6efe31fa53369ec49db442b68ff9amah Uri uri = Uri.fromParts("tel", commands[1], null); 97764c64e7c25e6efe31fa53369ec49db442b68ff9amah String num = formatNumber(commands[1]); 97864c64e7c25e6efe31fa53369ec49db442b68ff9amah if (num != null) { 97964c64e7c25e6efe31fa53369ec49db442b68ff9amah addCallIntent(intents, uri, 9807a55150b308ed03d41091e4c3ac693d6eb0ab145mah literal.split(" ")[0].trim() + " " + num, "", 0); 98164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 98264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 98364c64e7c25e6efe31fa53369ec49db442b68ff9amah 98464c64e7c25e6efe31fa53369ec49db442b68ff9amah // CALL JACK JONES 98585a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa // commands should become ["CALL", id, id, ..] reflecting addNameEntriesToGrammar(). 98685a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa else if ("CALL".equalsIgnoreCase(commands[0]) 98785a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa && commands.length >= PHONE_ID_COUNT + 1) { 98864c64e7c25e6efe31fa53369ec49db442b68ff9amah // parse the ids 98964c64e7c25e6efe31fa53369ec49db442b68ff9amah long contactId = Long.parseLong(commands[1]); // people table 99085a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa long primaryId = Long.parseLong(commands[2]); // phones table 99164c64e7c25e6efe31fa53369ec49db442b68ff9amah long homeId = Long.parseLong(commands[3]); // phones table 99264c64e7c25e6efe31fa53369ec49db442b68ff9amah long mobileId = Long.parseLong(commands[4]); // phones table 99364c64e7c25e6efe31fa53369ec49db442b68ff9amah long workId = Long.parseLong(commands[5]); // phones table 99464c64e7c25e6efe31fa53369ec49db442b68ff9amah long otherId = Long.parseLong(commands[6]); // phones table 99585a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa long fallbackId = Long.parseLong(commands[7]); // phones table 99664c64e7c25e6efe31fa53369ec49db442b68ff9amah Resources res = mActivity.getResources(); 99764c64e7c25e6efe31fa53369ec49db442b68ff9amah 99864c64e7c25e6efe31fa53369ec49db442b68ff9amah int count = 0; 99964c64e7c25e6efe31fa53369ec49db442b68ff9amah 100064c64e7c25e6efe31fa53369ec49db442b68ff9amah // 100164c64e7c25e6efe31fa53369ec49db442b68ff9amah // generate the best entry corresponding to what was said 100264c64e7c25e6efe31fa53369ec49db442b68ff9amah // 100364c64e7c25e6efe31fa53369ec49db442b68ff9amah 100464c64e7c25e6efe31fa53369ec49db442b68ff9amah // 'CALL JACK JONES AT HOME|MOBILE|WORK|OTHER' 100585a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa if (commands.length == PHONE_ID_COUNT + 2) { 100685a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa // The last command should imply the type of the phone number. 100785a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa final String spokenPhoneIdCommand = commands[PHONE_ID_COUNT + 1]; 100864c64e7c25e6efe31fa53369ec49db442b68ff9amah long spokenPhoneId = 100985a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa "H".equalsIgnoreCase(spokenPhoneIdCommand) ? homeId : 101085a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa "M".equalsIgnoreCase(spokenPhoneIdCommand) ? mobileId : 101185a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa "W".equalsIgnoreCase(spokenPhoneIdCommand) ? workId : 101285a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa "O".equalsIgnoreCase(spokenPhoneIdCommand) ? otherId : 101364c64e7c25e6efe31fa53369ec49db442b68ff9amah VoiceContact.ID_UNDEFINED; 101464c64e7c25e6efe31fa53369ec49db442b68ff9amah if (spokenPhoneId != VoiceContact.ID_UNDEFINED) { 101564c64e7c25e6efe31fa53369ec49db442b68ff9amah addCallIntent(intents, ContentUris.withAppendedId( 101664c64e7c25e6efe31fa53369ec49db442b68ff9amah Phone.CONTENT_URI, spokenPhoneId), 101785a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa literal, spokenPhoneIdCommand, 0); 101864c64e7c25e6efe31fa53369ec49db442b68ff9amah count++; 101964c64e7c25e6efe31fa53369ec49db442b68ff9amah } 102064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 102164c64e7c25e6efe31fa53369ec49db442b68ff9amah 102264c64e7c25e6efe31fa53369ec49db442b68ff9amah // 'CALL JACK JONES', with valid default phoneId 102385a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa else if (commands.length == PHONE_ID_COUNT + 1) { 10247a55150b308ed03d41091e4c3ac693d6eb0ab145mah String phoneType = null; 10257a55150b308ed03d41091e4c3ac693d6eb0ab145mah CharSequence phoneIdMsg = null; 102685a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa if (primaryId == VoiceContact.ID_UNDEFINED) { 10277a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneType = null; 10287a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneIdMsg = null; 102985a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa } else if (primaryId == homeId) { 10307a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneType = "H"; 10317a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneIdMsg = res.getText(R.string.at_home); 103285a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa } else if (primaryId == mobileId) { 10337a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneType = "M"; 10347a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneIdMsg = res.getText(R.string.on_mobile); 103585a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa } else if (primaryId == workId) { 10367a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneType = "W"; 10377a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneIdMsg = res.getText(R.string.at_work); 103885a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa } else if (primaryId == otherId) { 10397a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneType = "O"; 10407a55150b308ed03d41091e4c3ac693d6eb0ab145mah phoneIdMsg = res.getText(R.string.at_other); 10417a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 104264c64e7c25e6efe31fa53369ec49db442b68ff9amah if (phoneIdMsg != null) { 104364c64e7c25e6efe31fa53369ec49db442b68ff9amah addCallIntent(intents, ContentUris.withAppendedId( 104485a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa Phone.CONTENT_URI, primaryId), 10457a55150b308ed03d41091e4c3ac693d6eb0ab145mah literal + phoneIdMsg, phoneType, 0); 104664c64e7c25e6efe31fa53369ec49db442b68ff9amah count++; 104764c64e7c25e6efe31fa53369ec49db442b68ff9amah } 104864c64e7c25e6efe31fa53369ec49db442b68ff9amah } 104964c64e7c25e6efe31fa53369ec49db442b68ff9amah 10507a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (count == 0 || !mMinimizeResults) { 10517a55150b308ed03d41091e4c3ac693d6eb0ab145mah // 10527a55150b308ed03d41091e4c3ac693d6eb0ab145mah // generate all other entries for this person 10537a55150b308ed03d41091e4c3ac693d6eb0ab145mah // 10547a55150b308ed03d41091e4c3ac693d6eb0ab145mah 10557a55150b308ed03d41091e4c3ac693d6eb0ab145mah // trim last two words, ie 'at home', etc 10567a55150b308ed03d41091e4c3ac693d6eb0ab145mah String lit = literal; 105785a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa if (commands.length == PHONE_ID_COUNT + 2) { 10587a55150b308ed03d41091e4c3ac693d6eb0ab145mah String[] words = literal.trim().split(" "); 10597a55150b308ed03d41091e4c3ac693d6eb0ab145mah StringBuffer sb = new StringBuffer(); 10607a55150b308ed03d41091e4c3ac693d6eb0ab145mah for (int i = 0; i < words.length - 2; i++) { 10617a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (i != 0) { 10627a55150b308ed03d41091e4c3ac693d6eb0ab145mah sb.append(' '); 10637a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 10647a55150b308ed03d41091e4c3ac693d6eb0ab145mah sb.append(words[i]); 106564c64e7c25e6efe31fa53369ec49db442b68ff9amah } 10667a55150b308ed03d41091e4c3ac693d6eb0ab145mah lit = sb.toString(); 106764c64e7c25e6efe31fa53369ec49db442b68ff9amah } 106864c64e7c25e6efe31fa53369ec49db442b68ff9amah 10697a55150b308ed03d41091e4c3ac693d6eb0ab145mah // add 'CALL JACK JONES at home' using phoneId 10707a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (homeId != VoiceContact.ID_UNDEFINED) { 10717a55150b308ed03d41091e4c3ac693d6eb0ab145mah addCallIntent(intents, ContentUris.withAppendedId( 10727a55150b308ed03d41091e4c3ac693d6eb0ab145mah Phone.CONTENT_URI, homeId), 10737a55150b308ed03d41091e4c3ac693d6eb0ab145mah lit + res.getText(R.string.at_home), "H", 0); 10747a55150b308ed03d41091e4c3ac693d6eb0ab145mah count++; 10757a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 107664c64e7c25e6efe31fa53369ec49db442b68ff9amah 10777a55150b308ed03d41091e4c3ac693d6eb0ab145mah // add 'CALL JACK JONES on mobile' using mobileId 10787a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (mobileId != VoiceContact.ID_UNDEFINED) { 10797a55150b308ed03d41091e4c3ac693d6eb0ab145mah addCallIntent(intents, ContentUris.withAppendedId( 10807a55150b308ed03d41091e4c3ac693d6eb0ab145mah Phone.CONTENT_URI, mobileId), 10817a55150b308ed03d41091e4c3ac693d6eb0ab145mah lit + res.getText(R.string.on_mobile), "M", 0); 10827a55150b308ed03d41091e4c3ac693d6eb0ab145mah count++; 10837a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 108464c64e7c25e6efe31fa53369ec49db442b68ff9amah 10857a55150b308ed03d41091e4c3ac693d6eb0ab145mah // add 'CALL JACK JONES at work' using workId 10867a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (workId != VoiceContact.ID_UNDEFINED) { 10877a55150b308ed03d41091e4c3ac693d6eb0ab145mah addCallIntent(intents, ContentUris.withAppendedId( 10887a55150b308ed03d41091e4c3ac693d6eb0ab145mah Phone.CONTENT_URI, workId), 10897a55150b308ed03d41091e4c3ac693d6eb0ab145mah lit + res.getText(R.string.at_work), "W", 0); 10907a55150b308ed03d41091e4c3ac693d6eb0ab145mah count++; 10917a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 109264c64e7c25e6efe31fa53369ec49db442b68ff9amah 10937a55150b308ed03d41091e4c3ac693d6eb0ab145mah // add 'CALL JACK JONES at other' using otherId 10947a55150b308ed03d41091e4c3ac693d6eb0ab145mah if (otherId != VoiceContact.ID_UNDEFINED) { 10957a55150b308ed03d41091e4c3ac693d6eb0ab145mah addCallIntent(intents, ContentUris.withAppendedId( 10967a55150b308ed03d41091e4c3ac693d6eb0ab145mah Phone.CONTENT_URI, otherId), 10977a55150b308ed03d41091e4c3ac693d6eb0ab145mah lit + res.getText(R.string.at_other), "O", 0); 10987a55150b308ed03d41091e4c3ac693d6eb0ab145mah count++; 10997a55150b308ed03d41091e4c3ac693d6eb0ab145mah } 110064c64e7c25e6efe31fa53369ec49db442b68ff9amah 110185a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa if (fallbackId != VoiceContact.ID_UNDEFINED) { 110285a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa addCallIntent(intents, ContentUris.withAppendedId( 110385a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa Phone.CONTENT_URI, fallbackId), 110485a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa lit, "", 0); 110585a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa count++; 110685a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa } 110764c64e7c25e6efe31fa53369ec49db442b68ff9amah } 110864c64e7c25e6efe31fa53369ec49db442b68ff9amah } 11098c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon 11108c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon else if ("X".equalsIgnoreCase(commands[0])) { 11118c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon Intent intent = new Intent(RecognizerEngine.ACTION_RECOGNIZER_RESULT, null); 11128c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon intent.putExtra(RecognizerEngine.SENTENCE_EXTRA, literal); 11138c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon intent.putExtra(RecognizerEngine.SEMANTIC_EXTRA, semantic); 11148c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon addIntent(intents, intent); 11158c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon } 11168c7aac011e578450a6837ed4ba55b1167c17bf46Martin Hibdon 111764c64e7c25e6efe31fa53369ec49db442b68ff9amah // "CALL VoiceMail" 11187a55150b308ed03d41091e4c3ac693d6eb0ab145mah else if ("voicemail".equalsIgnoreCase(commands[0]) && commands.length == 1) { 111964c64e7c25e6efe31fa53369ec49db442b68ff9amah addCallIntent(intents, Uri.fromParts("voicemail", "x", null), 11207a55150b308ed03d41091e4c3ac693d6eb0ab145mah literal, "", Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 112164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 112264c64e7c25e6efe31fa53369ec49db442b68ff9amah 112364c64e7c25e6efe31fa53369ec49db442b68ff9amah // "REDIAL" 11247a55150b308ed03d41091e4c3ac693d6eb0ab145mah else if ("redial".equalsIgnoreCase(commands[0]) && commands.length == 1) { 112564c64e7c25e6efe31fa53369ec49db442b68ff9amah String number = VoiceContact.redialNumber(mActivity); 112664c64e7c25e6efe31fa53369ec49db442b68ff9amah if (number != null) { 11277a55150b308ed03d41091e4c3ac693d6eb0ab145mah addCallIntent(intents, Uri.fromParts("tel", number, null), 11287a55150b308ed03d41091e4c3ac693d6eb0ab145mah literal, "", Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 112964c64e7c25e6efe31fa53369ec49db442b68ff9amah } 113064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 113164c64e7c25e6efe31fa53369ec49db442b68ff9amah 113264c64e7c25e6efe31fa53369ec49db442b68ff9amah // "Intent ..." 113364c64e7c25e6efe31fa53369ec49db442b68ff9amah else if ("Intent".equalsIgnoreCase(commands[0])) { 113464c64e7c25e6efe31fa53369ec49db442b68ff9amah for (int i = 1; i < commands.length; i++) { 113564c64e7c25e6efe31fa53369ec49db442b68ff9amah try { 113664c64e7c25e6efe31fa53369ec49db442b68ff9amah Intent intent = Intent.getIntent(commands[i]); 113764c64e7c25e6efe31fa53369ec49db442b68ff9amah if (intent.getStringExtra(SENTENCE_EXTRA) == null) { 113864c64e7c25e6efe31fa53369ec49db442b68ff9amah intent.putExtra(SENTENCE_EXTRA, literal); 113964c64e7c25e6efe31fa53369ec49db442b68ff9amah } 114064c64e7c25e6efe31fa53369ec49db442b68ff9amah addIntent(intents, intent); 114164c64e7c25e6efe31fa53369ec49db442b68ff9amah } catch (URISyntaxException e) { 1142d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) { 11437a55150b308ed03d41091e4c3ac693d6eb0ab145mah Log.d(TAG, "onRecognitionSuccess: poorly " + 11447a55150b308ed03d41091e4c3ac693d6eb0ab145mah "formed URI in grammar" + e); 114564c64e7c25e6efe31fa53369ec49db442b68ff9amah } 114664c64e7c25e6efe31fa53369ec49db442b68ff9amah } 114764c64e7c25e6efe31fa53369ec49db442b68ff9amah } 114864c64e7c25e6efe31fa53369ec49db442b68ff9amah } 114964c64e7c25e6efe31fa53369ec49db442b68ff9amah 115064c64e7c25e6efe31fa53369ec49db442b68ff9amah // "OPEN ..." 11515f25619fecb3fda9b34f90eb1e333a89ec431583Martin Hibdon else if ("OPEN".equalsIgnoreCase(commands[0]) && mAllowOpenEntries) { 115264c64e7c25e6efe31fa53369ec49db442b68ff9amah PackageManager pm = mActivity.getPackageManager(); 11534a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon if (commands.length > 1 & mOpenEntries != null) { 1154e5258ff473c778362d612389db79b740e9c35911Martin Hibdon // the semantic value is equal to the literal in this case. 11554a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // We have to do the mapping from this text to the 11564a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // componentname ourselves. See Bug: 2457238. 11574a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // The problem is that the list of all componentnames 11584a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // can be pretty large and overflow the limit that 11594a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon // the recognizer has. 11604a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String meaning = mOpenEntries.get(commands[1]); 11614a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String[] components = meaning.trim().split(" "); 11624a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon for (int i=0; i < components.length; i++) { 11634a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String component = components[i]; 11644a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon Intent intent = new Intent(Intent.ACTION_MAIN); 116564c64e7c25e6efe31fa53369ec49db442b68ff9amah intent.addCategory("android.intent.category.VOICE_LAUNCH"); 11664a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String packageName = component.substring( 11674a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon 0, component.lastIndexOf('/')); 11684a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String className = component.substring( 11694a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon component.lastIndexOf('/')+1, component.length()); 117027d520022f552e3e4b17b00d6ec4db9306fe7deaMartin Hibdon intent.setClassName(packageName, className); 11714a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon List<ResolveInfo> riList = pm.queryIntentActivities(intent, 0); 11724a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon for (ResolveInfo ri : riList) { 11734a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon String label = ri.loadLabel(pm).toString(); 11744a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon intent = new Intent(Intent.ACTION_MAIN); 11754a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon intent.addCategory("android.intent.category.VOICE_LAUNCH"); 11764a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon intent.setClassName(packageName, className); 11774a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon intent.putExtra(SENTENCE_EXTRA, literal.split(" ")[0] + " " + label); 11784a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon addIntent(intents, intent); 11794a330957ce5190ed86c57e0c65910359b866cba7Martin Hibdon } 118064c64e7c25e6efe31fa53369ec49db442b68ff9amah } 118164c64e7c25e6efe31fa53369ec49db442b68ff9amah } 118264c64e7c25e6efe31fa53369ec49db442b68ff9amah } 118364c64e7c25e6efe31fa53369ec49db442b68ff9amah 118464c64e7c25e6efe31fa53369ec49db442b68ff9amah // can't parse result 118564c64e7c25e6efe31fa53369ec49db442b68ff9amah else { 1186d3694c0511a27f1fb44fa2760ee0d4562ffe1066Joe Onorato if (false) Log.d(TAG, "onRecognitionSuccess: parse error"); 118764c64e7c25e6efe31fa53369ec49db442b68ff9amah } 118864c64e7c25e6efe31fa53369ec49db442b68ff9amah } 118964c64e7c25e6efe31fa53369ec49db442b68ff9amah 119064c64e7c25e6efe31fa53369ec49db442b68ff9amah // log if requested 119164c64e7c25e6efe31fa53369ec49db442b68ff9amah if (mLogger != null) mLogger.logIntents(intents); 119264c64e7c25e6efe31fa53369ec49db442b68ff9amah 119364c64e7c25e6efe31fa53369ec49db442b68ff9amah // bail out if cancelled 119464c64e7c25e6efe31fa53369ec49db442b68ff9amah if (Thread.interrupted()) throw new InterruptedException(); 119564c64e7c25e6efe31fa53369ec49db442b68ff9amah 119664c64e7c25e6efe31fa53369ec49db442b68ff9amah if (intents.size() == 0) { 119764c64e7c25e6efe31fa53369ec49db442b68ff9amah // TODO: strip HOME|MOBILE|WORK and try default here? 119864c64e7c25e6efe31fa53369ec49db442b68ff9amah recognizerClient.onRecognitionFailure("No Intents generated"); 119964c64e7c25e6efe31fa53369ec49db442b68ff9amah } 120064c64e7c25e6efe31fa53369ec49db442b68ff9amah else { 120164c64e7c25e6efe31fa53369ec49db442b68ff9amah recognizerClient.onRecognitionSuccess( 120264c64e7c25e6efe31fa53369ec49db442b68ff9amah intents.toArray(new Intent[intents.size()])); 120364c64e7c25e6efe31fa53369ec49db442b68ff9amah } 120464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 120564c64e7c25e6efe31fa53369ec49db442b68ff9amah 120664c64e7c25e6efe31fa53369ec49db442b68ff9amah // only add if different 120764c64e7c25e6efe31fa53369ec49db442b68ff9amah private static void addCallIntent(ArrayList<Intent> intents, Uri uri, String literal, 12087a55150b308ed03d41091e4c3ac693d6eb0ab145mah String phoneType, int flags) { 120985a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri) 121085a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa .setFlags(flags) 121185a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa .putExtra(SENTENCE_EXTRA, literal) 121285a421c6d6bf1fdbbee134d99c1a7450b00ce8fcDaisuke Miyakawa .putExtra(PHONE_TYPE_EXTRA, phoneType); 121364c64e7c25e6efe31fa53369ec49db442b68ff9amah addIntent(intents, intent); 121464c64e7c25e6efe31fa53369ec49db442b68ff9amah } 121564c64e7c25e6efe31fa53369ec49db442b68ff9amah} 1216