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