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