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 107 public MessageListItem(Context context) { 108 super(context); 109 } 110 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 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 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 169 public MessageItem getMessageItem() { 170 return mMessageItem; 171 } 172 173 public void setMsgListItemHandler(Handler handler) { 174 mHandler = handler; 175 } 176 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 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 294 private void hideMmsViewIfNeeded() { 295 if (mMmsView != null) { 296 mMmsView.setVisibility(View.GONE); 297 } 298 } 299 300 public void startAudio() { 301 // TODO Auto-generated method stub 302 } 303 304 public void startVideo() { 305 // TODO Auto-generated method stub 306 } 307 308 public void setAudio(Uri audio, String name, Map<String, ?> extras) { 309 // TODO Auto-generated method stub 310 } 311 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 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 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 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 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 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 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 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 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 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 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 620 public void setImageRegionFit(String fit) { 621 // TODO Auto-generated method stub 622 } 623 624 public void setImageVisibility(boolean visible) { 625 // TODO Auto-generated method stub 626 } 627 628 public void setText(String name, String text) { 629 // TODO Auto-generated method stub 630 } 631 632 public void setTextVisibility(boolean visible) { 633 // TODO Auto-generated method stub 634 } 635 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 652 public void setVideoVisibility(boolean visible) { 653 // TODO Auto-generated method stub 654 } 655 656 public void stopAudio() { 657 // TODO Auto-generated method stub 658 } 659 660 public void stopVideo() { 661 // TODO Auto-generated method stub 662 } 663 664 public void reset() { 665 if (mImageView != null) { 666 mImageView.setVisibility(GONE); 667 } 668 } 669 670 public void setVisibility(boolean visible) { 671 // TODO Auto-generated method stub 672 } 673 674 public void pauseAudio() { 675 // TODO Auto-generated method stub 676 677 } 678 679 public void pauseVideo() { 680 // TODO Auto-generated method stub 681 682 } 683 684 public void seekAudio(int seekTo) { 685 // TODO Auto-generated method stub 686 687 } 688 689 public void seekVideo(int seekTo) { 690 // TODO Auto-generated method stub 691 692 } 693 } 694