Details for multiple calls.
Add the details of the call at the bottom of the call details in a list.
The code allows having multiple details listed at the bottom, but
currently we only have one. A follow-up will add details for multiple
calls.
Change-Id: I0a91cc372f658bada603e22b9438a6db771dc124
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index d08b76a..ca17e7b 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -16,6 +16,8 @@
package com.android.contacts;
+import com.android.contacts.calllog.CallDetailHistoryAdapter;
+import com.android.contacts.calllog.CallTypeHelper;
import com.android.internal.telephony.CallerInfo;
import android.app.ListActivity;
@@ -35,7 +37,6 @@
import android.telephony.PhoneNumberUtils;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
-import android.text.format.DateUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -43,6 +44,7 @@
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
+import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@@ -58,9 +60,8 @@
/** The views representing the details of a phone call. */
private PhoneCallDetailsViews mPhoneCallDetailsViews;
+ private CallTypeHelper mCallTypeHelper;
private PhoneCallDetailsHelper mPhoneCallDetailsHelper;
- private TextView mCallTimeView;
- private TextView mCallDurationView;
private View mHomeActionView;
private ImageView mMainActionView;
private ImageView mContactBackgroundView;
@@ -72,7 +73,6 @@
/* package */ Resources mResources;
/** Helper to load contact photos. */
private ContactPhotoManager mContactPhotoManager;
- /** Attached to the call action button in the UI. */
static final String[] CALL_LOG_PROJECTION = new String[] {
CallLog.Calls.DATE,
@@ -115,17 +115,16 @@
mResources = getResources();
mPhoneCallDetailsViews = PhoneCallDetailsViews.fromView(getWindow().getDecorView());
- mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(this, getResources(),
- getVoicemailNumber(),
+ mCallTypeHelper = new CallTypeHelper(getResources(),
getResources().getDrawable(R.drawable.ic_call_log_list_incoming_call),
getResources().getDrawable(R.drawable.ic_call_log_list_outgoing_call),
getResources().getDrawable(R.drawable.ic_call_log_list_missed_call),
getResources().getDrawable(R.drawable.ic_call_log_list_voicemail));
+ mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(this, getResources(),
+ getVoicemailNumber(), mCallTypeHelper);
mHomeActionView = findViewById(R.id.action_bar_home);
mMainActionView = (ImageView) findViewById(R.id.main_action);
mContactBackgroundView = (ImageView) findViewById(R.id.contact_background);
- mCallTimeView = (TextView) findViewById(R.id.time);
- mCallDurationView = (TextView) findViewById(R.id.duration);
mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(this);
mContactPhotoManager = ContactPhotoManager.getInstance(this);
getListView().setOnItemClickListener(this);
@@ -183,19 +182,6 @@
if (TextUtils.isEmpty(countryIso)) {
countryIso = mDefaultCountryIso;
}
- // Pull out string in format [relative], [date]
- CharSequence dateClause = DateUtils.formatDateRange(this, date, date,
- DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
- DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
- mCallTimeView.setText(dateClause);
-
- // Set the duration
- if (callType == Calls.MISSED_TYPE) {
- mCallDurationView.setVisibility(View.GONE);
- } else {
- mCallDurationView.setVisibility(View.VISIBLE);
- mCallDurationView.setText(formatDuration(duration));
- }
long photoId = 0L;
CharSequence nameText = "";
@@ -303,9 +289,14 @@
ViewAdapter adapter = new ViewAdapter(this, actions);
setListAdapter(adapter);
}
+ PhoneCallDetails details = new PhoneCallDetails(mNumber, numberText,
+ new int[]{ callType }, duration, date, nameText, numberType, numberLabel);
mPhoneCallDetailsHelper.setPhoneCallDetails(mPhoneCallDetailsViews,
- new PhoneCallDetails(mNumber, numberText, new int[]{ callType }, date,
- nameText, numberType, numberLabel), false);
+ details, false);
+ ListView historyList = (ListView) findViewById(R.id.history);
+ historyList.setAdapter(
+ new CallDetailHistoryAdapter(this, mInflater, mCallTypeHelper,
+ new PhoneCallDetails[]{ details }));
loadContactPhotos(photoId);
} else {
@@ -327,19 +318,6 @@
mContactPhotoManager.loadPhoto(mContactBackgroundView, photoId);
}
- private String formatDuration(long elapsedSeconds) {
- long minutes = 0;
- long seconds = 0;
-
- if (elapsedSeconds >= 60) {
- minutes = elapsedSeconds / 60;
- elapsedSeconds -= minutes * 60;
- }
- seconds = elapsedSeconds;
-
- return getString(R.string.callDetailsDurationFormat, minutes, seconds);
- }
-
private String getVoicemailNumber() {
TelephonyManager telephonyManager =
(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
index 7b02a88..39620b2 100644
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ b/src/com/android/contacts/PhoneCallDetails.java
@@ -35,6 +35,8 @@
public final int[] callTypes;
/** The date of the call, in milliseconds since the epoch. */
public final long date;
+ /** The duration of the call in milliseconds, or 0 for missed calls. */
+ public final long duration;
/** The name of the contact, or the empty string. */
public final CharSequence name;
/** The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available. */
@@ -44,17 +46,18 @@
/** Create the details for a call with a number not associated with a contact. */
public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int[] callTypes,
- long date) {
- this(number, formattedNumber, callTypes, date, "", 0, "");
+ long date, long duration) {
+ this(number, formattedNumber, callTypes, date, duration, "", 0, "");
}
/** Create the details for a call with a number associated with a contact. */
public PhoneCallDetails(CharSequence number, CharSequence formattedNumber, int[] callTypes,
- long date, CharSequence name, int numberType, CharSequence numberLabel) {
+ long date, long duration, CharSequence name, int numberType, CharSequence numberLabel) {
this.number = number;
this.formattedNumber = formattedNumber;
this.callTypes = callTypes;
this.date = date;
+ this.duration = duration;
this.name = name;
this.numberType = numberType;
this.numberLabel = numberLabel;
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
index 7f73b04..cbf3c5c 100644
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ b/src/com/android/contacts/PhoneCallDetailsHelper.java
@@ -16,14 +16,13 @@
package com.android.contacts;
+import com.android.contacts.calllog.CallTypeHelper;
import com.android.contacts.format.FormatUtils;
import com.android.internal.telephony.CallerInfo;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.provider.CallLog.Calls;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.telephony.PhoneNumberUtils;
import android.text.Spanned;
@@ -39,24 +38,9 @@
private final Context mContext;
private final Resources mResources;
private final String mVoicemailNumber;
- /** Icon for incoming calls. */
- private final Drawable mIncomingDrawable;
- /** Icon for outgoing calls. */
- private final Drawable mOutgoingDrawable;
- /** Icon for missed calls. */
- private final Drawable mMissedDrawable;
- /** Icon for voicemails. */
- private final Drawable mVoicemailDrawable;
- /** Name used to identify incoming calls. */
- private final String mIncomingName;
- /** Name used to identify outgoing calls. */
- private final String mOutgoingName;
- /** Name used to identify missed calls. */
- private final String mMissedName;
- /** Name used to identify voicemail calls. */
- private final String mVoicemailName;
/** The injected current time in milliseconds since the epoch. Used only by tests. */
private Long mCurrentTimeMillisForTest;
+ private final CallTypeHelper mCallTypeHelper;
/**
* Creates a new instance of the helper.
@@ -66,20 +50,11 @@
* @param resources used to look up strings
*/
public PhoneCallDetailsHelper(Context context, Resources resources, String voicemailNumber,
- Drawable incomingDrawable, Drawable outgoingDrawable, Drawable missedDrawable,
- Drawable voicemailDrawable) {
+ CallTypeHelper callTypeHelper) {
mContext = context;
mResources = resources;
mVoicemailNumber = voicemailNumber;
- mIncomingDrawable = incomingDrawable;
- mOutgoingDrawable = outgoingDrawable;
- mMissedDrawable = missedDrawable;
- mVoicemailDrawable = voicemailDrawable;
- // Cache these values so that we do not need to look them up each time.
- mIncomingName = mResources.getString(R.string.type_incoming);
- mOutgoingName = mResources.getString(R.string.type_outgoing);
- mMissedName = mResources.getString(R.string.type_missed);
- mVoicemailName = mResources.getString(R.string.type_voicemail);
+ mCallTypeHelper = callTypeHelper;
}
/** Fills the call details views with content. */
@@ -90,7 +65,7 @@
int count = details.callTypes.length;
for (int callType : details.callTypes) {
ImageView callTypeImage = new ImageView(mContext);
- callTypeImage.setImageDrawable(getCallTypeDrawable(callType));
+ callTypeImage.setImageDrawable(mCallTypeHelper.getCallTypeDrawable(callType));
views.callTypeIcons.addView(callTypeImage);
}
views.callTypeIcons.setVisibility(View.VISIBLE);
@@ -101,7 +76,7 @@
// Use the name of the first call type.
// TODO: We should update this to handle the text for multiple calls as well.
int callType = details.callTypes[0];
- views.callTypeText.setText(getCallTypeText(callType));
+ views.callTypeText.setText(mCallTypeHelper.getCallTypeText(callType));
views.callTypeIcons.removeAllViews();
views.callTypeText.setVisibility(View.VISIBLE);
@@ -155,46 +130,6 @@
}
}
- /** Returns the text used to represent the given call type. */
- private String getCallTypeText(int callType) {
- switch (callType) {
- case Calls.INCOMING_TYPE:
- return mIncomingName;
-
- case Calls.OUTGOING_TYPE:
- return mOutgoingName;
-
- case Calls.MISSED_TYPE:
- return mMissedName;
-
- case Calls.VOICEMAIL_TYPE:
- return mVoicemailName;
-
- default:
- throw new IllegalArgumentException("invalid call type: " + callType);
- }
- }
-
- /** Returns the drawable of the icon associated with the given call type. */
- private Drawable getCallTypeDrawable(int callType) {
- switch (callType) {
- case Calls.INCOMING_TYPE:
- return mIncomingDrawable;
-
- case Calls.OUTGOING_TYPE:
- return mOutgoingDrawable;
-
- case Calls.MISSED_TYPE:
- return mMissedDrawable;
-
- case Calls.VOICEMAIL_TYPE:
- return mVoicemailDrawable;
-
- default:
- throw new IllegalArgumentException("invalid call type: " + callType);
- }
- }
-
private CharSequence getDisplayNumber(CharSequence number, CharSequence formattedNumber) {
if (TextUtils.isEmpty(number)) {
return "";
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
new file mode 100644
index 0000000..82ac971
--- /dev/null
+++ b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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.contacts.calllog;
+
+import com.android.contacts.PhoneCallDetails;
+import com.android.contacts.R;
+
+import android.content.Context;
+import android.provider.CallLog.Calls;
+import android.text.format.DateUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * Adapter for a ListView containing history items from the details of a call.
+ */
+public class CallDetailHistoryAdapter extends BaseAdapter {
+ private final Context mContext;
+ private final LayoutInflater mLayoutInflater;
+ private final CallTypeHelper mCallTypeHelper;
+ private final PhoneCallDetails[] mPhoneCallDetails;
+
+ public CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater,
+ CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails) {
+ mContext = context;
+ mLayoutInflater = layoutInflater;
+ mCallTypeHelper = callTypeHelper;
+ mPhoneCallDetails = phoneCallDetails;
+ }
+
+ @Override
+ public int getCount() {
+ return mPhoneCallDetails.length;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return mPhoneCallDetails[position];
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // Make sure we have a valid convertView to start with
+ if (convertView == null) {
+ convertView = mLayoutInflater.inflate(R.layout.call_detail_history_item, parent, false);
+ }
+
+ PhoneCallDetails details = mPhoneCallDetails[position];
+ ImageView callTypeIconView = (ImageView) convertView.findViewById(R.id.call_type_icon);
+ TextView callTypeTextView = (TextView) convertView.findViewById(R.id.call_type_text);
+ TextView numberView = (TextView) convertView.findViewById(R.id.number);
+ TextView dateView = (TextView) convertView.findViewById(R.id.date);
+ TextView durationView = (TextView) convertView.findViewById(R.id.duration);
+
+ int callType = details.callTypes[0];
+ callTypeIconView.setImageDrawable(mCallTypeHelper.getCallTypeDrawable(callType));
+ callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType));
+ // TODO: Add the label for this number as well.
+ numberView.setText(details.number);
+ // Set the date.
+ CharSequence dateValue = DateUtils.formatDateRange(mContext, details.date, details.date,
+ DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
+ DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
+ dateView.setText(dateValue);
+ // Set the duration
+ if (callType == Calls.MISSED_TYPE) {
+ durationView.setVisibility(View.GONE);
+ } else {
+ durationView.setVisibility(View.VISIBLE);
+ durationView.setText(formatDuration(details.duration));
+ }
+
+ return convertView;
+ }
+
+ private String formatDuration(long elapsedSeconds) {
+ long minutes = 0;
+ long seconds = 0;
+
+ if (elapsedSeconds >= 60) {
+ minutes = elapsedSeconds / 60;
+ elapsedSeconds -= minutes * 60;
+ }
+ seconds = elapsedSeconds;
+
+ return mContext.getString(R.string.callDetailsDurationFormat, minutes, seconds);
+ }
+}
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 11f8965..901ebd8 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -35,6 +35,7 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabaseCorruptException;
@@ -64,7 +65,6 @@
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
@@ -261,23 +261,25 @@
mRequests = new LinkedList<CallerInfoQuery>();
mPreDrawListener = null;
- Drawable incomingDrawable = getResources().getDrawable(
+ Resources resources = getResources();
+ Drawable incomingDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_incoming_call);
- Drawable outgoingDrawable = getResources().getDrawable(
+ Drawable outgoingDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_outgoing_call);
- Drawable missedDrawable = getResources().getDrawable(
+ Drawable missedDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_missed_call);
- Drawable voicemailDrawable = getResources().getDrawable(
+ Drawable voicemailDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_voicemail);
- Drawable callDrawable = getResources().getDrawable(
+ Drawable callDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_action_call);
- Drawable playDrawable = getResources().getDrawable(
+ Drawable playDrawable = resources.getDrawable(
R.drawable.ic_call_log_list_action_play);
mContactPhotoManager = ContactPhotoManager.getInstance(getActivity());
- PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
- getActivity(), getResources(), mVoiceMailNumber, incomingDrawable,
+ CallTypeHelper callTypeHelper = new CallTypeHelper(resources, incomingDrawable,
outgoingDrawable, missedDrawable, voicemailDrawable);
+ PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
+ getActivity(), resources, mVoiceMailNumber, callTypeHelper);
mCallLogViewsHelper = new CallLogListItemHelper(phoneCallDetailsHelper, callDrawable,
playDrawable);
}
@@ -640,6 +642,7 @@
String number = c.getString(CallLogQuery.NUMBER);
long date = c.getLong(CallLogQuery.DATE);
+ long duration = c.getLong(CallLogQuery.DURATION);
final String formattedNumber;
String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
// Store away the number so we can call it directly if you click on the call icon
@@ -699,10 +702,10 @@
int[] callTypes = getCallTypes(c, count);
final PhoneCallDetails details;
if (TextUtils.isEmpty(name)) {
- details = new PhoneCallDetails(number, formattedNumber, callTypes, date);
+ details = new PhoneCallDetails(number, formattedNumber, callTypes, date, duration);
} else {
- details = new PhoneCallDetails(number, formattedNumber, callTypes, date, name,
- ntype, label);
+ details = new PhoneCallDetails(number, formattedNumber, callTypes, date, duration,
+ name, ntype, label);
}
mCallLogViewsHelper.setPhoneCallDetails(views, details , true);
if (views.photoView != null) {
diff --git a/src/com/android/contacts/calllog/CallTypeHelper.java b/src/com/android/contacts/calllog/CallTypeHelper.java
new file mode 100644
index 0000000..b06a1c1
--- /dev/null
+++ b/src/com/android/contacts/calllog/CallTypeHelper.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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.contacts.calllog;
+
+import com.android.contacts.R;
+
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.provider.CallLog.Calls;
+
+/**
+ * Helper class to perform operations related to call types.
+ */
+public class CallTypeHelper {
+ /** Icon for incoming calls. */
+ private final Drawable mIncomingDrawable;
+ /** Icon for outgoing calls. */
+ private final Drawable mOutgoingDrawable;
+ /** Icon for missed calls. */
+ private final Drawable mMissedDrawable;
+ /** Icon for voicemails. */
+ private final Drawable mVoicemailDrawable;
+ /** Name used to identify incoming calls. */
+ private final String mIncomingName;
+ /** Name used to identify outgoing calls. */
+ private final String mOutgoingName;
+ /** Name used to identify missed calls. */
+ private final String mMissedName;
+ /** Name used to identify voicemail calls. */
+ private final String mVoicemailName;
+
+ public CallTypeHelper(Resources resources, Drawable incomingDrawable, Drawable outgoingDrawable,
+ Drawable missedDrawable, Drawable voicemailDrawable) {
+ mIncomingDrawable = incomingDrawable;
+ mOutgoingDrawable = outgoingDrawable;
+ mMissedDrawable = missedDrawable;
+ mVoicemailDrawable = voicemailDrawable;
+ // Cache these values so that we do not need to look them up each time.
+ mIncomingName = resources.getString(R.string.type_incoming);
+ mOutgoingName = resources.getString(R.string.type_outgoing);
+ mMissedName = resources.getString(R.string.type_missed);
+ mVoicemailName = resources.getString(R.string.type_voicemail);
+ }
+
+ /** Returns the text used to represent the given call type. */
+ public String getCallTypeText(int callType) {
+ switch (callType) {
+ case Calls.INCOMING_TYPE:
+ return mIncomingName;
+
+ case Calls.OUTGOING_TYPE:
+ return mOutgoingName;
+
+ case Calls.MISSED_TYPE:
+ return mMissedName;
+
+ case Calls.VOICEMAIL_TYPE:
+ return mVoicemailName;
+
+ default:
+ throw new IllegalArgumentException("invalid call type: " + callType);
+ }
+ }
+
+ /** Returns the drawable of the icon associated with the given call type. */
+ public Drawable getCallTypeDrawable(int callType) {
+ switch (callType) {
+ case Calls.INCOMING_TYPE:
+ return mIncomingDrawable;
+
+ case Calls.OUTGOING_TYPE:
+ return mOutgoingDrawable;
+
+ case Calls.MISSED_TYPE:
+ return mMissedDrawable;
+
+ case Calls.VOICEMAIL_TYPE:
+ return mVoicemailDrawable;
+
+ default:
+ throw new IllegalArgumentException("invalid call type: " + callType);
+ }
+ }
+}