Loading core/java/com/android/internal/widget/ContactHeaderWidget.java +65 −87 Original line number Diff line number Diff line Loading @@ -16,13 +16,14 @@ package com.android.internal.widget; import com.android.internal.R; 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.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; Loading @@ -31,13 +32,13 @@ import android.net.Uri; import android.os.SystemClock; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.Presence; import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Photo; import android.provider.SocialContract.Activities; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; Loading @@ -47,8 +48,6 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; /** * 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 Loading @@ -68,6 +67,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList private FasttrackBadgeWidget mPhotoView; private ImageView mPresenceView; private TextView mStatusView; private TextView mStatusDateView; private int mNoPhotoResource; private QueryHandler mQueryHandler; Loading @@ -87,31 +87,30 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList private ContactHeaderListener mListener; private interface ContactQuery { //Projection used for the summary info in the header. protected static final String[] HEADER_PROJECTION = new String[] { String[] COLUMNS = new String[] { Contacts._ID, Contacts.LOOKUP_KEY, Contacts.PHOTO_ID, Contacts.DISPLAY_NAME, Contacts.STARRED, Contacts.PHOTO_ID, Contacts.PRESENCE_STATUS, Contacts._ID, Contacts.LOOKUP_KEY, Contacts.PRESENCE_CUSTOM_STATUS, Contacts.PRESENCE_CUSTOM_STATUS_TIMESTAMP, }; protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0; int _ID = 0; int LOOKUP_KEY = 1; int PHOTO_ID = 2; int DISPLAY_NAME = 3; //TODO: We need to figure out how we're going to get the phonetic name. //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX protected static final int HEADER_STARRED_COLUMN_INDEX = 1; protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2; protected static final int HEADER_PRESENCE_STATUS_COLUMN_INDEX = 3; protected static final int HEADER_CONTACT_ID_COLUMN_INDEX = 4; protected static final int HEADER_LOOKUP_KEY_COLUMN_INDEX = 5; //Projection used for finding the most recent social status. protected static final String[] SOCIAL_PROJECTION = new String[] { Activities.TITLE, Activities.PUBLISHED, }; protected static final int SOCIAL_TITLE_COLUMN_INDEX = 0; protected static final int SOCIAL_PUBLISHED_COLUMN_INDEX = 1; int STARRED = 4; int PRESENCE_STATUS = 5; int PRESENCE_CUSTOM_STATUS = 6; int PRESENCE_CUSTOM_STATUS_TIMESTAMP = 7; } //Projection used for looking up contact id from phone number protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] { Loading @@ -135,10 +134,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0; private static final int TOKEN_CONTACT_INFO = 0; private static final int TOKEN_SOCIAL = 1; private static final int TOKEN_PHONE_LOOKUP = 2; private static final int TOKEN_EMAIL_LOOKUP = 3; private static final int TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY = 4; private static final int TOKEN_PHONE_LOOKUP = 1; private static final int TOKEN_EMAIL_LOOKUP = 2; public ContactHeaderWidget(Context context) { this(context, null); Loading Loading @@ -171,7 +168,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList mPresenceView = (ImageView) findViewById(R.id.presence); mStatusView = (TextView)findViewById(R.id.status); setSocialSnippet(null); mStatusDateView = (TextView)findViewById(R.id.status_date); // Set the photo with a random "no contact" image long now = SystemClock.elapsedRealtime(); Loading Loading @@ -229,11 +226,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList invalidate(); break; } case TOKEN_SOCIAL: { bindSocial(cursor); invalidate(); break; } case TOKEN_PHONE_LOOKUP: { if (cursor != null && cursor.moveToFirst()) { long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX); Loading @@ -260,13 +252,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList } break; } case TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY: { if (cursor != null && cursor.moveToFirst()) { long contactId = cursor.getLong(CONTACT_LOOKUP_ID_COLUMN_INDEX); startSocialQuery(ContentUris.withAppendedId( Activities.CONTENT_CONTACT_STATUS_URI, contactId)); } } } } finally { if (cursor != null) { Loading Loading @@ -370,11 +355,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList */ public void bindFromContactLookupUri(Uri contactLookupUri) { mContactUri = contactLookupUri; // Query for the contactId so we can do the social query. mQueryHandler.startQuery(TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY, null, contactLookupUri, CONTACT_LOOKUP_PROJECTION, null, null, null); startContactQuery(contactLookupUri); } Loading @@ -389,8 +369,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList long contactId = ContentUris.parseId(contactUri); startContactQuery(contactUri); startSocialQuery(ContentUris.withAppendedId( Activities.CONTENT_CONTACT_STATUS_URI, contactId)); } /** Loading Loading @@ -421,13 +399,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList PHONE_LOOKUP_PROJECTION, null, null, null); } private void startSocialQuery(Uri contactSocial) { mQueryHandler.startQuery(TOKEN_SOCIAL, null, contactSocial, SOCIAL_PROJECTION, null, null, null); } private void startContactQuery(Uri contactUri) { mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, HEADER_PROJECTION, mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, ContactQuery.COLUMNS, null, null, null); } Loading @@ -438,17 +411,17 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList if (c == null || !c.moveToFirst()) return; // TODO: Bring back phonetic name final String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX); final long contactId = c.getLong(HEADER_CONTACT_ID_COLUMN_INDEX); final String lookupKey = c.getString(HEADER_LOOKUP_KEY_COLUMN_INDEX); final String displayName = c.getString(ContactQuery.DISPLAY_NAME); final long contactId = c.getLong(ContactQuery._ID); final String lookupKey = c.getString(ContactQuery.LOOKUP_KEY); final String phoneticName = null; this.setDisplayName(displayName, null); final boolean starred = c.getInt(HEADER_STARRED_COLUMN_INDEX) != 0; final boolean starred = c.getInt(ContactQuery.STARRED) != 0; mStarredView.setChecked(starred); //Set the photo Bitmap photoBitmap = loadContactPhoto(c.getLong(HEADER_PHOTO_ID_COLUMN_INDEX), null); Bitmap photoBitmap = loadContactPhoto(c.getLong(ContactQuery.PHOTO_ID), null); if (photoBitmap == null) { photoBitmap = loadPlaceholderPhoto(null); } Loading @@ -456,22 +429,39 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey)); //Set the presence status if (!c.isNull(HEADER_PRESENCE_STATUS_COLUMN_INDEX)) { int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX); if (!c.isNull(ContactQuery.PRESENCE_STATUS)) { int presence = c.getInt(ContactQuery.PRESENCE_STATUS); mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence)); mPresenceView.setVisibility(View.VISIBLE); } else { mPresenceView.setVisibility(View.GONE); } //Set the status update String status = c.getString(ContactQuery.PRESENCE_CUSTOM_STATUS); if (!TextUtils.isEmpty(status)) { mStatusView.setText(status); mStatusView.setVisibility(View.VISIBLE); if (!c.isNull(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP)) { long date = c.getLong(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP); // Set the date/time field by mixing relative and absolute // times. int flags = DateUtils.FORMAT_ABBREV_RELATIVE; mStatusDateView.setText(DateUtils.getRelativeTimeSpanString(date, System .currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, flags)); mStatusDateView.setVisibility(View.VISIBLE); } else { mStatusDateView.setVisibility(View.GONE); } } else { mStatusView.setVisibility(View.GONE); mStatusDateView.setVisibility(View.GONE); } /** * Bind the social data provided by the given {@link Cursor}. */ protected void bindSocial(Cursor c) { if (c == null || !c.moveToFirst()) return; final String status = c.getString(SOCIAL_TITLE_COLUMN_INDEX); this.setSocialSnippet(status); // TODO add support for status update source, e.g. "via Google Talk" } public void onClick(View view) { Loading @@ -497,18 +487,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList } } 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 Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) { Cursor photoCursor = null; Bitmap photoBm = null; Loading core/res/res/layout/contact_header.xml +12 −3 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" android:layout_gravity="center_vertical" > Loading @@ -61,9 +60,19 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:maxLines="2" android:ellipsize="end"/> android:maxLines="1" android:ellipsize="end" android:layout_marginTop="-4dip" /> <TextView android:id="@+id/status_date" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceSmall" android:textSize="12sp" android:layout_marginTop="-2dip" /> </LinearLayout> <ImageView Loading Loading
core/java/com/android/internal/widget/ContactHeaderWidget.java +65 −87 Original line number Diff line number Diff line Loading @@ -16,13 +16,14 @@ package com.android.internal.widget; import com.android.internal.R; 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.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; Loading @@ -31,13 +32,13 @@ import android.net.Uri; import android.os.SystemClock; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Data; import android.provider.ContactsContract.Intents; import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.Presence; import android.provider.ContactsContract.RawContacts; import android.provider.ContactsContract.CommonDataKinds.Email; import android.provider.ContactsContract.CommonDataKinds.Photo; import android.provider.SocialContract.Activities; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; Loading @@ -47,8 +48,6 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.TextView; import com.android.internal.R; /** * 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 Loading @@ -68,6 +67,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList private FasttrackBadgeWidget mPhotoView; private ImageView mPresenceView; private TextView mStatusView; private TextView mStatusDateView; private int mNoPhotoResource; private QueryHandler mQueryHandler; Loading @@ -87,31 +87,30 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList private ContactHeaderListener mListener; private interface ContactQuery { //Projection used for the summary info in the header. protected static final String[] HEADER_PROJECTION = new String[] { String[] COLUMNS = new String[] { Contacts._ID, Contacts.LOOKUP_KEY, Contacts.PHOTO_ID, Contacts.DISPLAY_NAME, Contacts.STARRED, Contacts.PHOTO_ID, Contacts.PRESENCE_STATUS, Contacts._ID, Contacts.LOOKUP_KEY, Contacts.PRESENCE_CUSTOM_STATUS, Contacts.PRESENCE_CUSTOM_STATUS_TIMESTAMP, }; protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0; int _ID = 0; int LOOKUP_KEY = 1; int PHOTO_ID = 2; int DISPLAY_NAME = 3; //TODO: We need to figure out how we're going to get the phonetic name. //static final int HEADER_PHONETIC_NAME_COLUMN_INDEX protected static final int HEADER_STARRED_COLUMN_INDEX = 1; protected static final int HEADER_PHOTO_ID_COLUMN_INDEX = 2; protected static final int HEADER_PRESENCE_STATUS_COLUMN_INDEX = 3; protected static final int HEADER_CONTACT_ID_COLUMN_INDEX = 4; protected static final int HEADER_LOOKUP_KEY_COLUMN_INDEX = 5; //Projection used for finding the most recent social status. protected static final String[] SOCIAL_PROJECTION = new String[] { Activities.TITLE, Activities.PUBLISHED, }; protected static final int SOCIAL_TITLE_COLUMN_INDEX = 0; protected static final int SOCIAL_PUBLISHED_COLUMN_INDEX = 1; int STARRED = 4; int PRESENCE_STATUS = 5; int PRESENCE_CUSTOM_STATUS = 6; int PRESENCE_CUSTOM_STATUS_TIMESTAMP = 7; } //Projection used for looking up contact id from phone number protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] { Loading @@ -135,10 +134,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0; private static final int TOKEN_CONTACT_INFO = 0; private static final int TOKEN_SOCIAL = 1; private static final int TOKEN_PHONE_LOOKUP = 2; private static final int TOKEN_EMAIL_LOOKUP = 3; private static final int TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY = 4; private static final int TOKEN_PHONE_LOOKUP = 1; private static final int TOKEN_EMAIL_LOOKUP = 2; public ContactHeaderWidget(Context context) { this(context, null); Loading Loading @@ -171,7 +168,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList mPresenceView = (ImageView) findViewById(R.id.presence); mStatusView = (TextView)findViewById(R.id.status); setSocialSnippet(null); mStatusDateView = (TextView)findViewById(R.id.status_date); // Set the photo with a random "no contact" image long now = SystemClock.elapsedRealtime(); Loading Loading @@ -229,11 +226,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList invalidate(); break; } case TOKEN_SOCIAL: { bindSocial(cursor); invalidate(); break; } case TOKEN_PHONE_LOOKUP: { if (cursor != null && cursor.moveToFirst()) { long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX); Loading @@ -260,13 +252,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList } break; } case TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY: { if (cursor != null && cursor.moveToFirst()) { long contactId = cursor.getLong(CONTACT_LOOKUP_ID_COLUMN_INDEX); startSocialQuery(ContentUris.withAppendedId( Activities.CONTENT_CONTACT_STATUS_URI, contactId)); } } } } finally { if (cursor != null) { Loading Loading @@ -370,11 +355,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList */ public void bindFromContactLookupUri(Uri contactLookupUri) { mContactUri = contactLookupUri; // Query for the contactId so we can do the social query. mQueryHandler.startQuery(TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY, null, contactLookupUri, CONTACT_LOOKUP_PROJECTION, null, null, null); startContactQuery(contactLookupUri); } Loading @@ -389,8 +369,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList long contactId = ContentUris.parseId(contactUri); startContactQuery(contactUri); startSocialQuery(ContentUris.withAppendedId( Activities.CONTENT_CONTACT_STATUS_URI, contactId)); } /** Loading Loading @@ -421,13 +399,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList PHONE_LOOKUP_PROJECTION, null, null, null); } private void startSocialQuery(Uri contactSocial) { mQueryHandler.startQuery(TOKEN_SOCIAL, null, contactSocial, SOCIAL_PROJECTION, null, null, null); } private void startContactQuery(Uri contactUri) { mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, HEADER_PROJECTION, mQueryHandler.startQuery(TOKEN_CONTACT_INFO, null, contactUri, ContactQuery.COLUMNS, null, null, null); } Loading @@ -438,17 +411,17 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList if (c == null || !c.moveToFirst()) return; // TODO: Bring back phonetic name final String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX); final long contactId = c.getLong(HEADER_CONTACT_ID_COLUMN_INDEX); final String lookupKey = c.getString(HEADER_LOOKUP_KEY_COLUMN_INDEX); final String displayName = c.getString(ContactQuery.DISPLAY_NAME); final long contactId = c.getLong(ContactQuery._ID); final String lookupKey = c.getString(ContactQuery.LOOKUP_KEY); final String phoneticName = null; this.setDisplayName(displayName, null); final boolean starred = c.getInt(HEADER_STARRED_COLUMN_INDEX) != 0; final boolean starred = c.getInt(ContactQuery.STARRED) != 0; mStarredView.setChecked(starred); //Set the photo Bitmap photoBitmap = loadContactPhoto(c.getLong(HEADER_PHOTO_ID_COLUMN_INDEX), null); Bitmap photoBitmap = loadContactPhoto(c.getLong(ContactQuery.PHOTO_ID), null); if (photoBitmap == null) { photoBitmap = loadPlaceholderPhoto(null); } Loading @@ -456,22 +429,39 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey)); //Set the presence status if (!c.isNull(HEADER_PRESENCE_STATUS_COLUMN_INDEX)) { int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX); if (!c.isNull(ContactQuery.PRESENCE_STATUS)) { int presence = c.getInt(ContactQuery.PRESENCE_STATUS); mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence)); mPresenceView.setVisibility(View.VISIBLE); } else { mPresenceView.setVisibility(View.GONE); } //Set the status update String status = c.getString(ContactQuery.PRESENCE_CUSTOM_STATUS); if (!TextUtils.isEmpty(status)) { mStatusView.setText(status); mStatusView.setVisibility(View.VISIBLE); if (!c.isNull(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP)) { long date = c.getLong(ContactQuery.PRESENCE_CUSTOM_STATUS_TIMESTAMP); // Set the date/time field by mixing relative and absolute // times. int flags = DateUtils.FORMAT_ABBREV_RELATIVE; mStatusDateView.setText(DateUtils.getRelativeTimeSpanString(date, System .currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, flags)); mStatusDateView.setVisibility(View.VISIBLE); } else { mStatusDateView.setVisibility(View.GONE); } } else { mStatusView.setVisibility(View.GONE); mStatusDateView.setVisibility(View.GONE); } /** * Bind the social data provided by the given {@link Cursor}. */ protected void bindSocial(Cursor c) { if (c == null || !c.moveToFirst()) return; final String status = c.getString(SOCIAL_TITLE_COLUMN_INDEX); this.setSocialSnippet(status); // TODO add support for status update source, e.g. "via Google Talk" } public void onClick(View view) { Loading @@ -497,18 +487,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList } } 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 Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) { Cursor photoCursor = null; Bitmap photoBm = null; Loading
core/res/res/layout/contact_header.xml +12 −3 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ android:layout_width="0dip" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" android:layout_gravity="center_vertical" > Loading @@ -61,9 +60,19 @@ android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:maxLines="2" android:ellipsize="end"/> android:maxLines="1" android:ellipsize="end" android:layout_marginTop="-4dip" /> <TextView android:id="@+id/status_date" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:textAppearance="?android:attr/textAppearanceSmall" android:textSize="12sp" android:layout_marginTop="-2dip" /> </LinearLayout> <ImageView Loading