从前一篇,我们知道了如何使用了QuikcContactBadge.这一篇我们看QuikcContactBadge是如何实现。开源好处就在于,你可以尽情地了解你想了解。
我们都知道QuickContactBadge是从ImageView继承而来的,我们先来看QuikcContactBadge的源码:
framework\base\core\java\android\widget\QuikcContactBadge.java
/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.widget;import android.content.AsyncQueryHandler;import android.content.ContentResolver;import android.content.Context;import android.content.Intent;import android.content.res.TypedArray;import android.database.Cursor;import android.graphics.drawable.Drawable;import android.net.Uri;import android.provider.ContactsContract.Contacts;import android.provider.ContactsContract.Intents;import android.provider.ContactsContract.PhoneLookup;import android.provider.ContactsContract.QuickContact;import android.provider.ContactsContract.RawContacts;import android.provider.ContactsContract.CommonDataKinds.Email;import android.util.AttributeSet;import android.view.View;import android.view.View.OnClickListener;import com.android.internal.R;/** * Widget used to show an image with the standard QuickContact badge * and on-click behavior. */public class QuickContactBadge extends ImageView implements OnClickListener {    private Uri mContactUri;    private String mContactEmail;    private String mContactPhone;    private int mMode;    private QueryHandler mQueryHandler;    private Drawable mBadgeBackground;    private Drawable mNoBadgeBackground;    private int mSelectedContactsAppTabIndex = -1;    protected String[] mExcludeMimes = null;    static final private int TOKEN_EMAIL_LOOKUP = 0;    static final private int TOKEN_PHONE_LOOKUP = 1;    static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2;    static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3;    static final private int TOKEN_CONTACT_LOOKUP_AND_TRIGGER = 4;    static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {        RawContacts.CONTACT_ID,        Contacts.LOOKUP_KEY,    };    static final int EMAIL_ID_COLUMN_INDEX = 0;    static final int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1;    static final String[] PHONE_LOOKUP_PROJECTION = new String[] {        PhoneLookup._ID,        PhoneLookup.LOOKUP_KEY,    };    static final int PHONE_ID_COLUMN_INDEX = 0;    static final int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1;    static final String[] CONTACT_LOOKUP_PROJECTION = new String[] {        Contacts._ID,        Contacts.LOOKUP_KEY,    };    static final int CONTACT_ID_COLUMN_INDEX = 0;    static final int CONTACT_LOOKUPKEY_COLUMN_INDEX = 1;    public QuickContactBadge(Context context) {        this(context, null);    }    public QuickContactBadge(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public QuickContactBadge(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a =            context.obtainStyledAttributes(attrs,                    com.android.internal.R.styleable.QuickContactBadge, defStyle, 0);        mMode = a.getInt(com.android.internal.R.styleable.QuickContactBadge_quickContactWindowSize,                QuickContact.MODE_MEDIUM);        a.recycle();        init();        mBadgeBackground = getBackground();    }    private void init() {        mQueryHandler = new QueryHandler(mContext.getContentResolver());        setOnClickListener(this);    }    /**     * Set the QuickContact window mode. Options are {@link QuickContact#MODE_SMALL},     * {@link QuickContact#MODE_MEDIUM}, {@link QuickContact#MODE_LARGE}.     * @param size     */    public void setMode(int size) {        mMode = size;    }    /**     * Assign the contact uri that this QuickContactBadge should be associated     * with. Note that this is only used for displaying the QuickContact window and     * won't bind the contact's photo for you.     *     * @param contactUri Either a {@link Contacts#CONTENT_URI} or     *            {@link Contacts#CONTENT_LOOKUP_URI} style URI.     */    public void assignContactUri(Uri contactUri) {        mContactUri = contactUri;        mContactEmail = null;        mContactPhone = null;        onContactUriChanged();    }    /**     * Sets the currently selected tab of the Contacts application. If not set, this is -1     * and therefore does not save a tab selection when a phone call is being made     * @hide     */    public void setSelectedContactsAppTabIndex(int value) {        mSelectedContactsAppTabIndex = value;    }    private void onContactUriChanged() {        if (mContactUri == null && mContactEmail == null && mContactPhone == null) {            if (mNoBadgeBackground == null) {                mNoBadgeBackground = getResources().getDrawable(R.drawable.quickcontact_nobadge);            }            setBackgroundDrawable(mNoBadgeBackground);        } else {            setBackgroundDrawable(mBadgeBackground);        }    }    /**     * Assign a contact based on an email address. This should only be used when     * the contact's URI is not available, as an extra query will have to be     * performed to lookup the URI based on the email.     *     * @param emailAddress The email address of the contact.     * @param lazyLookup If this is true, the lookup query will not be performed     * until this view is clicked.     */    public void assignContactFromEmail(String emailAddress, boolean lazyLookup) {        mContactEmail = emailAddress;        if (!lazyLookup) {            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, null,                    Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),                    EMAIL_LOOKUP_PROJECTION, null, null, null);        } else {            mContactUri = null;            onContactUriChanged();        }    }    /**     * Assign a contact based on a phone number. This should only be used when     * the contact's URI is not available, as an extra query will have to be     * performed to lookup the URI based on the phone number.     *     * @param phoneNumber The phone number of the contact.     * @param lazyLookup If this is true, the lookup query will not be performed     * until this view is clicked.     */    public void assignContactFromPhone(String phoneNumber, boolean lazyLookup) {        mContactPhone = phoneNumber;        if (!lazyLookup) {            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, null,                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),                    PHONE_LOOKUP_PROJECTION, null, null, null);        } else {            mContactUri = null;            onContactUriChanged();        }    }    public void onClick(View v) {        if (mContactUri != null) {            mQueryHandler.startQuery(TOKEN_CONTACT_LOOKUP_AND_TRIGGER, null,                    mContactUri,                    CONTACT_LOOKUP_PROJECTION, null, null, null);        } else if (mContactEmail != null) {            mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, mContactEmail,                    Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),                    EMAIL_LOOKUP_PROJECTION, null, null, null);        } else if (mContactPhone != null) {            mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, mContactPhone,                    Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),                    PHONE_LOOKUP_PROJECTION, null, null, null);        } else {            // If a contact hasn't been assigned, don't react to click.            return;        }    }    /**     * Set a list of specific MIME-types to exclude and not display. For     * example, this can be used to hide the {@link Contacts#CONTENT_ITEM_TYPE}     * profile icon.     */    public void setExcludeMimes(String[] excludeMimes) {        mExcludeMimes = excludeMimes;    }    private void trigger(Uri lookupUri) {        final Intent intent = QuickContact.getQuickContactIntent(getContext(), this, lookupUri,                mMode, mExcludeMimes);        if (mSelectedContactsAppTabIndex != -1) {            intent.putExtra(QuickContact.EXTRA_SELECTED_CONTACTS_APP_TAB_INDEX,                    mSelectedContactsAppTabIndex);        }        getContext().startActivity(intent);    }    private class QueryHandler extends AsyncQueryHandler {        public QueryHandler(ContentResolver cr) {            super(cr);        }        @Override        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {            Uri lookupUri = null;            Uri createUri = null;            boolean trigger = false;            try {                switch(token) {                    case TOKEN_PHONE_LOOKUP_AND_TRIGGER:                        trigger = true;                        createUri = Uri.fromParts("tel", (String)cookie, null);                        //$FALL-THROUGH$                    case TOKEN_PHONE_LOOKUP: {                        if (cursor != null && cursor.moveToFirst()) {                            long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);                            String lookupKey = cursor.getString(PHONE_LOOKUP_STRING_COLUMN_INDEX);                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);                        }                        break;                    }                    case TOKEN_EMAIL_LOOKUP_AND_TRIGGER:                        trigger = true;                        createUri = Uri.fromParts("mailto", (String)cookie, null);                        //$FALL-THROUGH$                    case TOKEN_EMAIL_LOOKUP: {                        if (cursor != null && cursor.moveToFirst()) {                            long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);                            String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);                        }                        break;                    }                    case TOKEN_CONTACT_LOOKUP_AND_TRIGGER: {                        if (cursor != null && cursor.moveToFirst()) {                            long contactId = cursor.getLong(CONTACT_ID_COLUMN_INDEX);                            String lookupKey = cursor.getString(CONTACT_LOOKUPKEY_COLUMN_INDEX);                            lookupUri = Contacts.getLookupUri(contactId, lookupKey);                            trigger = true;                        }                        break;                    }                }            } finally {                if (cursor != null) {                    cursor.close();                }            }            mContactUri = lookupUri;            onContactUriChanged();            if (trigger && lookupUri != null) {                // Found contact, so trigger track                trigger(lookupUri);            } else if (createUri != null) {                // Prompt user to add this person to contacts                final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, createUri);                getContext().startActivity(intent);            }        }    }}

从source code我们可以知道QuickContactBadge已经处理了它的onClick事件。通过AsyncQueryHandler(用这个来查询的好处待会稍后研究^_^)来异步查询Contact的信息,进而做出了不同的处理,// Found contact, so trigger track
trigger(lookupUri);若查询到了已经有这样的Contact就会发出com.android.contacts.action.QUICK_CONTACT这样的Intent去启动我们看到的Contact tools:call.message,web...而处理这个Intent的Acticity是位于Contact里面的QuickContactActivity.java(大家可以在这里继续研究Contact tools的UI是怎么形成与实现的)。那还有另外一种情况就是这个Contact还没有保存在手机里,那么就会
inal Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, createUri);
getContext().startActivity(intent);启动是否要保存这个contact的Activity.发出com.android.contacts.action.SHOW_OR_CREATE_CONTACT这个Intent,而处理这个Activity也是在Contact这个源码里面的ShowOrCreateActivity。




更多相关文章

  1. Android轻量级ORM框架ActiveAndroid入门教程
  2. Android即时通讯服务,类似QQ的聊天工具,源码分享
  3. Android(安卓)沉浸式状态栏 一体化状态栏实现
  4. Android(安卓)开发艺术探索读书笔记 9 -- 四大组件的工作流程
  5. android源码解析之(十四)-->Activity启动流程
  6. 【Android开发】完善搜索功能-添加最近查询字段
  7. [Android]开源中国源码分析——Activity
  8. android 源码环境 启动模拟器
  9. Android客制化adb shell进去后显示shell@xxx的标识

随机推荐

  1. RxJava RxAndroid(安卓)资源收录
  2. Android Power Management
  3. Android 的相关文件类型
  4. 实战 QQ demo (学习 android 先来个QQ)
  5. Android(安卓)P系统修改状态栏记录
  6. Android中的WebView详解
  7. Visual Studio跨平台开发实战(4) - Xamar
  8. Android——textView
  9. Android系统编译系统分析大全(一)
  10. Unity调用Android配置方法