Android的SIM卡名片導入流程
文章出處:http://www.limodev.cn/blog
作者聯系方式:李先靜 <xianjimli@gmail.com>
Android的SIM卡名片導入流程
ContactsListActivity
在ContactsListActivity裏創建了一個名片導入的菜單。
// SIM import Intent importIntent = new Intent(Intent.ACTION_VIEW); importIntent.setType("vnd.android.cursor.item/sim-contact"); importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts"); menu.add(0, 0, 0, R.string.importFromSim) .setIcon(R.drawable.ic_menu_import_contact) .setIntent(importIntent);
很明顯可以看出名片應用程序只是啟動了電話裏面的SimContacts:
ADNList
SimContacts是從ADNList繼承過來的,有必要先看下ADNList。它是一個ListActivity,用來顯示SIM卡中的名片。
先查詢SIM卡中的名片:
protected Uri resolveIntent() { Intent intent = getIntent(); if (intent.getData() == null) { intent.setData(Uri.parse("content://sim/adn")); } return intent.getData(); } private void query() { Uri uri = resolveIntent(); if (DBG) log("query: starting an async query"); mQueryHandler.startQuery(QUERY_TOKEN, null, uri, COLUMN_NAMES, null, null, null); displayProgress(true); }
mQueryHandler是AsyncQueryHandler的子類,當查詢完成時,會調用onQueryComplete去更新SIM卡名片列表和進度狀態:
protected void onQueryComplete(int token, Object cookie, Cursor c) { if (DBG) log("onQueryComplete: cursor.count=" + c.getCount()); mCursor = c; setAdapter(); displayProgress(false); }
SimContacts
再回到SimContacts,從SIM卡裏查詢名片是ADNList做的,SimContacts則主要是負責導入SIM卡名片到手機名片裏:
選擇某條名片導入,會給用戶編輯的機會,由名片應用程序來負責:
private void importOne(int position) { if (mCursor.moveToPosition(position)) { String name = mCursor.getString(NAME_COLUMN); String number = mCursor.getString(NUMBER_COLUMN); Object[] parsed = new Object[2]; Uri personUrl = parseName(name, parsed); Intent intent; if (personUrl == null) { // Add a new contact intent = new Intent(Contacts.Intents.Insert.ACTION, Contacts.People.CONTENT_URI); intent.putExtra(Contacts.Intents.Insert.NAME, (String)parsed[0]); intent.putExtra(Contacts.Intents.Insert.PHONE, number); intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, ((Integer)parsed[1]).intValue()); } else { // Add the number to an existing contact intent = new Intent(Intent.ACTION_EDIT, personUrl); } startActivity(intent); } }
如果是全部導入,則直接通過ContentResolver插入進去,這裏由一個獨立的線程負責:
public void run() { ContentValues map = new ContentValues(); ContentResolver cr = getContentResolver(); Object[] parsed = new Object[2]; mCursor.moveToPosition(-1); while (!mCanceled && mCursor.moveToNext()) { String name = mCursor.getString(0); String number = mCursor.getString(1); Uri personUrl = parseName(name, parsed); if (personUrl == null) { map.clear(); map.put(Contacts.People.NAME, (String) parsed[0]); personUrl = People.createPersonInMyContactsGroup(cr, map); if (personUrl == null) { Log.e(TAG, "Error inserting person " + map); continue; } } map.clear(); map.put(Contacts.People.Phones.NUMBER, number); map.put(Contacts.People.Phones.TYPE, (Integer) parsed[1]); Uri numberUrl = cr.insert( Uri.withAppendedPath(personUrl, Contacts.People.Phones.CONTENT_DIRECTORY), map); mProgressDialog.incrementProgressBy(1); if (numberUrl == null) { Log.e(TAG, "Error inserting phone " + map + " for person " + personUrl + ", removing person"); continue; } } mProgressDialog.dismiss(); finish(); }