From e727f18cf2649d07a89aba19ecefed93c9d0b305 Mon Sep 17 00:00:00 2001 From: Evan Millar Date: Thu, 27 Aug 2009 11:15:55 -0700 Subject: [PATCH] Add the FasttrackBadgeWidget. This widget is an extension of ImageView that takes care of the standard fasttrack badging and on-click behavior. It should be used in any applications that display contact photos. This view's name will have to be changed before release, and will be kept private until the name change is made. At that point the view will be made public api. Change-Id: I4704e0e979466929ad7b2ef11911681a5028b4a7 --- core/java/android/widget/FasttrackBadgeWidget.java | 253 +++++++++++++++++++++ ...middle.xml => fasttrack_badge_middle_large.xml} | 4 +- .../fasttrack_badge_middle_large_normal.9.png | Bin 0 -> 612 bytes .../fasttrack_badge_middle_large_pressed.9.png | Bin 0 -> 834 bytes .../drawable/fasttrack_badge_middle_normal.9.png | Bin 606 -> 0 bytes .../drawable/fasttrack_badge_middle_pressed.9.png | Bin 818 -> 0 bytes core/res/res/layout/contact_header.xml | 6 +- core/res/res/values/attrs.xml | 16 ++ core/res/res/values/styles.xml | 20 ++ core/res/res/values/themes.xml | 3 + 10 files changed, 297 insertions(+), 5 deletions(-) create mode 100644 core/java/android/widget/FasttrackBadgeWidget.java rename core/res/res/drawable/{fasttrack_badge_middle.xml => fasttrack_badge_middle_large.xml} (84%) create mode 100644 core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png create mode 100644 core/res/res/drawable/fasttrack_badge_middle_large_pressed.9.png delete mode 100644 core/res/res/drawable/fasttrack_badge_middle_normal.9.png delete mode 100644 core/res/res/drawable/fasttrack_badge_middle_pressed.9.png diff --git a/core/java/android/widget/FasttrackBadgeWidget.java b/core/java/android/widget/FasttrackBadgeWidget.java new file mode 100644 index 000000000000..22ca5fd7856a --- /dev/null +++ b/core/java/android/widget/FasttrackBadgeWidget.java @@ -0,0 +1,253 @@ +/* + * 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.Rect; +import android.net.Uri; +import android.provider.ContactsContract.Contacts; +import android.provider.ContactsContract.Intents; +import android.provider.ContactsContract.PhoneLookup; +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 android.widget.ImageView; + +/** + * Widget used to show an image with the standard fasttrack badge + * and on-click behavior. + * + * @hide + */ +public class FasttrackBadgeWidget extends ImageView implements OnClickListener { + + private Uri mContactUri; + private String mContactEmail; + private String mContactPhone; + private int mMode; + private QueryHandler mQueryHandler; + + 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 String[] EMAIL_LOOKUP_PROJECTION = new String[] { + RawContacts.CONTACT_ID, + Contacts.LOOKUP_KEY, + }; + static int EMAIL_ID_COLUMN_INDEX = 0; + static int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1; + + static final String[] PHONE_LOOKUP_PROJECTION = new String[] { + PhoneLookup._ID, + PhoneLookup.LOOKUP_KEY, + }; + static int PHONE_ID_COLUMN_INDEX = 0; + static int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1; + + + + public FasttrackBadgeWidget(Context context) { + this(context, null); + } + + public FasttrackBadgeWidget(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public FasttrackBadgeWidget(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = + context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.FasttrackBadgeWidget, defStyle, 0); + + mMode = a.getInt(com.android.internal.R.styleable.FasttrackBadgeWidget_fasttrackWindowSize, + Intents.MODE_MEDIUM); + + a.recycle(); + + init(); + } + + private void init() { + mQueryHandler = new QueryHandler(mContext.getContentResolver()); + setOnClickListener(this); + } + + /** + * Assign the contact uri that this fasttrack badge should be associated with. + * Note that this is only used for displaying the fasttrack window and won't + * bind the contact's photo for you. + * + * @param conatctUri Either a {Contacts.CONTENT_URI} or {Contacts.CONTENT_LOOKUP_URI} + * style URI. + */ + public void assignContactUri(Uri contactUri) { + mContactUri = contactUri; + } + + /** + * 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); + } + } + + /** + * 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); + } + } + + /** + * Set the fasttrack window mode. Options are {@link Intents.MODE_SMALL}, + * {@link Intents.MODE_MEDIUM}, {@link Intents.MODE_LARGE}. + * @param size + */ + public void setMode(int size) { + mMode = size; + } + + public void onClick(View v) { + final Rect target = getTargetRect(v); + + if (mContactUri != null) { + trigger(mContactUri, target); + } else if (mContactEmail != null) { + mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, target, + 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, target, + 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 contactUri, Rect target) { + Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, contactUri); + intent.putExtra(Intents.EXTRA_TARGET_RECT, target); + intent.putExtra(Intents.EXTRA_MODE, mMode); + mContext.startActivity(intent); + } + + private Rect getTargetRect(View anchor) { + final int[] location = new int[2]; + anchor.getLocationOnScreen(location); + + final Rect rect = new Rect(); + rect.left = location[0]; + rect.top = location[1]; + rect.right = rect.left + anchor.getWidth(); + rect.bottom = rect.top + anchor.getHeight(); + return rect; + } + + private class QueryHandler extends AsyncQueryHandler { + + public QueryHandler(ContentResolver cr) { + super(cr); + } + + @Override + protected void onQueryComplete(int token, Object cookie, Cursor cursor) { + Uri contactUri = null; + boolean trigger = false; + + try{ + switch(token) { + case TOKEN_PHONE_LOOKUP_AND_TRIGGER: + trigger = true; + 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); + contactUri = Contacts.getLookupUri(contactId, lookupKey); + } + break; + } + case TOKEN_EMAIL_LOOKUP_AND_TRIGGER: + trigger = true; + 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); + contactUri = Contacts.getLookupUri(contactId, lookupKey); + } + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + if (contactUri != null) { + mContactUri = contactUri; + if (trigger && cookie != null) { + trigger(contactUri, (Rect) cookie); + } + } + } + } +} diff --git a/core/res/res/drawable/fasttrack_badge_middle.xml b/core/res/res/drawable/fasttrack_badge_middle_large.xml similarity index 84% rename from core/res/res/drawable/fasttrack_badge_middle.xml rename to core/res/res/drawable/fasttrack_badge_middle_large.xml index 6df230aaf053..dd591bd7819b 100644 --- a/core/res/res/drawable/fasttrack_badge_middle.xml +++ b/core/res/res/drawable/fasttrack_badge_middle_large.xml @@ -19,10 +19,10 @@ android:state_focused="false" android:state_selected="false" android:state_pressed="false" - android:drawable="@drawable/fasttrack_badge_middle_normal" /> + android:drawable="@drawable/fasttrack_badge_middle_large_normal" /> + android:drawable="@drawable/fasttrack_badge_middle_large_pressed" /> \ No newline at end of file diff --git a/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png b/core/res/res/drawable/fasttrack_badge_middle_large_normal.9.png new file mode 100644 index 0000000000000000000000000000000000000000..ca275cdd37d2c3f7fc4568737e23ff3f3cfe658d GIT binary patch literal 612 zcmV-q0-ODbP)ulgE*E7;?hmJw1QZ0kzzl{U}>rtdl!t@ zpqq&b_lNVnyomSX-rWWB*l0B3W{EKdw?>RxpyvH1taEq=Cp=tBVB27uoHP0bdjo3& zgKmI$Jf6L5HhU$@@`c;&4mv^6@Ap5N&E_rmz0owSg^}RAUhj^gD3?w_pwJikMBjM5 zfgh@>GM?xC7@bb1V>?7R95zPuiM}TwC^KnsG{0zLLlp# zBeUw9a)dw#g!%~e5dt9)J3w?@pMaQi+8P2OkhKD#haQ0t2vrS%5D1ko{RyWWSvCkB zQNS2mItU*2fsRe*fk41<5M)^GH%7}4KMi6vS(dp*qp{Gr)&7A5gF&Y2`nQ#`TrMws zJ}vP153N=!S1Oh64Uk%`b`p=rhnY;~P7s8U z6A**JpqtC(&a2fbAB{#UY`jmQLZNU}EEabmGH0SF9=cqvEjs{)!{Jx2*L#ATDJ7H1 z*HkL?2+QwmDq#-l_42n=(3O&C70000dcu?ofnz+#F9Y@0Az01`3{XE=)tq$WkqK$LR*Q66T~hMN?kE&cp=K( zPdv6}%>hD98vv!@k>P>?d$OJh3&2Sey^H}3XR-J)GM63rV`M&FqhN&i0`XF{0N03q zI=WETM2RG3d>)x+1Y$-G1R8oS@dXlj z9sv&b8a`JIjq`|4j4W!e;b!;c*EKYDO`J!#-+kjxPF{c1#IA`G+MgVr7kOsoh7p04 zD7XMJU+h~}NaP?G27X-g+jkdST>j~Ly&$disBX*i^Zb&ZPed5nM_>))3ATEQ3I-Z zcR^M2@b7&>?1@S#OE&isugc}Jg~6(Xce~xIl}g3X?kzu+&D{)4$3R)hm72jF*Y?>E z(5@uISU9|ud)U9#>2!orsnjO3y8)SIvw3;v#e@8{v#FcMW&KhT^rMsk3FKTroH(3- z_+xu4zIpj^^jy7h|8uQYdyT4X;<==7q1Wr3Z!{XicDp^*G|dcSvE*_&0oj-8_4-nw zPYq zLJL9LrMOsdkk)Nixm3UiLnh3G`(nX)E7Es)&{{MwgvgAlbkfqfcO}X z7){NeAa+$vQ$s;0h#iQkss@Pe)6`H9PZukWo+wuOTSIGvrsm&u4XqIhLJvk1go4n6 z5e0Dz1g{oh++R8fUebf@>A|DXsOuoe;9q8^m`%Ih$R&jmE-#vqq!QRW_T|vZDQ8({8s9a=F~JR4QF?92avV6^fz^ zDwWDntJU&lGMOfs*G8;XtL@h7_0425c^D3dcUYEPbpim=@g~diEu`u)pU*!Q3WaN! zekP_O-R^WcTh(e+ZZ?}ruh(N2cSdSVhG|J+7lT$D%E~9` s6(oTM`XsSy+xbh*(f5XR?puHX03H&_6Qo|O7ytkO07*qoM6N<$g3ad&`~Uy| diff --git a/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png b/core/res/res/drawable/fasttrack_badge_middle_pressed.9.png deleted file mode 100644 index ded95f699167db8848dc89431b93e1ef787df617..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 818 zcmV-21I_%2P)L;IxF!$+BG&{P74?KI86uFq6 z-5uY|CY!yOI}mm^d$0qKEc1qW-+u3BHuDH$3}y{N2&xzXAICv^at&WV@i~if3Ppu* zMjzz|ih&qxna`-IdS>n3x%>Ika5qW%I#>e$!4&h^HsQ1YND1gMb!YuMJiGq%>l0LL z2q39cDzlt{6~*dkY}f^`h7JhkGY}4fgOLGHhKj|B z%Qs=oa2ERVEI?3UgWIyG@<-Dg7YHEvd|v+9lh;8>0v94B#KryVH>iFpihr(WglrBh=22Fbq40Sj}d$6xmlQmC8acm-~oQA6(aXMjGV;$_bQY wKzY+c`GxWcWy|GkR&z1vA~&nS_*Z}d0NgIG + android:background="@drawable/fasttrack_badge_middle_large"/> + + + + + + + + @@ -2197,6 +2205,14 @@ + + + + + + + + diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index a2ceb8f38446..fae612c8bada 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -517,6 +517,26 @@ 2.75 + + + + + + + + diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 3b9590d24652..4f76c5605349 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -176,6 +176,9 @@ @android:style/Widget.TextView.SpinnerItem @android:style/TextAppearance.Widget.DropDownHint @android:style/Widget.KeyboardView + @android:style/Widget.FasttrackBadgeWidget.WindowSmall + @android:style/Widget.FasttrackBadgeWidget.WindowMedium + @android:style/Widget.FasttrackBadgeWidget.WindowLarge @android:style/Preference.PreferenceScreen -- 2.11.0