am 8e55eacc: Changing contact status to Presence-based
Merge commit '8e55eaccffeda078d7389b7fb66b0c6df347bf31' into eclair-plus-aosp * commit '8e55eaccffeda078d7389b7fb66b0c6df347bf31': Changing contact status to Presence-based
This commit is contained in:
@@ -16,13 +16,14 @@
|
|||||||
|
|
||||||
package com.android.internal.widget;
|
package com.android.internal.widget;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.content.AsyncQueryHandler;
|
import android.content.AsyncQueryHandler;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
@@ -31,13 +32,13 @@ import android.net.Uri;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.provider.ContactsContract.Contacts;
|
import android.provider.ContactsContract.Contacts;
|
||||||
import android.provider.ContactsContract.Data;
|
import android.provider.ContactsContract.Data;
|
||||||
import android.provider.ContactsContract.Intents;
|
|
||||||
import android.provider.ContactsContract.PhoneLookup;
|
import android.provider.ContactsContract.PhoneLookup;
|
||||||
import android.provider.ContactsContract.Presence;
|
import android.provider.ContactsContract.Presence;
|
||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Photo;
|
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.util.AttributeSet;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -47,8 +48,6 @@ import android.widget.FrameLayout;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.internal.R;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Header used across system for displaying a title bar with contact info. You
|
* 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
|
* can bind specific values on the header, or use helper methods like
|
||||||
@@ -68,6 +67,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
private FasttrackBadgeWidget mPhotoView;
|
private FasttrackBadgeWidget mPhotoView;
|
||||||
private ImageView mPresenceView;
|
private ImageView mPresenceView;
|
||||||
private TextView mStatusView;
|
private TextView mStatusView;
|
||||||
|
private TextView mStatusDateView;
|
||||||
private int mNoPhotoResource;
|
private int mNoPhotoResource;
|
||||||
private QueryHandler mQueryHandler;
|
private QueryHandler mQueryHandler;
|
||||||
|
|
||||||
@@ -87,31 +87,30 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
|
|
||||||
private ContactHeaderListener mListener;
|
private ContactHeaderListener mListener;
|
||||||
|
|
||||||
//Projection used for the summary info in the header.
|
|
||||||
protected static final String[] HEADER_PROJECTION = new String[] {
|
|
||||||
Contacts.DISPLAY_NAME,
|
|
||||||
Contacts.STARRED,
|
|
||||||
Contacts.PHOTO_ID,
|
|
||||||
Contacts.PRESENCE_STATUS,
|
|
||||||
Contacts._ID,
|
|
||||||
Contacts.LOOKUP_KEY,
|
|
||||||
};
|
|
||||||
protected static final int HEADER_DISPLAY_NAME_COLUMN_INDEX = 0;
|
|
||||||
//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.
|
private interface ContactQuery {
|
||||||
protected static final String[] SOCIAL_PROJECTION = new String[] {
|
//Projection used for the summary info in the header.
|
||||||
Activities.TITLE,
|
String[] COLUMNS = new String[] {
|
||||||
Activities.PUBLISHED,
|
Contacts._ID,
|
||||||
};
|
Contacts.LOOKUP_KEY,
|
||||||
protected static final int SOCIAL_TITLE_COLUMN_INDEX = 0;
|
Contacts.PHOTO_ID,
|
||||||
protected static final int SOCIAL_PUBLISHED_COLUMN_INDEX = 1;
|
Contacts.DISPLAY_NAME,
|
||||||
|
Contacts.STARRED,
|
||||||
|
Contacts.PRESENCE_STATUS,
|
||||||
|
Contacts.PRESENCE_CUSTOM_STATUS,
|
||||||
|
Contacts.PRESENCE_CUSTOM_STATUS_TIMESTAMP,
|
||||||
|
};
|
||||||
|
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
|
||||||
|
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
|
//Projection used for looking up contact id from phone number
|
||||||
protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
|
protected static final String[] PHONE_LOOKUP_PROJECTION = new String[] {
|
||||||
@@ -135,10 +134,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0;
|
protected static final int CONTACT_LOOKUP_ID_COLUMN_INDEX = 0;
|
||||||
|
|
||||||
private static final int TOKEN_CONTACT_INFO = 0;
|
private static final int TOKEN_CONTACT_INFO = 0;
|
||||||
private static final int TOKEN_SOCIAL = 1;
|
private static final int TOKEN_PHONE_LOOKUP = 1;
|
||||||
private static final int TOKEN_PHONE_LOOKUP = 2;
|
private static final int TOKEN_EMAIL_LOOKUP = 2;
|
||||||
private static final int TOKEN_EMAIL_LOOKUP = 3;
|
|
||||||
private static final int TOKEN_LOOKUP_CONTACT_FOR_SOCIAL_QUERY = 4;
|
|
||||||
|
|
||||||
public ContactHeaderWidget(Context context) {
|
public ContactHeaderWidget(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@@ -171,7 +168,7 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
mPresenceView = (ImageView) findViewById(R.id.presence);
|
mPresenceView = (ImageView) findViewById(R.id.presence);
|
||||||
|
|
||||||
mStatusView = (TextView)findViewById(R.id.status);
|
mStatusView = (TextView)findViewById(R.id.status);
|
||||||
setSocialSnippet(null);
|
mStatusDateView = (TextView)findViewById(R.id.status_date);
|
||||||
|
|
||||||
// Set the photo with a random "no contact" image
|
// Set the photo with a random "no contact" image
|
||||||
long now = SystemClock.elapsedRealtime();
|
long now = SystemClock.elapsedRealtime();
|
||||||
@@ -229,11 +226,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
invalidate();
|
invalidate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TOKEN_SOCIAL: {
|
|
||||||
bindSocial(cursor);
|
|
||||||
invalidate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case TOKEN_PHONE_LOOKUP: {
|
case TOKEN_PHONE_LOOKUP: {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
|
long contactId = cursor.getLong(PHONE_LOOKUP_CONTACT_ID_COLUMN_INDEX);
|
||||||
@@ -260,13 +252,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
}
|
}
|
||||||
break;
|
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 {
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
@@ -370,11 +355,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
*/
|
*/
|
||||||
public void bindFromContactLookupUri(Uri contactLookupUri) {
|
public void bindFromContactLookupUri(Uri contactLookupUri) {
|
||||||
mContactUri = 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);
|
startContactQuery(contactLookupUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,8 +369,6 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
long contactId = ContentUris.parseId(contactUri);
|
long contactId = ContentUris.parseId(contactUri);
|
||||||
|
|
||||||
startContactQuery(contactUri);
|
startContactQuery(contactUri);
|
||||||
startSocialQuery(ContentUris.withAppendedId(
|
|
||||||
Activities.CONTENT_CONTACT_STATUS_URI, contactId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -421,13 +399,8 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
PHONE_LOOKUP_PROJECTION, null, null, null);
|
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) {
|
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);
|
null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,17 +411,17 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
if (c == null || !c.moveToFirst()) return;
|
if (c == null || !c.moveToFirst()) return;
|
||||||
|
|
||||||
// TODO: Bring back phonetic name
|
// TODO: Bring back phonetic name
|
||||||
final String displayName = c.getString(HEADER_DISPLAY_NAME_COLUMN_INDEX);
|
final String displayName = c.getString(ContactQuery.DISPLAY_NAME);
|
||||||
final long contactId = c.getLong(HEADER_CONTACT_ID_COLUMN_INDEX);
|
final long contactId = c.getLong(ContactQuery._ID);
|
||||||
final String lookupKey = c.getString(HEADER_LOOKUP_KEY_COLUMN_INDEX);
|
final String lookupKey = c.getString(ContactQuery.LOOKUP_KEY);
|
||||||
final String phoneticName = null;
|
final String phoneticName = null;
|
||||||
this.setDisplayName(displayName, 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);
|
mStarredView.setChecked(starred);
|
||||||
|
|
||||||
//Set the photo
|
//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) {
|
if (photoBitmap == null) {
|
||||||
photoBitmap = loadPlaceholderPhoto(null);
|
photoBitmap = loadPlaceholderPhoto(null);
|
||||||
}
|
}
|
||||||
@@ -456,22 +429,39 @@ public class ContactHeaderWidget extends FrameLayout implements View.OnClickList
|
|||||||
mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
|
mPhotoView.assignContactUri(Contacts.getLookupUri(contactId, lookupKey));
|
||||||
|
|
||||||
//Set the presence status
|
//Set the presence status
|
||||||
if (!c.isNull(HEADER_PRESENCE_STATUS_COLUMN_INDEX)) {
|
if (!c.isNull(ContactQuery.PRESENCE_STATUS)) {
|
||||||
int presence = c.getInt(HEADER_PRESENCE_STATUS_COLUMN_INDEX);
|
int presence = c.getInt(ContactQuery.PRESENCE_STATUS);
|
||||||
mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
|
mPresenceView.setImageResource(Presence.getPresenceIconResourceId(presence));
|
||||||
mPresenceView.setVisibility(View.VISIBLE);
|
mPresenceView.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mPresenceView.setVisibility(View.GONE);
|
mPresenceView.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
//Set the status update
|
||||||
* Bind the social data provided by the given {@link Cursor}.
|
String status = c.getString(ContactQuery.PRESENCE_CUSTOM_STATUS);
|
||||||
*/
|
if (!TextUtils.isEmpty(status)) {
|
||||||
protected void bindSocial(Cursor c) {
|
mStatusView.setText(status);
|
||||||
if (c == null || !c.moveToFirst()) return;
|
mStatusView.setVisibility(View.VISIBLE);
|
||||||
final String status = c.getString(SOCIAL_TITLE_COLUMN_INDEX);
|
|
||||||
this.setSocialSnippet(status);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO add support for status update source, e.g. "via Google Talk"
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
@@ -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) {
|
private Bitmap loadContactPhoto(long photoId, BitmapFactory.Options options) {
|
||||||
Cursor photoCursor = null;
|
Cursor photoCursor = null;
|
||||||
Bitmap photoBm = null;
|
Bitmap photoBm = null;
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
android:layout_width="0dip"
|
android:layout_width="0dip"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_gravity="center_vertical" >
|
android:layout_gravity="center_vertical" >
|
||||||
|
|
||||||
@@ -61,9 +60,19 @@
|
|||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:maxLines="2"
|
android:maxLines="1"
|
||||||
android:ellipsize="end"/>
|
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>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|||||||
Reference in New Issue
Block a user