1 /* 2 * Copyright (C) 2008 Esmertec AG. 3 * Copyright (C) 2008 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.android.mms.ui; 19 20 import java.util.Map; 21 import java.util.regex.Matcher; 22 import java.util.regex.Pattern; 23 24 import android.app.AlertDialog; 25 import android.content.Context; 26 import android.content.DialogInterface; 27 import android.content.Intent; 28 import android.graphics.Bitmap; 29 import android.graphics.BitmapFactory; 30 import android.graphics.Canvas; 31 import android.graphics.Paint; 32 import android.graphics.Typeface; 33 import android.graphics.Paint.FontMetricsInt; 34 import android.graphics.drawable.Drawable; 35 import android.net.Uri; 36 import android.os.Handler; 37 import android.os.Message; 38 import android.provider.Browser; 39 import android.provider.Telephony.Mms; 40 import android.provider.Telephony.MmsSms; 41 import android.provider.Telephony.Sms; 42 import android.telephony.PhoneNumberUtils; 43 import android.telephony.TelephonyManager; 44 import android.text.Html; 45 import android.text.Layout; 46 import android.text.Spannable; 47 import android.text.SpannableStringBuilder; 48 import android.text.TextUtils; 49 import android.text.method.HideReturnsTransformationMethod; 50 import android.text.style.ForegroundColorSpan; 51 import android.text.style.LeadingMarginSpan; 52 import android.text.style.LineHeightSpan; 53 import android.text.style.StyleSpan; 54 import android.text.style.TextAppearanceSpan; 55 import android.text.style.URLSpan; 56 import android.util.AttributeSet; 57 import android.util.Log; 58 import android.view.View; 59 import android.view.ViewGroup; 60 import android.view.View.OnClickListener; 61 import android.widget.ArrayAdapter; 62 import android.widget.Button; 63 import android.widget.ImageButton; 64 import android.widget.ImageView; 65 import android.widget.LinearLayout; 66 import android.widget.QuickContactBadge; 67 import android.widget.TextView; 68 69 import com.android.mms.MmsApp; 70 import com.android.mms.R; 71 import com.android.mms.data.WorkingMessage; 72 import com.android.mms.transaction.Transaction; 73 import com.android.mms.transaction.TransactionBundle; 74 import com.android.mms.transaction.TransactionService; 75 import com.android.mms.util.DownloadManager; 76 import com.android.mms.util.SmileyParser; 77 import com.google.android.mms.ContentType; 78 import com.google.android.mms.pdu.PduHeaders; 79 80 /** 81 * This class provides view of a message in the messages list. 82 */ 83 public class MessageListItem extends LinearLayout implements 84 SlideViewInterface, OnClickListener { 85 public static final String EXTRA_URLS = "com.android.mms.ExtraUrls"; 86 87 private static final String TAG = "MessageListItem"; 88 private static final StyleSpan STYLE_BOLD = new StyleSpan(Typeface.BOLD); 89 90 static final int MSG_LIST_EDIT_MMS = 1; 91 static final int MSG_LIST_EDIT_SMS = 2; 92 93 private View mMsgListItem; 94 private View mMmsView; 95 private ImageView mImageView; 96 private ImageView mLockedIndicator; 97 private ImageView mDeliveredIndicator; 98 private ImageView mDetailsIndicator; 99 private ImageButton mSlideShowButton; 100 private TextView mBodyTextView; 101 private Button mDownloadButton; 102 private TextView mDownloadingLabel; 103 private QuickContactBadge mAvatar; 104 private Handler mHandler; 105 private MessageItem mMessageItem; 106 MessageListItem(Context context)107 public MessageListItem(Context context) { 108 super(context); 109 } 110 MessageListItem(Context context, AttributeSet attrs)111 public MessageListItem(Context context, AttributeSet attrs) { 112 super(context, attrs); 113 114 int color = mContext.getResources().getColor(R.color.timestamp_color); 115 mColorSpan = new ForegroundColorSpan(color); 116 } 117 118 @Override onFinishInflate()119 protected void onFinishInflate() { 120 super.onFinishInflate(); 121 122 mMsgListItem = findViewById(R.id.msg_list_item); 123 mBodyTextView = (TextView) findViewById(R.id.text_view); 124 mLockedIndicator = (ImageView) findViewById(R.id.locked_indicator); 125 mDeliveredIndicator = (ImageView) findViewById(R.id.delivered_indicator); 126 mDetailsIndicator = (ImageView) findViewById(R.id.details_indicator); 127 mAvatar = (QuickContactBadge) findViewById(R.id.avatar); 128 129 ViewGroup.MarginLayoutParams badgeParams = (MarginLayoutParams)mAvatar.getLayoutParams(); 130 final int badgeWidth = badgeParams.width + badgeParams.rightMargin + badgeParams.leftMargin; 131 132 int lineHeight = mBodyTextView.getLineHeight(); 133 int effectiveBadgeHeight = badgeParams.height + badgeParams.topMargin - mBodyTextView.getPaddingTop(); 134 final int indentLineCount = (int) ((effectiveBadgeHeight-1) / lineHeight) + 1; 135 136 mLeadingMarginSpan = new LeadingMarginSpan.LeadingMarginSpan2() { 137 public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 138 int top, int baseline, int bottom, CharSequence text, 139 int start, int end, boolean first, Layout layout) { 140 // no op 141 } 142 143 public int getLeadingMargin(boolean first) { 144 return first ? badgeWidth : 0; 145 } 146 147 public int getLeadingMarginLineCount() { 148 return indentLineCount; 149 } 150 }; 151 152 } 153 bind(MessageListAdapter.AvatarCache avatarCache, MessageItem msgItem)154 public void bind(MessageListAdapter.AvatarCache avatarCache, MessageItem msgItem) { 155 mMessageItem = msgItem; 156 157 setLongClickable(false); 158 159 switch (msgItem.mMessageType) { 160 case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 161 bindNotifInd(msgItem); 162 break; 163 default: 164 bindCommonMessage(avatarCache, msgItem); 165 break; 166 } 167 } 168 getMessageItem()169 public MessageItem getMessageItem() { 170 return mMessageItem; 171 } 172 setMsgListItemHandler(Handler handler)173 public void setMsgListItemHandler(Handler handler) { 174 mHandler = handler; 175 } 176 bindNotifInd(final MessageItem msgItem)177 private void bindNotifInd(final MessageItem msgItem) { 178 hideMmsViewIfNeeded(); 179 180 String msgSizeText = mContext.getString(R.string.message_size_label) 181 + String.valueOf((msgItem.mMessageSize + 1023) / 1024) 182 + mContext.getString(R.string.kilobyte); 183 184 mBodyTextView.setText(formatMessage(msgItem, msgItem.mContact, null, msgItem.mSubject, 185 msgSizeText + "\n" + msgItem.mTimestamp, 186 msgItem.mHighlight, msgItem.mTextContentType)); 187 188 int state = DownloadManager.getInstance().getState(msgItem.mMessageUri); 189 switch (state) { 190 case DownloadManager.STATE_DOWNLOADING: 191 inflateDownloadControls(); 192 mDownloadingLabel.setVisibility(View.VISIBLE); 193 mDownloadButton.setVisibility(View.GONE); 194 break; 195 case DownloadManager.STATE_UNSTARTED: 196 case DownloadManager.STATE_TRANSIENT_FAILURE: 197 case DownloadManager.STATE_PERMANENT_FAILURE: 198 default: 199 setLongClickable(true); 200 inflateDownloadControls(); 201 mDownloadingLabel.setVisibility(View.GONE); 202 mDownloadButton.setVisibility(View.VISIBLE); 203 mDownloadButton.setOnClickListener(new OnClickListener() { 204 public void onClick(View v) { 205 mDownloadingLabel.setVisibility(View.VISIBLE); 206 mDownloadButton.setVisibility(View.GONE); 207 Intent intent = new Intent(mContext, TransactionService.class); 208 intent.putExtra(TransactionBundle.URI, msgItem.mMessageUri.toString()); 209 intent.putExtra(TransactionBundle.TRANSACTION_TYPE, 210 Transaction.RETRIEVE_TRANSACTION); 211 mContext.startService(intent); 212 } 213 }); 214 break; 215 } 216 217 // Hide the indicators. 218 mLockedIndicator.setVisibility(View.GONE); 219 mDeliveredIndicator.setVisibility(View.GONE); 220 mDetailsIndicator.setVisibility(View.GONE); 221 222 drawLeftStatusIndicator(msgItem.mBoxId); 223 } 224 bindCommonMessage(final MessageListAdapter.AvatarCache avatarCache, final MessageItem msgItem)225 private void bindCommonMessage(final MessageListAdapter.AvatarCache avatarCache, final MessageItem msgItem) { 226 if (mDownloadButton != null) { 227 mDownloadButton.setVisibility(View.GONE); 228 mDownloadingLabel.setVisibility(View.GONE); 229 } 230 // Since the message text should be concatenated with the sender's 231 // address(or name), I have to display it here instead of 232 // displaying it by the Presenter. 233 mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); 234 235 String addr = null; 236 if (!Sms.isOutgoingFolder(msgItem.mBoxId)) { 237 addr = msgItem.mAddress; 238 } else { 239 addr = MmsApp.getApplication().getTelephonyManager().getLine1Number(); 240 } 241 if (!TextUtils.isEmpty(addr)) { 242 MessageListAdapter.AvatarCache.ContactData contactData = avatarCache.get(addr); 243 mAvatar.setImageDrawable(contactData.getAvatar()); 244 Uri contactUri = contactData.getContactUri(); 245 // Since we load the contact info in the background, on the first screenfull of 246 // messages, it's likely we haven't loaded the contact URI info yet. In that case, 247 // fall back and use the phone number. 248 if (contactUri != null) { 249 mAvatar.assignContactUri(contactUri); 250 } else { 251 mAvatar.assignContactFromPhone(addr, true); 252 } 253 } else { 254 mAvatar.setImageDrawable(null); 255 mAvatar.assignContactUri(null); 256 } 257 258 // Get and/or lazily set the formatted message from/on the 259 // MessageItem. Because the MessageItem instances come from a 260 // cache (currently of size ~50), the hit rate on avoiding the 261 // expensive formatMessage() call is very high. 262 CharSequence formattedMessage = msgItem.getCachedFormattedMessage(); 263 if (formattedMessage == null) { 264 formattedMessage = formatMessage(msgItem, msgItem.mContact, msgItem.mBody, 265 msgItem.mSubject, msgItem.mTimestamp, 266 msgItem.mHighlight, msgItem.mTextContentType); 267 } 268 mBodyTextView.setText(formattedMessage); 269 270 if (msgItem.isSms()) { 271 hideMmsViewIfNeeded(); 272 } else { 273 Presenter presenter = PresenterFactory.getPresenter( 274 "MmsThumbnailPresenter", mContext, 275 this, msgItem.mSlideshow); 276 presenter.present(); 277 278 if (msgItem.mAttachmentType != WorkingMessage.TEXT) { 279 inflateMmsView(); 280 mMmsView.setVisibility(View.VISIBLE); 281 setOnClickListener(msgItem); 282 drawPlaybackButton(msgItem); 283 } else { 284 hideMmsViewIfNeeded(); 285 } 286 } 287 288 drawLeftStatusIndicator(msgItem.mBoxId); 289 drawRightStatusIndicator(msgItem); 290 291 requestLayout(); 292 } 293 hideMmsViewIfNeeded()294 private void hideMmsViewIfNeeded() { 295 if (mMmsView != null) { 296 mMmsView.setVisibility(View.GONE); 297 } 298 } 299 startAudio()300 public void startAudio() { 301 // TODO Auto-generated method stub 302 } 303 startVideo()304 public void startVideo() { 305 // TODO Auto-generated method stub 306 } 307 setAudio(Uri audio, String name, Map<String, ?> extras)308 public void setAudio(Uri audio, String name, Map<String, ?> extras) { 309 // TODO Auto-generated method stub 310 } 311 setImage(String name, Bitmap bitmap)312 public void setImage(String name, Bitmap bitmap) { 313 inflateMmsView(); 314 315 try { 316 if (null == bitmap) { 317 bitmap = BitmapFactory.decodeResource(getResources(), 318 R.drawable.ic_missing_thumbnail_picture); 319 } 320 mImageView.setImageBitmap(bitmap); 321 mImageView.setVisibility(VISIBLE); 322 } catch (java.lang.OutOfMemoryError e) { 323 Log.e(TAG, "setImage: out of memory: ", e); 324 } 325 } 326 inflateMmsView()327 private void inflateMmsView() { 328 if (mMmsView == null) { 329 //inflate the surrounding view_stub 330 findViewById(R.id.mms_layout_view_stub).setVisibility(VISIBLE); 331 332 mMmsView = findViewById(R.id.mms_view); 333 mImageView = (ImageView) findViewById(R.id.image_view); 334 mSlideShowButton = (ImageButton) findViewById(R.id.play_slideshow_button); 335 } 336 } 337 inflateDownloadControls()338 private void inflateDownloadControls() { 339 if (mDownloadButton == null) { 340 //inflate the download controls 341 findViewById(R.id.mms_downloading_view_stub).setVisibility(VISIBLE); 342 mDownloadButton = (Button) findViewById(R.id.btn_download_msg); 343 mDownloadingLabel = (TextView) findViewById(R.id.label_downloading); 344 } 345 } 346 347 private LeadingMarginSpan mLeadingMarginSpan; 348 349 private LineHeightSpan mSpan = new LineHeightSpan() { 350 public void chooseHeight(CharSequence text, int start, 351 int end, int spanstartv, int v, FontMetricsInt fm) { 352 fm.ascent -= 10; 353 } 354 }; 355 356 TextAppearanceSpan mTextSmallSpan = 357 new TextAppearanceSpan(mContext, android.R.style.TextAppearance_Small); 358 359 ForegroundColorSpan mColorSpan = null; // set in ctor 360 formatMessage(MessageItem msgItem, String contact, String body, String subject, String timestamp, Pattern highlight, String contentType)361 private CharSequence formatMessage(MessageItem msgItem, String contact, String body, 362 String subject, String timestamp, Pattern highlight, 363 String contentType) { 364 CharSequence template = mContext.getResources().getText(R.string.name_colon); 365 SpannableStringBuilder buf = 366 new SpannableStringBuilder(TextUtils.replace(template, 367 new String[] { "%s" }, 368 new CharSequence[] { contact })); 369 370 boolean hasSubject = !TextUtils.isEmpty(subject); 371 if (hasSubject) { 372 buf.append(mContext.getResources().getString(R.string.inline_subject, subject)); 373 } 374 375 if (!TextUtils.isEmpty(body)) { 376 // Converts html to spannable if ContentType is "text/html". 377 if (contentType != null && ContentType.TEXT_HTML.equals(contentType)) { 378 buf.append("\n"); 379 buf.append(Html.fromHtml(body)); 380 } else { 381 if (hasSubject) { 382 buf.append(" - "); 383 } 384 SmileyParser parser = SmileyParser.getInstance(); 385 buf.append(parser.addSmileySpans(body)); 386 } 387 } 388 // If we're in the process of sending a message (i.e. pending), then we show a "Sending..." 389 // string in place of the timestamp. 390 if (msgItem.isSending()) { 391 timestamp = mContext.getResources().getString(R.string.sending_message); 392 } 393 // We always show two lines because the optional icon bottoms are aligned with the 394 // bottom of the text field, assuming there are two lines for the message and the sent time. 395 buf.append("\n"); 396 int startOffset = buf.length(); 397 398 startOffset = buf.length(); 399 buf.append(TextUtils.isEmpty(timestamp) ? " " : timestamp); 400 401 buf.setSpan(mTextSmallSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 402 buf.setSpan(mSpan, startOffset+1, buf.length(), 0); 403 404 // Make the timestamp text not as dark 405 buf.setSpan(mColorSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 406 407 if (highlight != null) { 408 Matcher m = highlight.matcher(buf.toString()); 409 while (m.find()) { 410 buf.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), 0); 411 } 412 } 413 buf.setSpan(mLeadingMarginSpan, 0, buf.length(), 0); 414 return buf; 415 } 416 drawPlaybackButton(MessageItem msgItem)417 private void drawPlaybackButton(MessageItem msgItem) { 418 switch (msgItem.mAttachmentType) { 419 case WorkingMessage.SLIDESHOW: 420 case WorkingMessage.AUDIO: 421 case WorkingMessage.VIDEO: 422 // Show the 'Play' button and bind message info on it. 423 mSlideShowButton.setTag(msgItem); 424 // Set call-back for the 'Play' button. 425 mSlideShowButton.setOnClickListener(this); 426 mSlideShowButton.setVisibility(View.VISIBLE); 427 setLongClickable(true); 428 429 // When we show the mSlideShowButton, this list item's onItemClickListener doesn't 430 // get called. (It gets set in ComposeMessageActivity: 431 // mMsgListView.setOnItemClickListener) Here we explicitly set the item's 432 // onClickListener. It allows the item to respond to embedded html links and at the 433 // same time, allows the slide show play button to work. 434 setOnClickListener(new OnClickListener() { 435 public void onClick(View v) { 436 onMessageListItemClick(); 437 } 438 }); 439 break; 440 default: 441 mSlideShowButton.setVisibility(View.GONE); 442 break; 443 } 444 } 445 446 // OnClick Listener for the playback button onClick(View v)447 public void onClick(View v) { 448 MessageItem mi = (MessageItem) v.getTag(); 449 switch (mi.mAttachmentType) { 450 case WorkingMessage.VIDEO: 451 case WorkingMessage.AUDIO: 452 case WorkingMessage.SLIDESHOW: 453 MessageUtils.viewMmsMessageAttachment(mContext, mi.mMessageUri, mi.mSlideshow); 454 break; 455 } 456 } 457 onMessageListItemClick()458 public void onMessageListItemClick() { 459 URLSpan[] spans = mBodyTextView.getUrls(); 460 461 if (spans.length == 0) { 462 // Do nothing. 463 } else if (spans.length == 1) { 464 Uri uri = Uri.parse(spans[0].getURL()); 465 Intent intent = new Intent(Intent.ACTION_VIEW, uri); 466 intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName()); 467 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 468 mContext.startActivity(intent); 469 } else { 470 final java.util.ArrayList<String> urls = MessageUtils.extractUris(spans); 471 472 ArrayAdapter<String> adapter = 473 new ArrayAdapter<String>(mContext, android.R.layout.select_dialog_item, urls) { 474 public View getView(int position, View convertView, ViewGroup parent) { 475 View v = super.getView(position, convertView, parent); 476 try { 477 String url = getItem(position).toString(); 478 TextView tv = (TextView) v; 479 Drawable d = mContext.getPackageManager().getActivityIcon(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); 480 if (d != null) { 481 d.setBounds(0, 0, d.getIntrinsicHeight(), d.getIntrinsicHeight()); 482 tv.setCompoundDrawablePadding(10); 483 tv.setCompoundDrawables(d, null, null, null); 484 } 485 final String telPrefix = "tel:"; 486 if (url.startsWith(telPrefix)) { 487 url = PhoneNumberUtils.formatNumber(url.substring(telPrefix.length())); 488 } 489 tv.setText(url); 490 } catch (android.content.pm.PackageManager.NameNotFoundException ex) { 491 ; 492 } 493 return v; 494 } 495 }; 496 497 AlertDialog.Builder b = new AlertDialog.Builder(mContext); 498 499 DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() { 500 public final void onClick(DialogInterface dialog, int which) { 501 if (which >= 0) { 502 Uri uri = Uri.parse(urls.get(which)); 503 Intent intent = new Intent(Intent.ACTION_VIEW, uri); 504 intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName()); 505 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); 506 mContext.startActivity(intent); 507 } 508 dialog.dismiss(); 509 } 510 }; 511 512 b.setTitle(R.string.select_link_title); 513 b.setCancelable(true); 514 b.setAdapter(adapter, click); 515 516 b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 517 public final void onClick(DialogInterface dialog, int which) { 518 dialog.dismiss(); 519 } 520 }); 521 522 b.show(); 523 } 524 } 525 526 setOnClickListener(final MessageItem msgItem)527 private void setOnClickListener(final MessageItem msgItem) { 528 switch(msgItem.mAttachmentType) { 529 case WorkingMessage.IMAGE: 530 case WorkingMessage.VIDEO: 531 mImageView.setOnClickListener(new OnClickListener() { 532 public void onClick(View v) { 533 MessageUtils.viewMmsMessageAttachment(mContext, null, msgItem.mSlideshow); 534 } 535 }); 536 mImageView.setOnLongClickListener(new OnLongClickListener() { 537 public boolean onLongClick(View v) { 538 return v.showContextMenu(); 539 } 540 }); 541 break; 542 543 default: 544 mImageView.setOnClickListener(null); 545 break; 546 } 547 } 548 drawLeftStatusIndicator(int msgBoxId)549 private void drawLeftStatusIndicator(int msgBoxId) { 550 switch (msgBoxId) { 551 case Mms.MESSAGE_BOX_INBOX: 552 mMsgListItem.setBackgroundResource(R.drawable.listitem_background_lightblue); 553 break; 554 555 case Mms.MESSAGE_BOX_DRAFTS: 556 case Sms.MESSAGE_TYPE_FAILED: 557 case Sms.MESSAGE_TYPE_QUEUED: 558 case Mms.MESSAGE_BOX_OUTBOX: 559 mMsgListItem.setBackgroundResource(R.drawable.listitem_background); 560 break; 561 562 default: 563 mMsgListItem.setBackgroundResource(R.drawable.listitem_background); 564 break; 565 } 566 } 567 setErrorIndicatorClickListener(final MessageItem msgItem)568 private void setErrorIndicatorClickListener(final MessageItem msgItem) { 569 String type = msgItem.mType; 570 final int what; 571 if (type.equals("sms")) { 572 what = MSG_LIST_EDIT_SMS; 573 } else { 574 what = MSG_LIST_EDIT_MMS; 575 } 576 mDeliveredIndicator.setOnClickListener(new OnClickListener() { 577 public void onClick(View v) { 578 if (null != mHandler) { 579 Message msg = Message.obtain(mHandler, what); 580 msg.obj = new Long(msgItem.mMsgId); 581 msg.sendToTarget(); 582 } 583 } 584 }); 585 } 586 drawRightStatusIndicator(MessageItem msgItem)587 private void drawRightStatusIndicator(MessageItem msgItem) { 588 // Locked icon 589 if (msgItem.mLocked) { 590 mLockedIndicator.setImageResource(R.drawable.ic_lock_message_sms); 591 mLockedIndicator.setVisibility(View.VISIBLE); 592 } else { 593 mLockedIndicator.setVisibility(View.GONE); 594 } 595 596 // Delivery icon 597 if (msgItem.isOutgoingMessage() && msgItem.isFailedMessage()) { 598 mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed); 599 setErrorIndicatorClickListener(msgItem); 600 mDeliveredIndicator.setVisibility(View.VISIBLE); 601 } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.FAILED) { 602 mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed); 603 mDeliveredIndicator.setVisibility(View.VISIBLE); 604 } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.RECEIVED) { 605 mDeliveredIndicator.setImageResource(R.drawable.ic_sms_mms_delivered); 606 mDeliveredIndicator.setVisibility(View.VISIBLE); 607 } else { 608 mDeliveredIndicator.setVisibility(View.GONE); 609 } 610 611 // Message details icon 612 if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.INFO || msgItem.mReadReport) { 613 mDetailsIndicator.setImageResource(R.drawable.ic_sms_mms_details); 614 mDetailsIndicator.setVisibility(View.VISIBLE); 615 } else { 616 mDetailsIndicator.setVisibility(View.GONE); 617 } 618 } 619 setImageRegionFit(String fit)620 public void setImageRegionFit(String fit) { 621 // TODO Auto-generated method stub 622 } 623 setImageVisibility(boolean visible)624 public void setImageVisibility(boolean visible) { 625 // TODO Auto-generated method stub 626 } 627 setText(String name, String text)628 public void setText(String name, String text) { 629 // TODO Auto-generated method stub 630 } 631 setTextVisibility(boolean visible)632 public void setTextVisibility(boolean visible) { 633 // TODO Auto-generated method stub 634 } 635 setVideo(String name, Uri video)636 public void setVideo(String name, Uri video) { 637 inflateMmsView(); 638 639 try { 640 Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video); 641 if (null == bitmap) { 642 bitmap = BitmapFactory.decodeResource(getResources(), 643 R.drawable.ic_missing_thumbnail_video); 644 } 645 mImageView.setImageBitmap(bitmap); 646 mImageView.setVisibility(VISIBLE); 647 } catch (java.lang.OutOfMemoryError e) { 648 Log.e(TAG, "setVideo: out of memory: ", e); 649 } 650 } 651 setVideoVisibility(boolean visible)652 public void setVideoVisibility(boolean visible) { 653 // TODO Auto-generated method stub 654 } 655 stopAudio()656 public void stopAudio() { 657 // TODO Auto-generated method stub 658 } 659 stopVideo()660 public void stopVideo() { 661 // TODO Auto-generated method stub 662 } 663 reset()664 public void reset() { 665 if (mImageView != null) { 666 mImageView.setVisibility(GONE); 667 } 668 } 669 setVisibility(boolean visible)670 public void setVisibility(boolean visible) { 671 // TODO Auto-generated method stub 672 } 673 pauseAudio()674 public void pauseAudio() { 675 // TODO Auto-generated method stub 676 677 } 678 pauseVideo()679 public void pauseVideo() { 680 // TODO Auto-generated method stub 681 682 } 683 seekAudio(int seekTo)684 public void seekAudio(int seekTo) { 685 // TODO Auto-generated method stub 686 687 } 688 seekVideo(int seekTo)689 public void seekVideo(int seekTo) { 690 // TODO Auto-generated method stub 691 692 } 693 } 694