aboutsummaryrefslogtreecommitdiff
path: root/LoaderApp/src
diff options
context:
space:
mode:
authorJeff Hamilton <jham@android.com>2010-06-28 16:56:44 -0500
committerJeff Hamilton <jham@android.com>2010-06-28 16:57:14 -0500
commite15efb9074c5497aaca00d960c310fff07817925 (patch)
tree9dc2616e575517ee8082a02154f3ae02cb4a8163 /LoaderApp/src
parentad76b0c6bb47c238f524e4629cc8b7ec4dc21d55 (diff)
downloadexperimental-e15efb9074c5497aaca00d960c310fff07817925.tar.gz
Fix the build by copying the now defunct ContactHeaderWidget into the app.
Change-Id: I76ae8ede2cbb95acbfdad0441486888eaeadd1a0
Diffstat (limited to 'LoaderApp/src')
-rw-r--r--LoaderApp/src/com/android/loaderapp/ContactHeaderWidget.java686
-rw-r--r--LoaderApp/src/com/android/loaderapp/fragments/ContactFragment.java3
2 files changed, 687 insertions, 2 deletions
diff --git a/LoaderApp/src/com/android/loaderapp/ContactHeaderWidget.java b/LoaderApp/src/com/android/loaderapp/ContactHeaderWidget.java
new file mode 100644
index 0000000..e6824a2
--- /dev/null
+++ b/LoaderApp/src/com/android/loaderapp/ContactHeaderWidget.java
@@ -0,0 +1,686 @@
+/*
+ * 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 com.android.loaderapp;
+
+import android.Manifest;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.StatusUpdates;
+import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.Photo;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.QuickContactBadge;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * Header used across system for displaying a title bar with contact info. You
+ * can bind specific values on the header, or use helper methods like
+ * {@link #bindFromContactLookupUri(Uri)} to populate asynchronously.
+ * <p>
+ * The parent must request the {@link Manifest.permission#READ_CONTACTS}
+ * permission to access contact data.
+ */
+public class ContactHeaderWidget extends FrameLayout implements View.OnClickListener {
+
+ private static final String TAG = "ContactHeaderWidget";
+
+ private TextView mDisplayNameView;
+ private View mAggregateBadge;
+ private TextView mPhoneticNameView;
+ private CheckBox mStarredView;
+ private QuickContactBadge mPhotoView;
+ private ImageView mPresenceView;
+ private TextView mStatusView;
+ private TextView mStatusAttributionView;
+ private int mNoPhotoResource;
+ private QueryHandler mQueryHandler;
+
+ protected Uri mContactUri;
+
+ protected String[] mExcludeMimes = null;
+
+ protected ContentResolver mContentResolver;
+
+ /**
+ * Interface for callbacks invoked when the user interacts with a header.
+ */
+ public interface ContactHeaderListener {
+ public void onPhotoClick(View view);
+ public void onDisplayNameClick(View view);
+ }
+
+ private ContactHeaderListener mListener;
+
+
+ private interface ContactQuery {
+ //Projection used for the summary info in the header.
+ String[] COLUMNS = new String[] {
+ Contacts._ID,
+ Contacts.LOOKUP_KEY,
+ Contacts.PHOTO_ID,
+ Contacts.DISPLAY_NAME,
+ Contacts.PHONETIC_NAME,
+ Contacts.STARRED,
+ Contacts.CONTACT_PRESENCE,
+ Contacts.CONTACT_STATUS,
+ Contacts.CONTACT_STATUS_TIMESTAMP,
+ Contacts.CONTACT_STATUS_RES_PACKAGE,
+ Contacts.CONTACT_STATUS_LABEL,
+ };
+ int _ID = 0;
+ int LOOKUP_KEY = 1;
+ int PHOTO_ID = 2;
+ int DISPLAY_NAME = 3;
+ int PHONETIC_NAME = 4;
+ //TODO: We need to figure out how we're going to get the phonetic name.
+ //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX
+ int STARRED = 5;
+ int CONTACT_PRESENCE_STATUS = 6;
+ int CONTACT_STATUS = 7;
+ int CONTACT_STATUS_TIMESTAMP = 8;
+ int CONTACT_STATUS_RES_PACKAGE = 9;
+ int CONTACT_STATUS_LABEL = 10;
+ }
+
+ private interface PhotoQuery {
+ String[] COLUMNS = new String[] {
+ Photo.PHOTO
+ };
+
+ int PHOTO = 0;
+ }
+
+ //Projection used for looking up contact id from phone number
+ protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
+ PhoneLookup._ID,
+ PhoneLookup.LOOKUP_KEY,
+ };
+ protected static final int PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX = 0;
+ protected static final int PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX = 1;
+
+ //Projection used for looking up contact id from email address
+ protected static final String[] EMAIL_LOOKUP_PROJECTION = new String[] {
+ RawContacts.CONTACT_ID,
+ Contacts.LOOKUP_KEY,
+ };
+ protected static final int EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX = 0;
+ protected static final int EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX = 1;
+
+ protected static final String[] CONTACT_LOOKUP_PROJECTION = new String[] {
+ Contacts._ID,
+ };
+ protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0;
+
+ private static final int TOKEN_CONTACT_INFO = 0;
+ private static final int TOKEN_PHONE_LOOKUP = 1;
+ private static final int TOKEN_EMAIL_LOOKUP = 2;
+ private static final int TOKEN_PHOTO_QUERY = 3;
+
+ public ContactHeaderWidget(Context context) {
+ this(context, null);
+ }
+
+ public ContactHeaderWidget(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ContactHeaderWidget(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ mContentResolver = mContext.getContentResolver();
+
+ LayoutInflater inflater =
+ (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.contact_header, this);
+
+ mDisplayNameView = (TextView) findViewById(R.id.name);
+
+ mPhoneticNameView = (TextView) findViewById(R.id.phonetic_name);
+
+ mPhotoView = (QuickContactBadge) findViewById(R.id.photo);
+
+ mPresenceView = (ImageView) findViewById(R.id.presence);
+
+ mStatusView = (TextView)findViewById(R.id.status);
+ mStatusAttributionView = (TextView)findViewById(R.id.status_date);
+
+ // Set the photo with a random "no contact" image
+ long now = SystemClock.elapsedRealtime();
+ int num = (int) now & 0xf;
+ if (num < 9) {
+ // Leaning in from right, common
+ mNoPhotoResource = R.drawable.ic_contact_picture;
+ } else if (num < 14) {
+ // Leaning in from left uncommon
+ mNoPhotoResource = R.drawable.ic_contact_picture_2;
+ } else {
+ // Coming in from the top, rare
+ mNoPhotoResource = R.drawable.ic_contact_picture_3;
+ }
+
+ resetAsyncQueryHandler();
+ }
+
+ public void enableClickListeners() {
+ mDisplayNameView.setOnClickListener(this);
+ mPhotoView.setOnClickListener(this);
+ }
+
+ /**
+ * Set the given {@link ContactHeaderListener} to handle header events.
+ */
+ public void setContactHeaderListener(ContactHeaderListener listener) {
+ mListener = listener;
+ }
+
+ private void performPhotoClick() {
+ if (mListener != null) {
+ mListener.onPhotoClick(mPhotoView);
+ }
+ }
+
+ private void performDisplayNameClick() {
+ if (mListener != null) {
+ mListener.onDisplayNameClick(mDisplayNameView);
+ }
+ }
+
+ private class QueryHandler extends AsyncQueryHandler {
+
+ public QueryHandler(ContentResolver cr) {
+ super(cr);
+ }
+
+ @Override
+ protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ try{
+ if (this != mQueryHandler) {
+ Log.d(TAG, "onQueryComplete: discard result, the query handler is reset!");
+ return;
+ }
+
+ switch (token) {
+ case TOKEN_PHOTO_QUERY: {
+ //Set the photo
+ Bitmap photoBitmap = null;
+ if (cursor != null && cursor.moveToFirst()
+ && !cursor.isNull(PhotoQuery.PHOTO)) {
+ byte[] photoData = cursor.getBlob(PhotoQuery.PHOTO);
+ photoBitmap = BitmapFactory.decodeByteArray(photoData, 0,
+ photoData.length, null);
+ }
+
+ if (photoBitmap == null) {
+ photoBitmap = loadPlaceholderPhoto(null);
+ }
+ setPhoto(photoBitmap);
+ if (cookie != null && cookie instanceof Uri) {
+ mPhotoView.assignContactUri((Uri) cookie);
+ }
+ invalidate();
+ break;
+ }
+ case TOKEN_CONTACT_INFO: {
+ if (cursor != null && cursor.moveToFirst()) {
+ bindContactInfo(cursor);
+ final Uri lookupUri = Contacts.getLookupUri(
+ cursor.getLong(ContactQuery._ID),
+ cursor.getString(ContactQuery.LOOKUP_KEY));
+
+ final long photoId = cursor.getLong(ContactQuery.PHOTO_ID);
+
+ setPhotoId(photoId, lookupUri);
+ } else {
+ // shouldn't really happen
+ setDisplayName(null, null);
+ setSocialSnippet(null);
+ setPhoto(loadPlaceholderPhoto(null));
+ }
+ break;
+ }
+ case TOKEN_PHONE_LOOKUP: {
+ if (cursor != null && cursor.moveToFirst()) {
+ long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+ String lookupKey = cursor.getString(
+ PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
+ bindFromContactUriInternal(Contacts.getLookupUri(contactId, lookupKey),
+ false /* don't reset query handler */);
+ } else {
+ String phoneNumber = (String) cookie;
+ setDisplayName(phoneNumber, null);
+ setSocialSnippet(null);
+ setPhoto(loadPlaceholderPhoto(null));
+ mPhotoView.assignContactFromPhone(phoneNumber, true);
+ }
+ break;
+ }
+ case TOKEN_EMAIL_LOOKUP: {
+ if (cursor != null && cursor.moveToFirst()) {
+ long contactId = cursor.getLong(EMAIL_LOOKUP_CONTACT_ID_COLUMN_INDEX);
+ String lookupKey = cursor.getString(
+ EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
+ bindFromContactUriInternal(Contacts.getLookupUri(contactId, lookupKey),
+ false /* don't reset query handler */);
+ } else {
+ String emailAddress = (String) cookie;
+ setDisplayName(emailAddress, null);
+ setSocialSnippet(null);
+ setPhoto(loadPlaceholderPhoto(null));
+ mPhotoView.assignContactFromEmail(emailAddress, true);
+ }
+ break;
+ }
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+ }
+
+ /**
+ * Manually set the presence.
+ */
+ public void setPresence(int presence) {
+ mPresenceView.setImageResource(StatusUpdates.getPresenceIconResourceId(presence));
+ }
+
+ /**
+ * Manually set the presence. If presence is null, it is hidden.
+ * This doesn't change the underlying {@link Contacts} value, only the UI state.
+ * @hide
+ */
+ public void setPresence(Integer presence) {
+ if (presence == null) {
+ showPresence(false);
+ } else {
+ showPresence(true);
+ setPresence(presence.intValue());
+ }
+ }
+
+ /**
+ * Turn on/off showing the presence.
+ * @hide this is here for consistency with setStared/showStar and should be public
+ */
+ public void showPresence(boolean showPresence) {
+ mPresenceView.setVisibility(showPresence ? View.VISIBLE : View.GONE);
+ }
+
+ /**
+ * Manually set the contact uri without loading any data
+ */
+ public void setContactUri(Uri uri) {
+ setContactUri(uri, true);
+ }
+
+ /**
+ * Manually set the contact uri without loading any data
+ */
+ public void setContactUri(Uri uri, boolean sendToQuickContact) {
+ mContactUri = uri;
+ if (sendToQuickContact) {
+ mPhotoView.assignContactUri(uri);
+ }
+ }
+
+ /**
+ * Manually set the photo to display in the header. This doesn't change the
+ * underlying {@link Contacts}, only the UI state.
+ */
+ public void setPhoto(Bitmap bitmap) {
+ mPhotoView.setImageBitmap(bitmap);
+ }
+
+ /**
+ * Manually set the photo given its id. If the id is 0, a placeholder picture will
+ * be loaded. For any other Id, an async query is started
+ * @hide
+ */
+ public void setPhotoId(final long photoId, final Uri lookupUri) {
+ if (photoId == 0) {
+ setPhoto(loadPlaceholderPhoto(null));
+ mPhotoView.assignContactUri(lookupUri);
+ invalidate();
+ } else {
+ startPhotoQuery(photoId, lookupUri,
+ false /* don't reset query handler */);
+ }
+ }
+
+ /**
+ * Manually set the display name and phonetic name to show in the header.
+ * This doesn't change the underlying {@link Contacts}, only the UI state.
+ */
+ public void setDisplayName(CharSequence displayName, CharSequence phoneticName) {
+ mDisplayNameView.setText(displayName);
+ if (!TextUtils.isEmpty(phoneticName)) {
+ mPhoneticNameView.setText(phoneticName);
+ mPhoneticNameView.setVisibility(View.VISIBLE);
+ } else {
+ mPhoneticNameView.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Manually set the social snippet text to display in the header. This doesn't change the
+ * underlying {@link Contacts}, only the UI state.
+ */
+ public void setSocialSnippet(CharSequence snippet) {
+ if (snippet == null) {
+ mStatusView.setVisibility(View.GONE);
+ mStatusAttributionView.setVisibility(View.GONE);
+ } else {
+ mStatusView.setText(snippet);
+ mStatusView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /**
+ * Manually set the status attribution text to display in the header.
+ * This doesn't change the underlying {@link Contacts}, only the UI state.
+ * @hide
+ */
+ public void setStatusAttribution(CharSequence attribution) {
+ if (attribution != null) {
+ mStatusAttributionView.setText(attribution);
+ mStatusAttributionView.setVisibility(View.VISIBLE);
+ } else {
+ mStatusAttributionView.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * 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;
+ mPhotoView.setExcludeMimes(excludeMimes);
+ }
+
+ /**
+ * Manually set all the status values to display in the header.
+ * This doesn't change the underlying {@link Contacts}, only the UI state.
+ * @hide
+ * @param status The status of the contact. If this is either null or empty,
+ * the status is cleared and the other parameters are ignored.
+ * @param statusTimestamp The timestamp (retrieved via a call to
+ * {@link System#currentTimeMillis()}) of the last status update.
+ * This value can be null if it is not known.
+ * @param statusLabel The id of a resource string that specifies the current
+ * status. This value can be null if no Label should be used.
+ * @param statusResPackage The name of the resource package containing the resource string
+ * referenced in the parameter statusLabel.
+ */
+ public void setStatus(final String status, final Long statusTimestamp,
+ final Integer statusLabel, final String statusResPackage) {
+ if (TextUtils.isEmpty(status)) {
+ setSocialSnippet(null);
+ return;
+ }
+
+ setSocialSnippet(status);
+
+ final CharSequence timestampDisplayValue;
+
+ if (statusTimestamp != null) {
+ // Set the date/time field by mixing relative and absolute
+ // times.
+ int flags = DateUtils.FORMAT_ABBREV_RELATIVE;
+
+ timestampDisplayValue = DateUtils.getRelativeTimeSpanString(
+ statusTimestamp.longValue(), System.currentTimeMillis(),
+ DateUtils.MINUTE_IN_MILLIS, flags);
+ } else {
+ timestampDisplayValue = null;
+ }
+
+
+ String labelDisplayValue = null;
+
+ if (statusLabel != null) {
+ Resources resources;
+ if (TextUtils.isEmpty(statusResPackage)) {
+ resources = getResources();
+ } else {
+ PackageManager pm = getContext().getPackageManager();
+ try {
+ resources = pm.getResourcesForApplication(statusResPackage);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Contact status update resource package not found: "
+ + statusResPackage);
+ resources = null;
+ }
+ }
+
+ if (resources != null) {
+ try {
+ labelDisplayValue = resources.getString(statusLabel.intValue());
+ } catch (NotFoundException e) {
+ Log.w(TAG, "Contact status update resource not found: " + statusResPackage + "@"
+ + statusLabel.intValue());
+ }
+ }
+ }
+
+ final CharSequence attribution;
+ if (timestampDisplayValue != null && labelDisplayValue != null) {
+ attribution = getContext().getString(
+ R.string.contact_status_update_attribution_with_date,
+ timestampDisplayValue, labelDisplayValue);
+ } else if (timestampDisplayValue == null && labelDisplayValue != null) {
+ attribution = getContext().getString(
+ R.string.contact_status_update_attribution,
+ labelDisplayValue);
+ } else if (timestampDisplayValue != null) {
+ attribution = timestampDisplayValue;
+ } else {
+ attribution = null;
+ }
+ setStatusAttribution(attribution);
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param contactLookupUri a {Contacts.CONTENT_LOOKUP_URI} style URI.
+ */
+ public void bindFromContactLookupUri(Uri contactLookupUri) {
+ bindFromContactUriInternal(contactLookupUri, true /* reset query handler */);
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param contactUri a {Contacts.CONTENT_URI} style URI.
+ * @param resetQueryHandler whether to use a new AsyncQueryHandler or not.
+ */
+ private void bindFromContactUriInternal(Uri contactUri, boolean resetQueryHandler) {
+ mContactUri = contactUri;
+ startContactQuery(contactUri, resetQueryHandler);
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param emailAddress The email address used to do a reverse lookup in
+ * the contacts database. If more than one contact contains this email
+ * address, one of them will be chosen to bind to.
+ */
+ public void bindFromEmail(String emailAddress) {
+ resetAsyncQueryHandler();
+
+ mQueryHandler.startQuery(TOKEN_EMAIL_LOOKUP, emailAddress,
+ Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(emailAddress)),
+ EMAIL_LOOKUP_PROJECTION, null, null, null);
+ }
+
+ /**
+ * Convenience method for binding all available data from an existing
+ * contact.
+ *
+ * @param number The phone number used to do a reverse lookup in
+ * the contacts database. If more than one contact contains this phone
+ * number, one of them will be chosen to bind to.
+ */
+ public void bindFromPhoneNumber(String number) {
+ resetAsyncQueryHandler();
+
+ mQueryHandler.startQuery(TOKEN_PHONE_LOOKUP, number,
+ Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
+ PHONE_LOOKUP_PROJECTION, null, null, null);
+ }
+
+ /**
+ * startContactQuery
+ *
+ * internal method to query contact by Uri.
+ *
+ * @param contactUri the contact uri
+ * @param resetQueryHandler whether to use a new AsyncQueryHandler or not
+ */
+ private void startContactQuery(Uri contactUri, boolean resetQueryHandler) {
+ if (resetQueryHandler) {
+ resetAsyncQueryHandler();
+ }
+
+ mQueryHandler.startQuery(TOKEN_CONTACT_INFO, contactUri, contactUri, ContactQuery.COLUMNS,
+ null, null, null);
+ }
+
+ /**
+ * startPhotoQuery
+ *
+ * internal method to query contact photo by photo id and uri.
+ *
+ * @param photoId the photo id.
+ * @param lookupKey the lookup uri.
+ * @param resetQueryHandler whether to use a new AsyncQueryHandler or not.
+ */
+ protected void startPhotoQuery(long photoId, Uri lookupKey, boolean resetQueryHandler) {
+ if (resetQueryHandler) {
+ resetAsyncQueryHandler();
+ }
+
+ mQueryHandler.startQuery(TOKEN_PHOTO_QUERY, lookupKey,
+ ContentUris.withAppendedId(Data.CONTENT_URI, photoId), PhotoQuery.COLUMNS,
+ null, null, null);
+ }
+
+ /**
+ * Method to force this widget to forget everything it knows about the contact.
+ * We need to stop any existing async queries for phone, email, contact, and photos.
+ */
+ public void wipeClean() {
+ resetAsyncQueryHandler();
+
+ setDisplayName(null, null);
+ setPhoto(loadPlaceholderPhoto(null));
+ setSocialSnippet(null);
+ setPresence(0);
+ mContactUri = null;
+ mExcludeMimes = null;
+ }
+
+
+ private void resetAsyncQueryHandler() {
+ // the api AsyncQueryHandler.cancelOperation() doesn't really work. Since we really
+ // need the old async queries to be cancelled, let's do it the hard way.
+ mQueryHandler = new QueryHandler(mContentResolver);
+ }
+
+ /**
+ * Bind the contact details provided by the given {@link Cursor}.
+ */
+ protected void bindContactInfo(Cursor c) {
+ final String displayName = c.getString(ContactQuery.DISPLAY_NAME);
+ final String phoneticName = c.getString(ContactQuery.PHONETIC_NAME);
+ this.setDisplayName(displayName, phoneticName);
+
+ //Set the presence status
+ if (!c.isNull(ContactQuery.CONTACT_PRESENCE_STATUS)) {
+ int presence = c.getInt(ContactQuery.CONTACT_PRESENCE_STATUS);
+ setPresence(presence);
+ showPresence(true);
+ } else {
+ showPresence(false);
+ }
+
+ //Set the status update
+ final String status = c.getString(ContactQuery.CONTACT_STATUS);
+ final Long statusTimestamp = c.isNull(ContactQuery.CONTACT_STATUS_TIMESTAMP)
+ ? null
+ : c.getLong(ContactQuery.CONTACT_STATUS_TIMESTAMP);
+ final Integer statusLabel = c.isNull(ContactQuery.CONTACT_STATUS_LABEL)
+ ? null
+ : c.getInt(ContactQuery.CONTACT_STATUS_LABEL);
+ final String statusResPackage = c.getString(ContactQuery.CONTACT_STATUS_RES_PACKAGE);
+
+ setStatus(status, statusTimestamp, statusLabel, statusResPackage);
+ }
+
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.photo: {
+ performPhotoClick();
+ break;
+ }
+ case R.id.name: {
+ performDisplayNameClick();
+ break;
+ }
+ }
+ }
+
+ private Bitmap loadPlaceholderPhoto(BitmapFactory.Options options) {
+ if (mNoPhotoResource == 0) {
+ return null;
+ }
+ return BitmapFactory.decodeResource(mContext.getResources(),
+ mNoPhotoResource, options);
+ }
+}
diff --git a/LoaderApp/src/com/android/loaderapp/fragments/ContactFragment.java b/LoaderApp/src/com/android/loaderapp/fragments/ContactFragment.java
index f88d160..672d438 100644
--- a/LoaderApp/src/com/android/loaderapp/fragments/ContactFragment.java
+++ b/LoaderApp/src/com/android/loaderapp/fragments/ContactFragment.java
@@ -16,7 +16,7 @@
package com.android.loaderapp.fragments;
-import com.android.internal.widget.ContactHeaderWidget;
+import com.android.loaderapp.ContactHeaderWidget;
import com.android.loaderapp.R;
import com.android.loaderapp.model.Collapser;
import com.android.loaderapp.model.ContactLoader;
@@ -158,7 +158,6 @@ public class ContactFragment extends LoaderManagingFragment<ContactData>
mInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContactHeaderWidget = (ContactHeaderWidget) view.findViewById(R.id.contact_header_widget);
- mContactHeaderWidget.showStar(true);
mContactHeaderWidget.setExcludeMimes(new String[] { Contacts.CONTENT_ITEM_TYPE });
mListView = (ListView) view.findViewById(android.R.id.list);