AI 144185: Integrate cdma into the main code base.
[android/platform/packages/apps/Phone.git] / src / com / android / phone / SimContacts.java
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.phone;
18
19 import android.app.ProgressDialog;
20 import android.content.ContentResolver;
21 import android.content.ContentUris;
22 import android.content.ContentValues;
23 import android.content.DialogInterface;
24 import android.content.Intent;
25 import android.content.DialogInterface.OnCancelListener;
26 import android.content.DialogInterface.OnClickListener;
27 import android.database.Cursor;
28 import android.database.DatabaseUtils;
29 import android.net.Uri;
30 import android.os.Bundle;
31 import android.provider.Contacts;
32 import android.provider.Contacts.People;
33 import android.text.TextUtils;
34 import android.util.Log;
35 import android.view.ContextMenu;
36 import android.view.KeyEvent;
37 import android.view.Menu;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.widget.AdapterView;
41 import android.widget.CursorAdapter;
42 import android.widget.ListView;
43 import android.widget.SimpleCursorAdapter;
44 import android.widget.TextView;
45
46 /**
47  * SIM Address Book UI for the Phone app.
48  */
49 public class SimContacts extends ADNList {
50     private static final int MENU_IMPORT_ONE = 1;
51     private static final int MENU_IMPORT_ALL = 2;
52     private ProgressDialog mProgressDialog;
53
54     
55     @Override
56     protected void onCreate(Bundle icicle) {
57         super.onCreate(icicle);
58         registerForContextMenu(getListView());
59     }
60
61     private class ImportAllThread extends Thread implements OnCancelListener, OnClickListener {
62         boolean mCanceled = false;
63         
64         public ImportAllThread() {
65             super("ImportAllThread");
66         }
67         
68         @Override
69         public void run() {
70             ContentValues map = new ContentValues();
71             ContentResolver cr = getContentResolver();
72             Object[] parsed = new Object[2];
73             
74             mCursor.moveToPosition(-1);
75             while (!mCanceled && mCursor.moveToNext()) {
76                 String name = mCursor.getString(0);
77                 String number = mCursor.getString(1);
78
79                 Uri personUrl = parseName(name, parsed);
80
81                 if (personUrl == null) {
82                     map.clear();
83                     map.put(Contacts.People.NAME, (String) parsed[0]);
84                     personUrl = People.createPersonInMyContactsGroup(cr, map);
85                     if (personUrl == null) {
86                         Log.e(TAG, "Error inserting person " + map);
87                         continue;
88                     }
89                 }
90
91                 map.clear();
92                 map.put(Contacts.People.Phones.NUMBER, number);
93                 map.put(Contacts.People.Phones.TYPE, (Integer) parsed[1]);
94                 Uri numberUrl = cr.insert(
95                         Uri.withAppendedPath(personUrl, Contacts.People.Phones.CONTENT_DIRECTORY),
96                         map);
97                 
98                 mProgressDialog.incrementProgressBy(1);
99                 if (numberUrl == null) {
100                     Log.e(TAG, "Error inserting phone " + map + " for person " +
101                             personUrl + ", removing person");
102                     continue;
103                 }
104             }
105             
106             mProgressDialog.dismiss();
107
108             finish();
109         }
110
111         public void onCancel(DialogInterface dialog) {
112             mCanceled = true;
113         }
114
115         public void onClick(DialogInterface dialog, int which) {
116             mCanceled = true;
117             mProgressDialog.dismiss();
118         }
119     }
120
121     @Override
122     protected CursorAdapter newAdapter() {
123         return new SimpleCursorAdapter(this, R.layout.sim_import_list_entry, mCursor,
124                 new String[] { "name" }, new int[] { android.R.id.text1 });
125     }
126
127     @Override
128     protected Uri resolveIntent() {
129         Intent intent = getIntent();
130         intent.setData(Uri.parse("content://icc/adn"));
131         if (Intent.ACTION_PICK.equals(intent.getAction())) {
132             // "index" is 1-based
133             mInitialSelection = intent.getIntExtra("index", 0) - 1;
134         }
135         return intent.getData();
136     }
137
138     @Override
139     public boolean onCreateOptionsMenu(Menu menu) {
140         super.onCreateOptionsMenu(menu);
141         menu.add(0, MENU_IMPORT_ALL, 0, R.string.importAllSimEntries);
142         return true;
143     }
144
145     @Override
146     public boolean onOptionsItemSelected(MenuItem item) {
147         switch (item.getItemId()) {
148             case MENU_IMPORT_ALL:
149                 CharSequence title = getString(R.string.importAllSimEntries);
150                 CharSequence message = getString(R.string.importingSimContacts); 
151
152                 ImportAllThread thread = new ImportAllThread();
153
154                 mProgressDialog = new ProgressDialog(this);
155                 mProgressDialog.setTitle(title);
156                 mProgressDialog.setMessage(message);
157                 mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
158                 mProgressDialog.setButton(getString(R.string.cancel), thread);
159                 mProgressDialog.setProgress(0);
160                 mProgressDialog.setMax(mCursor.getCount());
161                 mProgressDialog.show();
162                 
163                 thread.start();
164                 
165                 return true;
166         }
167         return super.onOptionsItemSelected(item);
168     }
169     
170     @Override
171     public boolean onContextItemSelected(MenuItem item) {
172         switch (item.getItemId()) {
173             case MENU_IMPORT_ONE:
174                 ContextMenu.ContextMenuInfo menuInfo = item.getMenuInfo();
175                 if (menuInfo instanceof AdapterView.AdapterContextMenuInfo) {
176                     int position = ((AdapterView.AdapterContextMenuInfo)menuInfo).position;
177                     importOne(position);
178                     return true;
179                 }
180         }
181         return super.onContextItemSelected(item);
182     }
183
184     
185     public void onCreateContextMenu(ContextMenu menu, View v,
186             ContextMenu.ContextMenuInfo menuInfo) {
187         if (menuInfo instanceof AdapterView.AdapterContextMenuInfo) {
188             AdapterView.AdapterContextMenuInfo itemInfo =
189                     (AdapterView.AdapterContextMenuInfo) menuInfo;
190             TextView textView = (TextView) itemInfo.targetView.findViewById(android.R.id.text1);
191             if (textView != null) {
192                 menu.setHeaderTitle(textView.getText());
193             }
194             menu.add(0, MENU_IMPORT_ONE, 0, R.string.importSimEntry);
195         }
196     }
197
198     @Override
199     public void onListItemClick(ListView l, View v, int position, long id) {
200         importOne(position);
201     }
202
203     private void importOne(int position) {
204         if (mCursor.moveToPosition(position)) {
205             String name = mCursor.getString(NAME_COLUMN);
206             String number = mCursor.getString(NUMBER_COLUMN);
207             Object[] parsed = new Object[2];
208             Uri personUrl = parseName(name, parsed);
209
210             Intent intent;
211             if (personUrl == null) {
212                 // Add a new contact
213                 intent = new Intent(Contacts.Intents.Insert.ACTION,
214                         Contacts.People.CONTENT_URI);
215                 intent.putExtra(Contacts.Intents.Insert.NAME, (String)parsed[0]);
216                 intent.putExtra(Contacts.Intents.Insert.PHONE, number);
217                 intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, ((Integer)parsed[1]).intValue());
218             } else {
219                 // Add the number to an existing contact
220                 intent = new Intent(Intent.ACTION_EDIT, personUrl);
221                 intent.putExtra(Contacts.Intents.Insert.PHONE, number);
222                 intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, ((Integer)parsed[1]).intValue());
223             }
224             startActivity(intent);
225         }
226     }
227
228     /**
229      * Parse the name looking for /W /H /M or /O at the end, signifying the type.
230      *
231      * @param name The name from the SIM card
232      * @param parsed slot 0 is filled in with the name, and slot 1 is filled
233      * in with the type
234      */
235     private Uri parseName(String name, Object[] parsed) {
236         // default to TYPE_MOBILE so you can send SMSs to the numbers
237         int type = Contacts.PhonesColumns.TYPE_MOBILE;
238
239         // Look for /W /H /M or /O at the end of the name signifying the type
240         int nameLen = name.length();
241         if (nameLen - 2 >= 0 && name.charAt(nameLen - 2) == '/') {
242             char c = Character.toUpperCase(name.charAt(nameLen - 1));
243             if (c == 'W') {
244                 type = Contacts.PhonesColumns.TYPE_WORK;
245             } else if (c == 'M') {
246                 type = Contacts.PhonesColumns.TYPE_MOBILE;
247             } else if (c == 'H') {
248                 type = Contacts.PhonesColumns.TYPE_HOME;
249             } else if (c == 'O') {
250                 type = Contacts.PhonesColumns.TYPE_MOBILE;
251             }
252             name = name.substring(0, nameLen - 2);
253         }
254         parsed[0] = name;
255         parsed[1] = type;
256
257         StringBuilder where = new StringBuilder(Contacts.People.NAME);
258         where.append('=');
259         DatabaseUtils.appendEscapedSQLString(where, name);
260         Uri url = null;
261         Cursor c = getContentResolver().query(Contacts.People.CONTENT_URI,
262                 new String[] {Contacts.People._ID},
263                 where.toString(), null, null);
264         if (c != null) {
265             if (c.moveToFirst()) {
266                 url = ContentUris.withAppendedId(Contacts.People.CONTENT_URI, c.getLong(0));
267             }
268             c.deactivate();
269         }
270         return url;
271     }
272
273     @Override
274     public boolean onKeyDown(int keyCode, KeyEvent event) {
275         switch (keyCode) {
276             case KeyEvent.KEYCODE_CALL: {
277                 if (mCursor != null && mCursor.moveToPosition(getSelectedItemPosition())) {
278                     String number = mCursor.getString(NUMBER_COLUMN);
279                     if (number == null || !TextUtils.isGraphic(number)) {
280                         // There is no number entered.
281                         //TODO play error sound or something...
282                         return true;
283                     }
284                     Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
285                             Uri.fromParts("tel", number, null));
286                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
287                                           | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
288                     startActivity(intent);
289                     finish();
290                     return true;
291                 }
292             }
293         }
294         return super.onKeyDown(keyCode, event);
295     }
296 }