• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.voicedialer;
18 
19 import android.app.Activity;
20 import android.database.Cursor;
21 import android.database.DatabaseUtils;
22 import android.provider.ContactsContract.CommonDataKinds.Phone;
23 import android.provider.CallLog;
24 import android.util.Config;
25 import android.util.Log;
26 import java.io.BufferedReader;
27 import java.io.File;
28 import java.io.FileReader;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.List;
32 
33 
34 /**
35  * This class represents a person who may be called via the VoiceDialer app.
36  * The person has a name and a list of phones (home, mobile, work, other).
37  */
38 public class VoiceContact {
39     private static final String TAG = "VoiceContact";
40 
41     /**
42      * Corresponding row doesn't exist.
43      */
44     public static final long ID_UNDEFINED = -1;
45 
46     public final String mName;
47     public final long mContactId;
48     public final long mPrimaryId;
49     public final long mHomeId;
50     public final long mMobileId;
51     public final long mWorkId;
52     public final long mOtherId;
53 
54     /**
55      * Constructor.
56      *
57      * @param name person's name.
58      * @param contactId ID in person table.
59      * @param primaryId primary ID in phone table.
60      * @param homeId home ID in phone table.
61      * @param mobileId mobile ID in phone table.
62      * @param workId work ID in phone table.
63      * @param otherId other ID in phone table.
64      */
VoiceContact(String name, long contactId, long primaryId, long homeId, long mobileId, long workId,long otherId)65     private VoiceContact(String name, long contactId, long primaryId,
66             long homeId, long mobileId, long workId,long otherId) {
67         mName = name;
68         mContactId = contactId;
69         mPrimaryId = primaryId;
70         mHomeId = homeId;
71         mMobileId = mobileId;
72         mWorkId = workId;
73         mOtherId = otherId;
74     }
75 
76     @Override
hashCode()77     public int hashCode() {
78         final int LARGE_PRIME = 1610612741;
79         int hash = 0;
80         hash = LARGE_PRIME * (hash + (int)mContactId);
81         hash = LARGE_PRIME * (hash + (int)mPrimaryId);
82         hash = LARGE_PRIME * (hash + (int)mHomeId);
83         hash = LARGE_PRIME * (hash + (int)mMobileId);
84         hash = LARGE_PRIME * (hash + (int)mWorkId);
85         hash = LARGE_PRIME * (hash + (int)mOtherId);
86         return mName.hashCode() + hash;
87     }
88 
89     @Override
toString()90     public String toString() {
91         return "mName=" + mName
92                 + " mPersonId=" + mContactId
93                 + " mPrimaryId=" + mPrimaryId
94                 + " mHomeId=" + mHomeId
95                 + " mMobileId=" + mMobileId
96                 + " mWorkId=" + mWorkId
97                 + " mOtherId=" + mOtherId;
98     }
99 
100     /**
101      * @param activity The VoiceDialerActivity instance.
102      * @return List of {@link VoiceContact} from
103      * the contact list content provider.
104      */
getVoiceContacts(Activity activity)105     public static List<VoiceContact> getVoiceContacts(Activity activity) {
106         if (Config.LOGD) Log.d(TAG, "VoiceContact.getVoiceContacts");
107 
108         List<VoiceContact> contacts = new ArrayList<VoiceContact>();
109 
110         String[] phonesProjection = new String[] {
111             Phone._ID,
112             Phone.TYPE,
113             Phone.IS_PRIMARY,
114             // TODO: handle type != 0,1,2, and use LABEL
115             Phone.LABEL,
116             Phone.DISPLAY_NAME,
117             //Contacts.Phones.NUMBER,
118             Phone.CONTACT_ID,
119         };
120 
121         // Table is sorted by number of times contacted and name. If we cannot fit all contacts
122         // in the recognizer, we will at least have the commonly used ones.
123         Cursor cursor = activity.getContentResolver().query(
124                 Phone.CONTENT_URI, phonesProjection,
125                 Phone.NUMBER + " NOT NULL", null,
126                 Phone.LAST_TIME_CONTACTED + " DESC");
127 
128         final int phoneIdColumn = cursor.getColumnIndexOrThrow(Phone._ID);
129         final int typeColumn = cursor.getColumnIndexOrThrow(Phone.TYPE);
130         final int isPrimaryColumn = cursor.getColumnIndexOrThrow(Phone.IS_PRIMARY);
131         int labelColumn = cursor.getColumnIndexOrThrow(Phone.LABEL);
132         final int nameColumn = cursor.getColumnIndexOrThrow(Phone.DISPLAY_NAME);
133         //final int numberColumn = cursor.getColumnIndexOrThrow(Contacts.Phones.NUMBER);
134         final int personIdColumn = cursor.getColumnIndexOrThrow(Phone.CONTACT_ID);
135 
136         // pieces of next VoiceContact
137         String name = null;
138         long personId = ID_UNDEFINED;
139         long primaryId = ID_UNDEFINED;
140         long homeId = ID_UNDEFINED;
141         long mobileId = ID_UNDEFINED;
142         long workId = ID_UNDEFINED;
143         long otherId = ID_UNDEFINED;
144 
145         // loop over phone table
146         cursor.moveToFirst();
147         while (cursor.moveToNext()) {
148             long phoneIdAtCursor = cursor.getLong(phoneIdColumn);
149             int typeAtCursor = cursor.getInt(typeColumn);
150             long isPrimaryAtCursor = cursor.getLong(isPrimaryColumn);
151             String labelAtCursor = cursor.getString(labelColumn);
152             String nameAtCursor = cursor.getString(nameColumn);
153             //String numberAtCursor = cursor.getString(numberColumn);
154             long personIdAtCursor = cursor.getLong(personIdColumn);
155 
156             /*
157             if (Config.LOGD) {
158                 Log.d(TAG, "phoneId=" + phoneIdAtCursor
159                         + " type=" + typeAtCursor
160                         + " isPrimary=" + isPrimaryAtCursor
161                         + " label=" + labelAtCursor
162                         + " name=" + nameAtCursor
163                         //+ " number=" + numberAtCursor
164                         + " personId=" + personIdAtCursor
165                         );
166             }
167             */
168 
169             // encountered a new name, so generate current VoiceContact
170             if (name != null && !name.equals(nameAtCursor)) {
171                 contacts.add(new VoiceContact(name, personId, primaryId,
172                         homeId, mobileId, workId, otherId));
173                 name = null;
174             }
175 
176             // start accumulating pieces for a new VoiceContact
177             if (name == null) {
178                 name = nameAtCursor;
179                 personId = personIdAtCursor;
180                 primaryId = ID_UNDEFINED;
181                 homeId = ID_UNDEFINED;
182                 mobileId = ID_UNDEFINED;
183                 workId = ID_UNDEFINED;
184                 otherId = ID_UNDEFINED;
185             }
186 
187             // if labeled, then patch to HOME/MOBILE/WORK/OTHER
188             if (typeAtCursor == Phone.TYPE_CUSTOM &&
189                     labelAtCursor != null) {
190                 String label = labelAtCursor.toLowerCase();
191                 if (label.contains("home") || label.contains("house")) {
192                     typeAtCursor = Phone.TYPE_HOME;
193                 }
194                 else if (label.contains("mobile") || label.contains("cell")) {
195                     typeAtCursor = Phone.TYPE_MOBILE;
196                 }
197                 else if (label.contains("work") || label.contains("office")) {
198                     typeAtCursor = Phone.TYPE_WORK;
199                 }
200                 else if (label.contains("other")) {
201                     typeAtCursor = Phone.TYPE_OTHER;
202                 }
203             }
204 
205             // save the home, mobile, or work phone id
206             switch (typeAtCursor) {
207                 case Phone.TYPE_HOME:
208                     homeId = phoneIdAtCursor;
209                     if (isPrimaryAtCursor != 0) {
210                         primaryId = phoneIdAtCursor;
211                     }
212                     break;
213                 case Phone.TYPE_MOBILE:
214                     mobileId = phoneIdAtCursor;
215                     if (isPrimaryAtCursor != 0) {
216                         primaryId = phoneIdAtCursor;
217                     }
218                     break;
219                 case Phone.TYPE_WORK:
220                     workId = phoneIdAtCursor;
221                     if (isPrimaryAtCursor != 0) {
222                         primaryId = phoneIdAtCursor;
223                     }
224                     break;
225                 case Phone.TYPE_OTHER:
226                     otherId = phoneIdAtCursor;
227                     if (isPrimaryAtCursor != 0) {
228                         primaryId = phoneIdAtCursor;
229                     }
230                     break;
231             }
232         }
233 
234         // generate the last VoiceContact
235         if (name != null) {
236             contacts.add(new VoiceContact(name, personId, primaryId,
237                             homeId, mobileId, workId, otherId));
238         }
239 
240         // clean up cursor
241         cursor.close();
242 
243         if (Config.LOGD) Log.d(TAG, "VoiceContact.getVoiceContacts " + contacts.size());
244 
245         return contacts;
246     }
247 
248     /**
249      * @param contactsFile File containing a list of names,
250      * one per line.
251      * @return a List of {@link VoiceContact} in a File.
252      */
getVoiceContactsFromFile(File contactsFile)253     public static List<VoiceContact> getVoiceContactsFromFile(File contactsFile) {
254         if (Config.LOGD) Log.d(TAG, "getVoiceContactsFromFile " + contactsFile);
255 
256         List<VoiceContact> contacts = new ArrayList<VoiceContact>();
257 
258         // read from a file
259         BufferedReader br = null;
260         try {
261             br = new BufferedReader(new FileReader(contactsFile), 8192);
262             String name;
263             for (int id = 1; (name = br.readLine()) != null; id++) {
264                 contacts.add(new VoiceContact(name, id, ID_UNDEFINED,
265                         ID_UNDEFINED, ID_UNDEFINED, ID_UNDEFINED, ID_UNDEFINED));
266             }
267         }
268         catch (IOException e) {
269             if (Config.LOGD) Log.d(TAG, "getVoiceContactsFromFile failed " + e);
270         }
271         finally {
272             try {
273                 br.close();
274             } catch (IOException e) {
275                 if (Config.LOGD) Log.d(TAG, "getVoiceContactsFromFile failed during close " + e);
276             }
277         }
278 
279         if (Config.LOGD) Log.d(TAG, "getVoiceContactsFromFile " + contacts.size());
280 
281         return contacts;
282     }
283 
284     /**
285      * @param activity The VoiceDialerActivity instance.
286      * @return String of last number dialed.
287      */
redialNumber(Activity activity)288     public static String redialNumber(Activity activity) {
289         Cursor cursor = activity.getContentResolver().query(
290                 CallLog.Calls.CONTENT_URI,
291                 new String[] { CallLog.Calls.NUMBER },
292                 CallLog.Calls.TYPE + "=" + CallLog.Calls.OUTGOING_TYPE,
293                 null,
294                 CallLog.Calls.DEFAULT_SORT_ORDER + " LIMIT 1");
295         String number = null;
296         if (cursor.getCount() >= 1) {
297             cursor.moveToNext();
298             int column = cursor.getColumnIndexOrThrow(CallLog.Calls.NUMBER);
299             number = cursor.getString(column);
300         }
301         cursor.close();
302 
303         if (Config.LOGD) Log.d(TAG, "redialNumber " + number);
304 
305         return number;
306     }
307 
308 }
309