PageRenderTime 50ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/core/java/android/widget/QuickContactBadge.java

https://github.com/Kali-/android_frameworks_base
Java | 302 lines | 202 code | 37 blank | 63 comment | 48 complexity | 9e4387e59d7f8b74823064a8a5639543 MD5 | raw file
  1. /*
  2. * Copyright (C) 2009 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package android.widget;
  17. import com.android.internal.R;
  18. import android.content.AsyncQueryHandler;
  19. import android.content.ContentResolver;
  20. import android.content.Context;
  21. import android.content.Intent;
  22. import android.content.res.TypedArray;
  23. import android.database.Cursor;
  24. import android.graphics.Canvas;
  25. import android.graphics.drawable.Drawable;
  26. import android.net.Uri;
  27. import android.provider.ContactsContract.CommonDataKinds.Email;
  28. import android.provider.ContactsContract.Contacts;
  29. import android.provider.ContactsContract.Intents;
  30. import android.provider.ContactsContract.PhoneLookup;
  31. import android.provider.ContactsContract.QuickContact;
  32. import android.provider.ContactsContract.RawContacts;
  33. import android.util.AttributeSet;
  34. import android.view.View;
  35. import android.view.View.OnClickListener;
  36. /**
  37. * Widget used to show an image with the standard QuickContact badge
  38. * and on-click behavior.
  39. */
  40. public class QuickContactBadge extends ImageView implements OnClickListener {
  41. private Uri mContactUri;
  42. private String mContactEmail;
  43. private String mContactPhone;
  44. private Drawable mOverlay;
  45. private QueryHandler mQueryHandler;
  46. private Drawable mDefaultAvatar;
  47. protected String[] mExcludeMimes = null;
  48. static final private int TOKEN_EMAIL_LOOKUP = 0;
  49. static final private int TOKEN_PHONE_LOOKUP = 1;
  50. static final private int TOKEN_EMAIL_LOOKUP_AND_TRIGGER = 2;
  51. static final private int TOKEN_PHONE_LOOKUP_AND_TRIGGER = 3;
  52. static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
  53. RawContacts.CONTACT_ID,
  54. Contacts.LOOKUP_KEY,
  55. };
  56. static final int EMAIL_ID_COLUMN_INDEX = 0;
  57. static final int EMAIL_LOOKUP_STRING_COLUMN_INDEX = 1;
  58. static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
  59. PhoneLookup._ID,
  60. PhoneLookup.LOOKUP_KEY,
  61. };
  62. static final int PHONE_ID_COLUMN_INDEX = 0;
  63. static final int PHONE_LOOKUP_STRING_COLUMN_INDEX = 1;
  64. public QuickContactBadge(Context context) {
  65. this(context, null);
  66. }
  67. public QuickContactBadge(Context context, AttributeSet attrs) {
  68. this(context, attrs, 0);
  69. }
  70. public QuickContactBadge(Context context, AttributeSet attrs, int defStyle) {
  71. super(context, attrs, defStyle);
  72. TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
  73. mOverlay = styledAttributes.getDrawable(
  74. com.android.internal.R.styleable.Theme_quickContactBadgeOverlay);
  75. styledAttributes.recycle();
  76. mQueryHandler = new QueryHandler(mContext.getContentResolver());
  77. setOnClickListener(this);
  78. }
  79. @Override
  80. protected void drawableStateChanged() {
  81. super.drawableStateChanged();
  82. if (mOverlay != null && mOverlay.isStateful()) {
  83. mOverlay.setState(getDrawableState());
  84. invalidate();
  85. }
  86. }
  87. /** This call has no effect anymore, as there is only one QuickContact mode */
  88. @SuppressWarnings("unused")
  89. public void setMode(int size) {
  90. }
  91. @Override
  92. protected void onDraw(Canvas canvas) {
  93. super.onDraw(canvas);
  94. if (!isEnabled()) {
  95. // not clickable? don't show triangle
  96. return;
  97. }
  98. if (mOverlay == null || mOverlay.getIntrinsicWidth() == 0 ||
  99. mOverlay.getIntrinsicHeight() == 0) {
  100. // nothing to draw
  101. return;
  102. }
  103. mOverlay.setBounds(0, 0, getWidth(), getHeight());
  104. if (mPaddingTop == 0 && mPaddingLeft == 0) {
  105. mOverlay.draw(canvas);
  106. } else {
  107. int saveCount = canvas.getSaveCount();
  108. canvas.save();
  109. canvas.translate(mPaddingLeft, mPaddingTop);
  110. mOverlay.draw(canvas);
  111. canvas.restoreToCount(saveCount);
  112. }
  113. }
  114. /** True if a contact, an email address or a phone number has been assigned */
  115. private boolean isAssigned() {
  116. return mContactUri != null || mContactEmail != null || mContactPhone != null;
  117. }
  118. /**
  119. * Resets the contact photo to the default state.
  120. */
  121. public void setImageToDefault() {
  122. if (mDefaultAvatar == null) {
  123. mDefaultAvatar = getResources().getDrawable(R.drawable.ic_contact_picture);
  124. }
  125. setImageDrawable(mDefaultAvatar);
  126. }
  127. /**
  128. * Assign the contact uri that this QuickContactBadge should be associated
  129. * with. Note that this is only used for displaying the QuickContact window and
  130. * won't bind the contact's photo for you. Call {@link #setImageDrawable(Drawable)} to set the
  131. * photo.
  132. *
  133. * @param contactUri Either a {@link Contacts#CONTENT_URI} or
  134. * {@link Contacts#CONTENT_LOOKUP_URI} style URI.
  135. */
  136. public void assignContactUri(Uri contactUri) {
  137. mContactUri = contactUri;
  138. mContactEmail = null;
  139. mContactPhone = null;
  140. onContactUriChanged();
  141. }
  142. /**
  143. * Assign a contact based on an email address. This should only be used when
  144. * the contact's URI is not available, as an extra query will have to be
  145. * performed to lookup the URI based on the email.
  146. *
  147. * @param emailAddress The email address of the contact.
  148. * @param lazyLookup If this is true, the lookup query will not be performed
  149. * until this view is clicked.
  150. */
  151. public void assignContactFromEmail(String emailAddress, boolean lazyLookup) {
  152. mContactEmail = emailAddress;
  153. if (!lazyLookup) {
  154. mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, null,
  155. Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
  156. EMAIL_LOOKUP_PROJECTION, null, null, null);
  157. } else {
  158. mContactUri = null;
  159. onContactUriChanged();
  160. }
  161. }
  162. /**
  163. * Assign a contact based on a phone number. This should only be used when
  164. * the contact's URI is not available, as an extra query will have to be
  165. * performed to lookup the URI based on the phone number.
  166. *
  167. * @param phoneNumber The phone number of the contact.
  168. * @param lazyLookup If this is true, the lookup query will not be performed
  169. * until this view is clicked.
  170. */
  171. public void assignContactFromPhone(String phoneNumber, boolean lazyLookup) {
  172. mContactPhone = phoneNumber;
  173. if (!lazyLookup) {
  174. mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, null,
  175. Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
  176. PHONE_LOOKUP_PROJECTION, null, null, null);
  177. } else {
  178. mContactUri = null;
  179. onContactUriChanged();
  180. }
  181. }
  182. private void onContactUriChanged() {
  183. setEnabled(isAssigned());
  184. }
  185. @Override
  186. public void onClick(View v) {
  187. if (mContactUri != null) {
  188. QuickContact.showQuickContact(getContext(), QuickContactBadge.this, mContactUri,
  189. QuickContact.MODE_LARGE, mExcludeMimes);
  190. } else if (mContactEmail != null) {
  191. mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP_AND_TRIGGER, mContactEmail,
  192. Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(mContactEmail)),
  193. EMAIL_LOOKUP_PROJECTION, null, null, null);
  194. } else if (mContactPhone != null) {
  195. mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP_AND_TRIGGER, mContactPhone,
  196. Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, mContactPhone),
  197. PHONE_LOOKUP_PROJECTION, null, null, null);
  198. } else {
  199. // If a contact hasn't been assigned, don't react to click.
  200. return;
  201. }
  202. }
  203. /**
  204. * Set a list of specific MIME-types to exclude and not display. For
  205. * example, this can be used to hide the {@link Contacts#CONTENT_ITEM_TYPE}
  206. * profile icon.
  207. */
  208. public void setExcludeMimes(String[] excludeMimes) {
  209. mExcludeMimes = excludeMimes;
  210. }
  211. private class QueryHandler extends AsyncQueryHandler {
  212. public QueryHandler(ContentResolver cr) {
  213. super(cr);
  214. }
  215. @Override
  216. protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
  217. Uri lookupUri = null;
  218. Uri createUri = null;
  219. boolean trigger = false;
  220. try {
  221. switch(token) {
  222. case TOKEN_PHONE_LOOKUP_AND_TRIGGER:
  223. trigger = true;
  224. createUri = Uri.fromParts("tel", (String)cookie, null);
  225. //$FALL-THROUGH$
  226. case TOKEN_PHONE_LOOKUP: {
  227. if (cursor != null && cursor.moveToFirst()) {
  228. long contactId = cursor.getLong(PHONE_ID_COLUMN_INDEX);
  229. String lookupKey = cursor.getString(PHONE_LOOKUP_STRING_COLUMN_INDEX);
  230. lookupUri = Contacts.getLookupUri(contactId, lookupKey);
  231. }
  232. break;
  233. }
  234. case TOKEN_EMAIL_LOOKUP_AND_TRIGGER:
  235. trigger = true;
  236. createUri = Uri.fromParts("mailto", (String)cookie, null);
  237. //$FALL-THROUGH$
  238. case TOKEN_EMAIL_LOOKUP: {
  239. if (cursor != null && cursor.moveToFirst()) {
  240. long contactId = cursor.getLong(EMAIL_ID_COLUMN_INDEX);
  241. String lookupKey = cursor.getString(EMAIL_LOOKUP_STRING_COLUMN_INDEX);
  242. lookupUri = Contacts.getLookupUri(contactId, lookupKey);
  243. }
  244. break;
  245. }
  246. }
  247. } finally {
  248. if (cursor != null) {
  249. cursor.close();
  250. }
  251. }
  252. mContactUri = lookupUri;
  253. onContactUriChanged();
  254. if (trigger && lookupUri != null) {
  255. // Found contact, so trigger QuickContact
  256. QuickContact.showQuickContact(getContext(), QuickContactBadge.this, lookupUri,
  257. QuickContact.MODE_LARGE, mExcludeMimes);
  258. } else if (createUri != null) {
  259. // Prompt user to add this person to contacts
  260. final Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, createUri);
  261. getContext().startActivity(intent);
  262. }
  263. }
  264. }
  265. }