QuickContactBadge如何实现
16lz
2021-01-26
从前一篇,我们知道了如何使用了QuikcContactBadge.这一篇我们看QuikcContactBadge是如何实现。开源好处就在于,你可以尽情地了解你想了解。
我们都知道QuickContactBadge是从ImageView继承而来的,我们先来看QuikcContactBadge的源码:
framework\base\core\java\android\widget\QuikcContactBadge.java
从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。
我们都知道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。
更多相关文章
- Android轻量级ORM框架ActiveAndroid入门教程
- Android即时通讯服务,类似QQ的聊天工具,源码分享
- Android(安卓)沉浸式状态栏 一体化状态栏实现
- Android(安卓)开发艺术探索读书笔记 9 -- 四大组件的工作流程
- android源码解析之(十四)-->Activity启动流程
- 【Android开发】完善搜索功能-添加最近查询字段
- [Android]开源中国源码分析——Activity
- android 源码环境 启动模拟器
- Android客制化adb shell进去后显示shell@xxx的标识