当我们从联系人界面点击添加联系人的图标时,实际上,它是通过隐式的Intent来启动添加联系人的界面。
在PeopleActivity.java的onOptionsTtemSelected方法中
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home: {
// The home icon on the action bar is pressed
if (mActionBarAdapter.isUpShowing()) {
// "UP" icon press -- should be treated as "back".
onBackPressed();
}
return true;
}
case R.id.menu_settings: {
final Intent intent = new Intent(this, ContactsPreferenceActivity.class);
// as there is only one section right now, make sure it is selected
// on small screens, this also hides the section selector
// Due to b/5045558, this code unfortunately only works properly on phones
boolean settingsAreMultiPane = getResources().getBoolean(
com.android.internal.R.bool.preferences_prefer_dual_pane);
if (!settingsAreMultiPane) {
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT,
DisplayOptionsPreferenceFragment.class.getName());
intent.putExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT_TITLE,
R.string.preference_displayOptions);
}
startActivity(intent);
return true;
}
case R.id.menu_contacts_filter: {
AccountFilterUtil.startAccountFilterActivityForResult(this,
SUBACTIVITY_ACCOUNT_FILTER);
return true;
}
case R.id.menu_search: {
onSearchRequested();
return true;
}
case R.id.menu_add_favorite: {
final Intent intent=new Intent(UI.MULTI_PICK_ACTION);
intent.setData(Contacts.CONTENT_URI);
intent.putExtra("setMulitStarred",true);
startActivityForResult(intent,SUBACTIVITY_SET_STARRED);
return true;
}
case R.id.menu_add_contact: {
final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
// On 2-pane UI, we can let the editor activity finish itself and return
// to this activity to display the new contact.
if (PhoneCapabilityTester.isUsingTwoPanes(this)) {
intent.putExtra(
ContactEditorActivity.INTENT_KEY_FINISH_ACTIVITY_ON_SAVE_COMPLETED, true);
startActivityForResult(intent, SUBACTIVITY_NEW_CONTACT);
} else {
// Otherwise, on 1-pane UI, we need the editor to launch the view contact
// intent itself.
startActivity(intent);
}
return true;
}
case R.id.menu_add_group: {
createNewGroupWithAccountDisambiguation();
return true;
}
case R.id.menu_import_export: {
ImportExportDialogFragment.show(getFragmentManager(),this);
return true;
}
case R.id.menu_batch_delete: {
final Intent intent=new Intent(UI.MULTI_PICK_ACTION);
intent.setData(Contacts.CONTENT_URI);
intent.putExtra("mode", SUBACTIVITY_BATCH_DELETE);
startActivityForResult(intent,SUBACTIVITY_BATCH_DELETE);
return true;
}
case R.id.menu_accounts: {
final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
ContactsContract.AUTHORITY
});
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(intent);
return true;
}
case R.id.menu_delete_group: {
if (mGroupsFragment.getAdapter().getCount() <=0){
AlertDialog dialog = new AlertDialog.Builder(PeopleActivity.this)
.setTitle(R.string.menu_delete_group)
.setMessage(R.string.no_group_can_delete)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.show();
return true;
}else{
final Intent intent=new Intent(this, DeleteGroupActivity.class);
startActivity(intent);
return true;
}
}
}
return false;
}
很容易找到是
R.id.menu_add_contact的事件,而Intent.ACTION_INSERT为
在清单文件中只有ContactEditorActivity.java与之匹配。进入该类,首先在它的onCreate方法中其实是加载了一个Fragment,如下:
setContentView(R.layout.contact_editor_activity);该XML文件内容
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment class="com.android.contacts.editor.ContactEditorFragment"
android:id="@+id/contact_editor_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
进入ContactEditorFragment.java文件,继续进入其onOptionsItemSelected方法
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_done:
return save(SaveMode.CLOSE);
case R.id.menu_discard:
return revert();
case R.id.menu_split:
return doSplitContactAction();
case R.id.menu_join:
return doJoinContactAction();
}
return false;
}
当我们编辑好了联系人的信息后,点击“完成”按钮时,就触发了R.id.menu_done的事件,执行save方法,查看save方法。
public boolean save(int saveMode) {
.......
// Save contact
Intent intent = ContactSaveService.createSaveContactIntent(getActivity(), mState,
SAVE_MODE_EXTRA_KEY, saveMode, isEditingUserProfile(),
getActivity().getClass(), ContactEditorActivity.ACTION_SAVE_COMPLETED);
getActivity().startService(intent);
return true;
}
其实在save方法中,里面有各种提示,当我们保存的信息由误的时候,会通过Toast来告诉用户,最后确认信息无误时save方法最后启动了一个服务来进行保存
进入服务ContactSaveService.java类中,该类继承了IntentService,所以进入onHandleIntent()方法中, 该方法也是根据不同的ACTION来执行不同的操作
protected void onHandleIntent(Intent intent) {
try {
String action = intent.getAction();
if (ACTION_NEW_RAW_CONTACT.equals(action)) {
createRawContact(intent);
} else if (ACTION_SAVE_CONTACT.equals(action)) {
saveContact(intent);
} else if (ACTION_CREATE_GROUP.equals(action)) {
createGroup(intent);
} else if (ACTION_RENAME_GROUP.equals(action)) {
renameGroup(intent);
根据需求,进入的是saveContact(intent)的方法,继续跟进
private void saveContact(Intent intent) {
EntityDeltaList state = intent.getParcelableExtra(EXTRA_CONTACT_STATE);
Intent callbackIntent = intent.getParcelableExtra(EXTRA_CALLBACK_INTENT);
boolean isProfile = intent.getBooleanExtra(EXTRA_SAVE_IS_PROFILE, false);
// Trim any empty fields, and RawContacts, before persisting
final AccountTypeManager accountTypes = AccountTypeManager.getInstance(this);
EntityModifier.trimEmpty(state, accountTypes);
Uri lookupUri = null;
final ContentResolver resolver = getContentResolver();
// Attempt to persist changes
int tries = 0;
while (tries++ < PERSIST_TRIES) {
try {
// Build operations and try applying
final ArrayList<ContentProviderOperation> diff = state.buildDiff();
if (DEBUG) {
Log.v(TAG, "Content Provider Operations:");
for (ContentProviderOperation operation : diff) {
Log.v(TAG, operation.toString());
}
}
ContentProviderResult[] results = null;
if (!diff.isEmpty()) {
try {
results = resolver.applyBatch(ContactsContract.AUTHORITY, diff);
在方法的最后results =resolver.applyBatch(ContactsContract.AUTHORITY, diff);进行了对联系人数据的保存。其中diff是一个ArrayList<ContentProviderOperation>的集合,通过log发现diff里面全是联系人的各种信息,如姓名,电话,地址,等等。其实最终还是通过ContentResolver 来操作联系人的数据库表,至于ContentResolver 怎么来操作,网上有很多列子。
小弟第一次发技术博客,可能从格式和内容中有很多不对或不妥的地方,还望各位指点。