android4.0联系人添加的源码解析


当我们从联系人界面点击添加联系人的图标时,实际上,它是通过隐式的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 怎么来操作,网上有很多列子。






小弟第一次发技术博客,可能从格式和内容中有很多不对或不妥的地方,还望各位指点。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值