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.io.File; 21 22 import com.google.android.mms.ContentType; 23 import com.android.mms.ExceedMessageSizeException; 24 import com.google.android.mms.MmsException; 25 import com.android.mms.MmsApp; 26 import com.android.mms.MmsConfig; 27 import com.android.mms.R; 28 import com.android.mms.ResolutionException; 29 import com.android.mms.TempFileProvider; 30 import com.android.mms.UnsupportContentTypeException; 31 import com.android.mms.model.IModelChangedObserver; 32 import com.android.mms.model.LayoutModel; 33 import com.android.mms.model.Model; 34 import com.android.mms.model.SlideModel; 35 import com.android.mms.model.SlideshowModel; 36 import com.google.android.mms.pdu.PduBody; 37 import com.google.android.mms.pdu.PduPart; 38 import com.google.android.mms.pdu.PduPersister; 39 import com.android.mms.ui.BasicSlideEditorView.OnTextChangedListener; 40 import com.android.mms.ui.MessageUtils.ResizeImageResultCallback; 41 42 import android.app.Activity; 43 import android.app.AlertDialog; 44 import android.content.ContentUris; 45 import android.content.Context; 46 import android.content.DialogInterface; 47 import android.content.Intent; 48 import android.content.res.Resources; 49 import android.media.RingtoneManager; 50 import android.net.Uri; 51 import android.os.Bundle; 52 import android.os.Handler; 53 import android.provider.MediaStore; 54 import android.provider.Settings; 55 import android.provider.Telephony.Mms; 56 import android.text.TextUtils; 57 import android.util.Log; 58 import android.view.Menu; 59 import android.view.MenuItem; 60 import android.view.SubMenu; 61 import android.view.View; 62 import android.view.View.OnClickListener; 63 import android.widget.Button; 64 import android.widget.ImageButton; 65 import android.widget.Toast; 66 import android.text.InputFilter.LengthFilter; 67 import android.widget.EditText; 68 import android.text.InputFilter; 69 70 /** 71 * This activity allows user to edit the contents of a slide. 72 */ 73 public class SlideEditorActivity extends Activity { 74 private static final String TAG = "SlideEditorActivity"; 75 private static final boolean DEBUG = false; 76 private static final boolean LOCAL_LOGV = false; 77 78 // Key for extra data. 79 public static final String SLIDE_INDEX = "slide_index"; 80 81 // Menu ids. 82 private final static int MENU_REMOVE_TEXT = 0; 83 private final static int MENU_ADD_PICTURE = 1; 84 private final static int MENU_TAKE_PICTURE = 2; 85 private final static int MENU_DEL_PICTURE = 3; 86 private final static int MENU_ADD_AUDIO = 4; 87 private final static int MENU_DEL_AUDIO = 5; 88 private final static int MENU_ADD_VIDEO = 6; 89 private final static int MENU_ADD_SLIDE = 7; 90 private final static int MENU_DEL_VIDEO = 8; 91 private final static int MENU_LAYOUT = 9; 92 private final static int MENU_DURATION = 10; 93 private final static int MENU_PREVIEW_SLIDESHOW = 11; 94 private final static int MENU_RECORD_SOUND = 12; 95 private final static int MENU_SUB_AUDIO = 13; 96 private final static int MENU_TAKE_VIDEO = 14; 97 98 // Request code. 99 private final static int REQUEST_CODE_EDIT_TEXT = 0; 100 private final static int REQUEST_CODE_CHANGE_PICTURE = 1; 101 private final static int REQUEST_CODE_TAKE_PICTURE = 2; 102 private final static int REQUEST_CODE_CHANGE_MUSIC = 3; 103 private final static int REQUEST_CODE_RECORD_SOUND = 4; 104 private final static int REQUEST_CODE_CHANGE_VIDEO = 5; 105 private final static int REQUEST_CODE_CHANGE_DURATION = 6; 106 private final static int REQUEST_CODE_TAKE_VIDEO = 7; 107 108 // number of items in the duration selector dialog that directly map from 109 // item index to duration in seconds (duration = index + 1) 110 private final static int NUM_DIRECT_DURATIONS = 10; 111 112 private ImageButton mNextSlide; 113 private ImageButton mPreSlide; 114 private Button mPreview; 115 private Button mReplaceImage; 116 private Button mRemoveSlide; 117 private EditText mTextEditor; 118 private Button mDone; 119 private BasicSlideEditorView mSlideView; 120 121 private SlideshowModel mSlideshowModel; 122 private SlideshowEditor mSlideshowEditor; 123 private SlideshowPresenter mPresenter; 124 private boolean mDirty; 125 126 private int mPosition; 127 private Uri mUri; 128 129 private final static String MESSAGE_URI = "message_uri"; 130 131 @Override onCreate(Bundle savedInstanceState)132 protected void onCreate(Bundle savedInstanceState) { 133 super.onCreate(savedInstanceState); 134 setContentView(R.layout.edit_slide_activity); 135 136 mSlideView = (BasicSlideEditorView) findViewById(R.id.slide_editor_view); 137 mSlideView.setOnTextChangedListener(mOnTextChangedListener); 138 139 mPreSlide = (ImageButton) findViewById(R.id.pre_slide_button); 140 mPreSlide.setOnClickListener(mOnNavigateBackward); 141 142 mNextSlide = (ImageButton) findViewById(R.id.next_slide_button); 143 mNextSlide.setOnClickListener(mOnNavigateForward); 144 145 mPreview = (Button) findViewById(R.id.preview_button); 146 mPreview.setOnClickListener(mOnPreview); 147 148 mReplaceImage = (Button) findViewById(R.id.replace_image_button); 149 mReplaceImage.setOnClickListener(mOnReplaceImage); 150 151 mRemoveSlide = (Button) findViewById(R.id.remove_slide_button); 152 mRemoveSlide.setOnClickListener(mOnRemoveSlide); 153 154 mTextEditor = (EditText) findViewById(R.id.text_message); 155 mTextEditor.setFilters(new InputFilter[] { 156 new LengthFilter(MmsConfig.getMaxTextLimit())}); 157 158 mDone = (Button) findViewById(R.id.done_button); 159 mDone.setOnClickListener(mDoneClickListener); 160 161 initActivityState(savedInstanceState, getIntent()); 162 163 try { 164 mSlideshowModel = SlideshowModel.createFromMessageUri(this, mUri); 165 // Confirm that we have at least 1 slide to display 166 if (mSlideshowModel.size() == 0) { 167 Log.e(TAG, "Loaded slideshow is empty; can't edit nothingness, exiting."); 168 finish(); 169 return; 170 } 171 // Register an observer to watch whether the data model is changed. 172 mSlideshowModel.registerModelChangedObserver(mModelChangedObserver); 173 mSlideshowEditor = new SlideshowEditor(this, mSlideshowModel); 174 mPresenter = (SlideshowPresenter) PresenterFactory.getPresenter( 175 "SlideshowPresenter", this, mSlideView, mSlideshowModel); 176 177 // Sanitize mPosition 178 if (mPosition >= mSlideshowModel.size()) { 179 mPosition = Math.max(0, mSlideshowModel.size() - 1); 180 } else if (mPosition < 0) { 181 mPosition = 0; 182 } 183 184 showCurrentSlide(); 185 } catch (MmsException e) { 186 Log.e(TAG, "Create SlideshowModel failed!", e); 187 finish(); 188 return; 189 } 190 } 191 initActivityState(Bundle savedInstanceState, Intent intent)192 private void initActivityState(Bundle savedInstanceState, Intent intent) { 193 if (savedInstanceState != null) { 194 mUri = (Uri) savedInstanceState.getParcelable(MESSAGE_URI); 195 mPosition = savedInstanceState.getInt(SLIDE_INDEX, 0); 196 } else { 197 mUri = intent.getData(); 198 mPosition = intent.getIntExtra(SLIDE_INDEX, 0); 199 } 200 } 201 202 @Override onSaveInstanceState(Bundle outState)203 protected void onSaveInstanceState(Bundle outState) { 204 super.onSaveInstanceState(outState); 205 206 outState.putInt(SLIDE_INDEX, mPosition); 207 outState.putParcelable(MESSAGE_URI, mUri); 208 } 209 210 @Override onPause()211 protected void onPause() { 212 super.onPause(); 213 214 synchronized (this) { 215 if (mDirty) { 216 try { 217 PduBody pb = mSlideshowModel.toPduBody(); 218 PduPersister.getPduPersister(this).updateParts(mUri, pb); 219 mSlideshowModel.sync(pb); 220 } catch (MmsException e) { 221 Log.e(TAG, "Cannot update the message: " + mUri, e); 222 } 223 } 224 } 225 } 226 227 @Override onDestroy()228 protected void onDestroy() { 229 super.onDestroy(); 230 231 if (mSlideshowModel != null) { 232 mSlideshowModel.unregisterModelChangedObserver( 233 mModelChangedObserver); 234 } 235 } 236 237 private final IModelChangedObserver mModelChangedObserver = 238 new IModelChangedObserver() { 239 public void onModelChanged(Model model, boolean dataChanged) { 240 synchronized (SlideEditorActivity.this) { 241 mDirty = true; 242 } 243 setResult(RESULT_OK); 244 } 245 }; 246 247 private final OnClickListener mOnRemoveSlide = new OnClickListener() { 248 public void onClick(View v) { 249 // Validate mPosition 250 if (mPosition >= 0 && mPosition < mSlideshowModel.size()) { 251 mSlideshowEditor.removeSlide(mPosition); 252 int size = mSlideshowModel.size(); 253 if (size > 0) { 254 if (mPosition >= size) { 255 mPosition--; 256 } 257 showCurrentSlide(); 258 } else { 259 finish(); 260 return; 261 } 262 } 263 } 264 }; 265 266 private final OnTextChangedListener mOnTextChangedListener = new OnTextChangedListener() { 267 public void onTextChanged(String s) { 268 if (!isFinishing()) { 269 mSlideshowEditor.changeText(mPosition, s); 270 } 271 } 272 }; 273 274 private final OnClickListener mOnPreview = new OnClickListener() { 275 public void onClick(View v) { 276 previewSlideshow(); 277 } 278 }; 279 280 private final OnClickListener mOnReplaceImage = new OnClickListener() { 281 public void onClick(View v) { 282 SlideModel slide = mSlideshowModel.get(mPosition); 283 if (slide != null && slide.hasVideo()) { 284 Toast.makeText(SlideEditorActivity.this, R.string.cannot_add_picture_and_video, 285 Toast.LENGTH_SHORT).show(); 286 return; 287 } 288 Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); 289 intent.setType(ContentType.IMAGE_UNSPECIFIED); 290 startActivityForResult(intent, REQUEST_CODE_CHANGE_PICTURE); 291 } 292 }; 293 294 private final OnClickListener mOnNavigateBackward = new OnClickListener() { 295 public void onClick(View v) { 296 if (mPosition > 0) { 297 mPosition --; 298 showCurrentSlide(); 299 } 300 } 301 }; 302 303 private final OnClickListener mOnNavigateForward = new OnClickListener() { 304 public void onClick(View v) { 305 if (mPosition < mSlideshowModel.size() - 1) { 306 mPosition ++; 307 showCurrentSlide(); 308 } 309 } 310 }; 311 312 private final OnClickListener mDoneClickListener = new OnClickListener() { 313 public void onClick(View v) { 314 Intent data = new Intent(); 315 data.putExtra("done", true); 316 setResult(RESULT_OK, data); 317 finish(); 318 } 319 }; 320 previewSlideshow()321 private void previewSlideshow() { 322 MessageUtils.viewMmsMessageAttachment(SlideEditorActivity.this, mUri, mSlideshowModel); 323 } 324 updateTitle()325 private void updateTitle() { 326 setTitle(getString(R.string.slide_show_part, (mPosition + 1), mSlideshowModel.size())); 327 } 328 329 @Override onPrepareOptionsMenu(Menu menu)330 public boolean onPrepareOptionsMenu(Menu menu) { 331 if (isFinishing()) { 332 return false; 333 } 334 menu.clear(); 335 336 SlideModel slide = mSlideshowModel.get(mPosition); 337 338 if (slide == null) { 339 return false; 340 } 341 342 // Preview slideshow. 343 menu.add(0, MENU_PREVIEW_SLIDESHOW, 0, R.string.preview_slideshow).setIcon( 344 com.android.internal.R.drawable.ic_menu_play_clip); 345 346 // Text 347 if (slide.hasText() && !TextUtils.isEmpty(slide.getText().getText())) { 348 //"Change text" if text is set. 349 menu.add(0, MENU_REMOVE_TEXT, 0, R.string.remove_text).setIcon( 350 R.drawable.ic_menu_remove_text); 351 } 352 353 // Picture 354 if (slide.hasImage()) { 355 menu.add(0, MENU_DEL_PICTURE, 0, R.string.remove_picture).setIcon( 356 R.drawable.ic_menu_remove_picture); 357 } else if (!slide.hasVideo()) { 358 menu.add(0, MENU_ADD_PICTURE, 0, R.string.add_picture).setIcon( 359 R.drawable.ic_menu_picture); 360 menu.add(0, MENU_TAKE_PICTURE, 0, R.string.attach_take_photo).setIcon( 361 R.drawable.ic_menu_picture); 362 } 363 364 // Music 365 if (slide.hasAudio()) { 366 menu.add(0, MENU_DEL_AUDIO, 0, R.string.remove_music).setIcon( 367 R.drawable.ic_menu_remove_sound); 368 } else if (!slide.hasVideo()) { 369 if (MmsConfig.getAllowAttachAudio()) { 370 SubMenu subMenu = menu.addSubMenu(0, MENU_SUB_AUDIO, 0, R.string.add_music) 371 .setIcon(R.drawable.ic_menu_add_sound); 372 subMenu.add(0, MENU_ADD_AUDIO, 0, R.string.attach_sound); 373 subMenu.add(0, MENU_RECORD_SOUND, 0, R.string.attach_record_sound); 374 } else { 375 menu.add(0, MENU_RECORD_SOUND, 0, R.string.attach_record_sound) 376 .setIcon(R.drawable.ic_menu_add_sound); 377 } 378 } 379 380 // Video 381 if (slide.hasVideo()) { 382 menu.add(0, MENU_DEL_VIDEO, 0, R.string.remove_video).setIcon( 383 R.drawable.ic_menu_remove_video); 384 } else if (!slide.hasAudio() && !slide.hasImage()) { 385 menu.add(0, MENU_ADD_VIDEO, 0, R.string.add_video).setIcon(R.drawable.ic_menu_movie); 386 menu.add(0, MENU_TAKE_VIDEO, 0, R.string.attach_record_video) 387 .setIcon(R.drawable.ic_menu_movie); 388 } 389 390 // Add slide 391 menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon( 392 R.drawable.ic_menu_add_slide); 393 394 // Slide duration 395 String duration = getResources().getString(R.string.duration_sec); 396 menu.add(0, MENU_DURATION, 0, 397 duration.replace("%s", String.valueOf(slide.getDuration() / 1000))).setIcon( 398 R.drawable.ic_menu_duration); 399 400 // Slide layout 401 int resId; 402 if (mSlideshowModel.getLayout().getLayoutType() == LayoutModel.LAYOUT_TOP_TEXT) { 403 resId = R.string.layout_top; 404 } else { 405 resId = R.string.layout_bottom; 406 } 407 // FIXME: set correct icon when layout icon is available. 408 menu.add(0, MENU_LAYOUT, 0, resId).setIcon(R.drawable.ic_menu_picture); 409 return true; 410 } 411 412 @Override onOptionsItemSelected(MenuItem item)413 public boolean onOptionsItemSelected(MenuItem item) { 414 switch (item.getItemId()) { 415 case MENU_PREVIEW_SLIDESHOW: 416 previewSlideshow(); 417 break; 418 419 case MENU_REMOVE_TEXT: 420 SlideModel slide = mSlideshowModel.get(mPosition); 421 if (slide != null) { 422 slide.removeText(); 423 } 424 break; 425 426 case MENU_ADD_PICTURE: 427 Intent intent = new Intent(Intent.ACTION_GET_CONTENT, null); 428 intent.setType(ContentType.IMAGE_UNSPECIFIED); 429 startActivityForResult(intent, REQUEST_CODE_CHANGE_PICTURE); 430 break; 431 432 case MENU_TAKE_PICTURE: 433 intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 434 // We have to pass a uri to store the picture data, otherwise the camera will return 435 // a very small image bitmap. 436 intent.putExtra(MediaStore.EXTRA_OUTPUT, TempFileProvider.SCRAP_CONTENT_URI); 437 startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE); 438 break; 439 440 case MENU_DEL_PICTURE: 441 mSlideshowEditor.removeImage(mPosition); 442 setReplaceButtonText(R.string.add_picture); 443 break; 444 445 case MENU_ADD_AUDIO: 446 MessageUtils.selectAudio(this, REQUEST_CODE_CHANGE_MUSIC); 447 break; 448 449 case MENU_RECORD_SOUND: 450 slide = mSlideshowModel.get(mPosition); 451 int currentSlideSize = slide.getSlideSize(); 452 long sizeLimit = ComposeMessageActivity.computeAttachmentSizeLimit(mSlideshowModel, 453 currentSlideSize); 454 MessageUtils.recordSound(this, REQUEST_CODE_RECORD_SOUND, sizeLimit); 455 break; 456 457 case MENU_DEL_AUDIO: 458 mSlideshowEditor.removeAudio(mPosition); 459 break; 460 461 case MENU_ADD_VIDEO: 462 intent = new Intent(Intent.ACTION_GET_CONTENT); 463 intent.setType(ContentType.VIDEO_UNSPECIFIED); 464 intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); 465 startActivityForResult(intent, REQUEST_CODE_CHANGE_VIDEO); 466 break; 467 468 case MENU_TAKE_VIDEO: 469 slide = mSlideshowModel.get(mPosition); 470 currentSlideSize = slide.getSlideSize(); 471 sizeLimit = ComposeMessageActivity.computeAttachmentSizeLimit(mSlideshowModel, 472 currentSlideSize); 473 if (sizeLimit > 0) { 474 MessageUtils.recordVideo(this, REQUEST_CODE_TAKE_VIDEO, sizeLimit); 475 } else { 476 Toast.makeText(this, 477 getString(R.string.message_too_big_for_video), 478 Toast.LENGTH_SHORT).show(); 479 } 480 break; 481 482 case MENU_DEL_VIDEO: 483 mSlideshowEditor.removeVideo(mPosition); 484 break; 485 486 case MENU_ADD_SLIDE: 487 mPosition++; 488 if ( mSlideshowEditor.addNewSlide(mPosition) ) { 489 // add successfully 490 showCurrentSlide(); 491 } else { 492 // move position back 493 mPosition--; 494 Toast.makeText(this, R.string.cannot_add_slide_anymore, 495 Toast.LENGTH_SHORT).show(); 496 } 497 break; 498 499 case MENU_LAYOUT: 500 showLayoutSelectorDialog(); 501 break; 502 503 case MENU_DURATION: 504 showDurationDialog(); 505 break; 506 } 507 508 return true; 509 } 510 setReplaceButtonText(int text)511 private void setReplaceButtonText(int text) { 512 mReplaceImage.setText(text); 513 } 514 showDurationDialog()515 private void showDurationDialog() { 516 AlertDialog.Builder builder = new AlertDialog.Builder(this); 517 builder.setIcon(R.drawable.ic_mms_duration); 518 String title = getResources().getString(R.string.duration_selector_title); 519 builder.setTitle(title + (mPosition + 1) + "/" + mSlideshowModel.size()); 520 521 builder.setItems(R.array.select_dialog_items, 522 new DialogInterface.OnClickListener() { 523 public void onClick(DialogInterface dialog, int which) { 524 if ((which >= 0) && (which < NUM_DIRECT_DURATIONS)) { 525 mSlideshowEditor.changeDuration( 526 mPosition, (which + 1) * 1000); 527 } else { 528 Intent intent = new Intent(SlideEditorActivity.this, 529 EditSlideDurationActivity.class); 530 intent.putExtra(EditSlideDurationActivity.SLIDE_INDEX, mPosition); 531 intent.putExtra(EditSlideDurationActivity.SLIDE_TOTAL, 532 mSlideshowModel.size()); 533 intent.putExtra(EditSlideDurationActivity.SLIDE_DUR, 534 mSlideshowModel.get(mPosition).getDuration() / 1000); // in seconds 535 startActivityForResult(intent, REQUEST_CODE_CHANGE_DURATION); 536 } 537 dialog.dismiss(); 538 } 539 }); 540 541 builder.show(); 542 } 543 showLayoutSelectorDialog()544 private void showLayoutSelectorDialog() { 545 AlertDialog.Builder builder = new AlertDialog.Builder(this); 546 builder.setIcon(R.drawable.ic_mms_layout); 547 548 String title = getResources().getString(R.string.layout_selector_title); 549 builder.setTitle(title + (mPosition + 1) + "/" + mSlideshowModel.size()); 550 551 LayoutSelectorAdapter adapter = new LayoutSelectorAdapter(this); 552 builder.setAdapter(adapter, new DialogInterface.OnClickListener() { 553 public void onClick(DialogInterface dialog, int which) { 554 switch (which) { 555 case 0: // Top text. 556 mSlideshowEditor.changeLayout(LayoutModel.LAYOUT_TOP_TEXT); 557 break; 558 case 1: // Bottom text. 559 mSlideshowEditor.changeLayout(LayoutModel.LAYOUT_BOTTOM_TEXT); 560 break; 561 } 562 dialog.dismiss(); 563 } 564 }); 565 566 builder.show(); 567 } 568 569 @Override onActivityResult(int requestCode, int resultCode, Intent data)570 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 571 if (resultCode != RESULT_OK) { 572 return; 573 } 574 575 switch(requestCode) { 576 case REQUEST_CODE_EDIT_TEXT: 577 // XXX where does this come from? Action is probably not the 578 // right place to have the text... 579 mSlideshowEditor.changeText(mPosition, data.getAction()); 580 break; 581 582 case REQUEST_CODE_TAKE_PICTURE: 583 Uri pictureUri = null; 584 boolean showError = false; 585 try { 586 pictureUri = TempFileProvider.renameScrapFile(".jpg", 587 Integer.toString(mPosition)); 588 589 if (pictureUri == null) { 590 showError = true; 591 } else { 592 mSlideshowEditor.changeImage(mPosition, pictureUri); 593 setReplaceButtonText(R.string.replace_image); 594 } 595 } catch (MmsException e) { 596 Log.e(TAG, "add image failed", e); 597 showError = true; 598 } catch (UnsupportContentTypeException e) { 599 MessageUtils.showErrorDialog(SlideEditorActivity.this, 600 getResourcesString(R.string.unsupported_media_format, getPictureString()), 601 getResourcesString(R.string.select_different_media, getPictureString())); 602 } catch (ResolutionException e) { 603 MessageUtils.resizeImageAsync(this, pictureUri, new Handler(), 604 mResizeImageCallback, false); 605 } catch (ExceedMessageSizeException e) { 606 MessageUtils.resizeImageAsync(this, pictureUri, new Handler(), 607 mResizeImageCallback, false); 608 } 609 if (showError) { 610 notifyUser("add picture failed"); 611 Toast.makeText(SlideEditorActivity.this, 612 getResourcesString(R.string.failed_to_add_media, getPictureString()), 613 Toast.LENGTH_SHORT).show(); 614 } 615 break; 616 617 case REQUEST_CODE_CHANGE_PICTURE: 618 try { 619 mSlideshowEditor.changeImage(mPosition, data.getData()); 620 setReplaceButtonText(R.string.replace_image); 621 } catch (MmsException e) { 622 Log.e(TAG, "add image failed", e); 623 notifyUser("add picture failed"); 624 Toast.makeText(SlideEditorActivity.this, 625 getResourcesString(R.string.failed_to_add_media, getPictureString()), 626 Toast.LENGTH_SHORT).show(); 627 } catch (UnsupportContentTypeException e) { 628 MessageUtils.showErrorDialog(SlideEditorActivity.this, 629 getResourcesString(R.string.unsupported_media_format, getPictureString()), 630 getResourcesString(R.string.select_different_media, getPictureString())); 631 } catch (ResolutionException e) { 632 MessageUtils.resizeImageAsync(this, data.getData(), new Handler(), 633 mResizeImageCallback, false); 634 } catch (ExceedMessageSizeException e) { 635 MessageUtils.resizeImageAsync(this, data.getData(), new Handler(), 636 mResizeImageCallback, false); 637 } 638 break; 639 640 case REQUEST_CODE_CHANGE_MUSIC: 641 case REQUEST_CODE_RECORD_SOUND: 642 Uri uri; 643 if (requestCode == REQUEST_CODE_CHANGE_MUSIC) { 644 uri = (Uri) data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI); 645 if (Settings.System.DEFAULT_RINGTONE_URI.equals(uri)) { 646 return; 647 } 648 } else { 649 uri = data.getData(); 650 } 651 652 try { 653 mSlideshowEditor.changeAudio(mPosition, uri); 654 } catch (MmsException e) { 655 Log.e(TAG, "add audio failed", e); 656 notifyUser("add music failed"); 657 Toast.makeText(SlideEditorActivity.this, 658 getResourcesString(R.string.failed_to_add_media, getAudioString()), 659 Toast.LENGTH_SHORT).show(); 660 } catch (UnsupportContentTypeException e) { 661 MessageUtils.showErrorDialog(SlideEditorActivity.this, 662 getResourcesString(R.string.unsupported_media_format, getAudioString()), 663 getResourcesString(R.string.select_different_media, getAudioString())); 664 } catch (ExceedMessageSizeException e) { 665 MessageUtils.showErrorDialog(SlideEditorActivity.this, 666 getResourcesString(R.string.exceed_message_size_limitation), 667 getResourcesString(R.string.failed_to_add_media, getAudioString())); 668 } 669 break; 670 671 case REQUEST_CODE_TAKE_VIDEO: 672 try { 673 Uri videoUri = TempFileProvider.renameScrapFile(".3gp", 674 Integer.toString(mPosition)); 675 676 mSlideshowEditor.changeVideo(mPosition, videoUri); 677 } catch (MmsException e) { 678 notifyUser("add video failed"); 679 Toast.makeText(SlideEditorActivity.this, 680 getResourcesString(R.string.failed_to_add_media, getVideoString()), 681 Toast.LENGTH_SHORT).show(); 682 } catch (UnsupportContentTypeException e) { 683 MessageUtils.showErrorDialog(SlideEditorActivity.this, 684 getResourcesString(R.string.unsupported_media_format, getVideoString()), 685 getResourcesString(R.string.select_different_media, getVideoString())); 686 } catch (ExceedMessageSizeException e) { 687 MessageUtils.showErrorDialog(SlideEditorActivity.this, 688 getResourcesString(R.string.exceed_message_size_limitation), 689 getResourcesString(R.string.failed_to_add_media, getVideoString())); 690 } 691 break; 692 693 case REQUEST_CODE_CHANGE_VIDEO: 694 try { 695 mSlideshowEditor.changeVideo(mPosition, data.getData()); 696 } catch (MmsException e) { 697 Log.e(TAG, "add video failed", e); 698 notifyUser("add video failed"); 699 Toast.makeText(SlideEditorActivity.this, 700 getResourcesString(R.string.failed_to_add_media, getVideoString()), 701 Toast.LENGTH_SHORT).show(); 702 } catch (UnsupportContentTypeException e) { 703 MessageUtils.showErrorDialog(SlideEditorActivity.this, 704 getResourcesString(R.string.unsupported_media_format, getVideoString()), 705 getResourcesString(R.string.select_different_media, getVideoString())); 706 } catch (ExceedMessageSizeException e) { 707 MessageUtils.showErrorDialog(SlideEditorActivity.this, 708 getResourcesString(R.string.exceed_message_size_limitation), 709 getResourcesString(R.string.failed_to_add_media, getVideoString())); 710 } 711 break; 712 713 case REQUEST_CODE_CHANGE_DURATION: 714 mSlideshowEditor.changeDuration(mPosition, 715 Integer.valueOf(data.getAction()) * 1000); 716 break; 717 } 718 } 719 720 private final ResizeImageResultCallback mResizeImageCallback = new ResizeImageResultCallback() { 721 public void onResizeResult(PduPart part, boolean append) { 722 Context context = SlideEditorActivity.this; 723 if (part == null) { 724 Toast.makeText(SlideEditorActivity.this, 725 getResourcesString(R.string.failed_to_add_media, getPictureString()), 726 Toast.LENGTH_SHORT).show(); 727 return; 728 } 729 730 try { 731 long messageId = ContentUris.parseId(mUri); 732 PduPersister persister = PduPersister.getPduPersister(context); 733 Uri newUri = persister.persistPart(part, messageId); 734 mSlideshowEditor.changeImage(mPosition, newUri); 735 736 setReplaceButtonText(R.string.replace_image); 737 } catch (MmsException e) { 738 notifyUser("add picture failed"); 739 Toast.makeText(SlideEditorActivity.this, 740 getResourcesString(R.string.failed_to_add_media, getPictureString()), 741 Toast.LENGTH_SHORT).show(); 742 } catch (UnsupportContentTypeException e) { 743 MessageUtils.showErrorDialog(SlideEditorActivity.this, 744 getResourcesString(R.string.unsupported_media_format, getPictureString()), 745 getResourcesString(R.string.select_different_media, getPictureString())); 746 } catch (ResolutionException e) { 747 MessageUtils.showErrorDialog(SlideEditorActivity.this, 748 getResourcesString(R.string.failed_to_resize_image), 749 getResourcesString(R.string.resize_image_error_information)); 750 } catch (ExceedMessageSizeException e) { 751 MessageUtils.showErrorDialog(SlideEditorActivity.this, 752 getResourcesString(R.string.exceed_message_size_limitation), 753 getResourcesString(R.string.failed_to_add_media, getPictureString())); 754 } 755 } 756 }; 757 getResourcesString(int id, String mediaName)758 private String getResourcesString(int id, String mediaName) { 759 Resources r = getResources(); 760 return r.getString(id, mediaName); 761 } 762 getResourcesString(int id)763 private String getResourcesString(int id) { 764 Resources r = getResources(); 765 return r.getString(id); 766 } 767 getAudioString()768 private String getAudioString() { 769 return getResourcesString(R.string.type_audio); 770 } 771 getPictureString()772 private String getPictureString() { 773 return getResourcesString(R.string.type_picture); 774 } 775 getVideoString()776 private String getVideoString() { 777 return getResourcesString(R.string.type_video); 778 } 779 notifyUser(String message)780 private void notifyUser(String message) { 781 if (LOCAL_LOGV) { 782 Log.v(TAG, "notifyUser: message=" + message); 783 } 784 } 785 showCurrentSlide()786 private void showCurrentSlide() { 787 mPresenter.setLocation(mPosition); 788 mPresenter.present(); 789 updateTitle(); 790 791 if (mSlideshowModel.get(mPosition).hasImage()) { 792 setReplaceButtonText(R.string.replace_image); 793 } else { 794 setReplaceButtonText(R.string.add_picture); 795 } 796 } 797 } 798