1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.messaging.ui; 17 18import android.app.Activity; 19import android.app.Fragment; 20import android.app.PendingIntent; 21import android.appwidget.AppWidgetManager; 22import android.content.ActivityNotFoundException; 23import android.content.ClipData; 24import android.content.ComponentName; 25import android.content.ContentValues; 26import android.content.Context; 27import android.content.Intent; 28import android.graphics.Point; 29import android.graphics.Rect; 30import android.media.RingtoneManager; 31import android.net.Uri; 32import android.os.Bundle; 33import android.provider.ContactsContract.Contacts; 34import android.provider.ContactsContract.Intents; 35import android.provider.MediaStore; 36import android.provider.Telephony; 37import android.support.annotation.Nullable; 38import android.support.v4.app.TaskStackBuilder; 39import android.support.v4.content.LocalBroadcastManager; 40import android.text.TextUtils; 41 42import com.android.ex.photo.Intents.PhotoViewIntentBuilder; 43import com.android.messaging.R; 44import com.android.messaging.datamodel.ConversationImagePartsView; 45import com.android.messaging.datamodel.MediaScratchFileProvider; 46import com.android.messaging.datamodel.MessagingContentProvider; 47import com.android.messaging.datamodel.data.MessageData; 48import com.android.messaging.datamodel.data.MessagePartData; 49import com.android.messaging.datamodel.data.ParticipantData; 50import com.android.messaging.receiver.NotificationReceiver; 51import com.android.messaging.sms.MmsSmsUtils; 52import com.android.messaging.ui.appsettings.ApnEditorActivity; 53import com.android.messaging.ui.appsettings.ApnSettingsActivity; 54import com.android.messaging.ui.appsettings.ApplicationSettingsActivity; 55import com.android.messaging.ui.appsettings.PerSubscriptionSettingsActivity; 56import com.android.messaging.ui.appsettings.SettingsActivity; 57import com.android.messaging.ui.attachmentchooser.AttachmentChooserActivity; 58import com.android.messaging.ui.conversation.ConversationActivity; 59import com.android.messaging.ui.conversation.LaunchConversationActivity; 60import com.android.messaging.ui.conversationlist.ArchivedConversationListActivity; 61import com.android.messaging.ui.conversationlist.ConversationListActivity; 62import com.android.messaging.ui.conversationlist.ForwardMessageActivity; 63import com.android.messaging.ui.conversationsettings.PeopleAndOptionsActivity; 64import com.android.messaging.ui.debug.DebugMmsConfigActivity; 65import com.android.messaging.ui.photoviewer.BuglePhotoViewActivity; 66import com.android.messaging.util.Assert; 67import com.android.messaging.util.ContentType; 68import com.android.messaging.util.ConversationIdSet; 69import com.android.messaging.util.LogUtil; 70import com.android.messaging.util.UiUtils; 71import com.android.messaging.util.UriUtil; 72 73/** 74 * A central repository of Intents used to start activities. 75 */ 76public class UIIntentsImpl extends UIIntents { 77 private static final String CELL_BROADCAST_LIST_ACTIVITY = 78 "com.android.cellbroadcastreceiver.CellBroadcastListActivity"; 79 private static final String CALL_TARGET_CLICK_KEY = "touchPoint"; 80 private static final String CALL_TARGET_CLICK_EXTRA_KEY = 81 "android.telecom.extra.OUTGOING_CALL_EXTRAS"; 82 private static final String MEDIA_SCANNER_CLASS = 83 "com.android.providers.media.MediaScannerService"; 84 private static final String MEDIA_SCANNER_PACKAGE = "com.android.providers.media"; 85 private static final String MEDIA_SCANNER_SCAN_ACTION = "android.media.IMediaScannerService"; 86 87 /** 88 * Get an intent which takes you to a conversation 89 */ 90 private Intent getConversationActivityIntent(final Context context, 91 final String conversationId, final MessageData draft, 92 final boolean withCustomTransition) { 93 final Intent intent = new Intent(context, ConversationActivity.class); 94 95 // Always try to reuse the same ConversationActivity in the current task so that we don't 96 // have two conversation activities in the back stack. 97 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 98 99 // Otherwise we're starting a new conversation 100 if (conversationId != null) { 101 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId); 102 } 103 if (draft != null) { 104 intent.putExtra(UI_INTENT_EXTRA_DRAFT_DATA, draft); 105 106 // If draft attachments came from an external content provider via a share intent, we 107 // need to propagate the URI permissions through to ConversationActivity. This requires 108 // putting the URIs into the ClipData (setData also works, but accepts only one URI). 109 ClipData clipData = null; 110 for (final MessagePartData partData : draft.getParts()) { 111 if (partData.isAttachment()) { 112 final Uri uri = partData.getContentUri(); 113 if (clipData == null) { 114 clipData = ClipData.newRawUri("Attachments", uri); 115 } else { 116 clipData.addItem(new ClipData.Item(uri)); 117 } 118 } 119 } 120 if (clipData != null) { 121 intent.setClipData(clipData); 122 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 123 } 124 } 125 if (withCustomTransition) { 126 intent.putExtra(UI_INTENT_EXTRA_WITH_CUSTOM_TRANSITION, true); 127 } 128 129 if (!(context instanceof Activity)) { 130 // If the caller supplies an application context, and not an activity context, we must 131 // include this flag 132 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 133 } 134 return intent; 135 } 136 137 @Override 138 public void launchPermissionCheckActivity(final Context context) { 139 final Intent intent = new Intent(context, PermissionCheckActivity.class); 140 context.startActivity(intent); 141 } 142 143 /** 144 * Get an intent which takes you to the conversation list 145 */ 146 private Intent getConversationListActivityIntent(final Context context) { 147 return new Intent(context, ConversationListActivity.class); 148 } 149 150 @Override 151 public void launchConversationListActivity(final Context context) { 152 final Intent intent = getConversationListActivityIntent(context); 153 context.startActivity(intent); 154 } 155 156 /** 157 * Get an intent which shows the low storage warning activity. 158 */ 159 private Intent getSmsStorageLowWarningActivityIntent(final Context context) { 160 return new Intent(context, SmsStorageLowWarningActivity.class); 161 } 162 163 @Override 164 public void launchConversationActivity(final Context context, 165 final String conversationId, final MessageData draft, final Bundle activityOptions, 166 final boolean withCustomTransition) { 167 Assert.isTrue(!withCustomTransition || activityOptions != null); 168 final Intent intent = getConversationActivityIntent(context, conversationId, draft, 169 withCustomTransition); 170 context.startActivity(intent, activityOptions); 171 } 172 173 @Override 174 public void launchConversationActivityNewTask( 175 final Context context, final String conversationId) { 176 final Intent intent = getConversationActivityIntent(context, conversationId, null, 177 false /* withCustomTransition */); 178 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 179 context.startActivity(intent); 180 } 181 182 @Override 183 public void launchConversationActivityWithParentStack(final Context context, 184 final String conversationId, final String smsBody) { 185 final MessageData messageData = TextUtils.isEmpty(smsBody) 186 ? null 187 : MessageData.createDraftSmsMessage(conversationId, null, smsBody); 188 TaskStackBuilder.create(context) 189 .addNextIntentWithParentStack( 190 getConversationActivityIntent(context, conversationId, messageData, 191 false /* withCustomTransition */)) 192 .startActivities(); 193 } 194 195 @Override 196 public void launchCreateNewConversationActivity(final Context context, 197 final MessageData draft) { 198 final Intent intent = getConversationActivityIntent(context, null, draft, 199 false /* withCustomTransition */); 200 context.startActivity(intent); 201 } 202 203 @Override 204 public void launchDebugMmsConfigActivity(final Context context) { 205 context.startActivity(new Intent(context, DebugMmsConfigActivity.class)); 206 } 207 208 @Override 209 public void launchAddContactActivity(final Context context, final String destination) { 210 final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); 211 final String destinationType = MmsSmsUtils.isEmailAddress(destination) ? 212 Intents.Insert.EMAIL : Intents.Insert.PHONE; 213 intent.setType(Contacts.CONTENT_ITEM_TYPE); 214 intent.putExtra(destinationType, destination); 215 startExternalActivity(context, intent); 216 } 217 218 @Override 219 public void launchSettingsActivity(final Context context) { 220 final Intent intent = new Intent(context, SettingsActivity.class); 221 context.startActivity(intent); 222 } 223 224 @Override 225 public void launchArchivedConversationsActivity(final Context context) { 226 final Intent intent = new Intent(context, ArchivedConversationListActivity.class); 227 context.startActivity(intent); 228 } 229 230 @Override 231 public void launchBlockedParticipantsActivity(final Context context) { 232 final Intent intent = new Intent(context, BlockedParticipantsActivity.class); 233 context.startActivity(intent); 234 } 235 236 @Override 237 public void launchDocumentImagePicker(final Fragment fragment) { 238 final Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 239 intent.putExtra(Intent.EXTRA_MIME_TYPES, MessagePartData.ACCEPTABLE_IMAGE_TYPES); 240 intent.addCategory(Intent.CATEGORY_OPENABLE); 241 intent.setType(ContentType.IMAGE_UNSPECIFIED); 242 243 fragment.startActivityForResult(intent, REQUEST_PICK_IMAGE_FROM_DOCUMENT_PICKER); 244 } 245 246 @Override 247 public void launchPeopleAndOptionsActivity(final Activity activity, 248 final String conversationId) { 249 final Intent intent = new Intent(activity, PeopleAndOptionsActivity.class); 250 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId); 251 activity.startActivityForResult(intent, 0); 252 } 253 254 @Override 255 public void launchPhoneCallActivity(final Context context, final String phoneNumber, 256 final Point clickPosition) { 257 final Intent intent = new Intent(Intent.ACTION_CALL, 258 Uri.parse(UriUtil.SCHEME_TEL + phoneNumber)); 259 final Bundle extras = new Bundle(); 260 extras.putParcelable(CALL_TARGET_CLICK_KEY, clickPosition); 261 intent.putExtra(CALL_TARGET_CLICK_EXTRA_KEY, extras); 262 startExternalActivity(context, intent); 263 } 264 265 @Override 266 public void launchClassZeroActivity(final Context context, final ContentValues messageValues) { 267 final Intent classZeroIntent = new Intent(context, ClassZeroActivity.class) 268 .putExtra(UI_INTENT_EXTRA_MESSAGE_VALUES, messageValues) 269 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 270 context.startActivity(classZeroIntent); 271 } 272 273 @Override 274 public void launchForwardMessageActivity(final Context context, final MessageData message) { 275 final Intent forwardMessageIntent = new Intent(context, ForwardMessageActivity.class) 276 .putExtra(UI_INTENT_EXTRA_DRAFT_DATA, message); 277 context.startActivity(forwardMessageIntent); 278 } 279 280 @Override 281 public void launchVCardDetailActivity(final Context context, final Uri vcardUri) { 282 final Intent vcardDetailIntent = new Intent(context, VCardDetailActivity.class) 283 .putExtra(UI_INTENT_EXTRA_VCARD_URI, vcardUri); 284 context.startActivity(vcardDetailIntent); 285 } 286 287 @Override 288 public void launchSaveVCardToContactsActivity(final Context context, final Uri vcardUri) { 289 Assert.isTrue(MediaScratchFileProvider.isMediaScratchSpaceUri(vcardUri)); 290 final Intent intent = new Intent(); 291 intent.setAction(Intent.ACTION_VIEW); 292 intent.setDataAndType(vcardUri, ContentType.TEXT_VCARD.toLowerCase()); 293 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 294 startExternalActivity(context, intent); 295 } 296 297 @Override 298 public void launchAttachmentChooserActivity(final Activity activity, 299 final String conversationId, final int requestCode) { 300 final Intent intent = new Intent(activity, AttachmentChooserActivity.class); 301 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId); 302 activity.startActivityForResult(intent, requestCode); 303 } 304 305 @Override 306 public void launchFullScreenVideoViewer(final Context context, final Uri videoUri) { 307 final Intent intent = new Intent(Intent.ACTION_VIEW); 308 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 309 310 // So we don't see "surrounding" images in Gallery 311 intent.putExtra("SingleItemOnly", true); 312 intent.setDataAndType(videoUri, ContentType.VIDEO_UNSPECIFIED); 313 startExternalActivity(context, intent); 314 } 315 316 @Override 317 public void launchFullScreenPhotoViewer(final Activity activity, final Uri initialPhoto, 318 final Rect initialPhotoBounds, final Uri photosUri) { 319 final PhotoViewIntentBuilder builder = 320 com.android.ex.photo.Intents.newPhotoViewIntentBuilder( 321 activity, BuglePhotoViewActivity.class); 322 builder.setPhotosUri(photosUri.toString()); 323 builder.setInitialPhotoUri(initialPhoto.toString()); 324 builder.setProjection(ConversationImagePartsView.PhotoViewQuery.PROJECTION); 325 326 // Set the location of the imageView so that the photoviewer can animate from that location 327 // to full screen. 328 builder.setScaleAnimation(initialPhotoBounds.left, initialPhotoBounds.top, 329 initialPhotoBounds.width(), initialPhotoBounds.height()); 330 331 builder.setDisplayThumbsFullScreen(false); 332 builder.setMaxInitialScale(8); 333 activity.startActivity(builder.build()); 334 activity.overridePendingTransition(0, 0); 335 } 336 337 @Override 338 public void launchApplicationSettingsActivity(final Context context, final boolean topLevel) { 339 final Intent intent = new Intent(context, ApplicationSettingsActivity.class); 340 intent.putExtra(UI_INTENT_EXTRA_TOP_LEVEL_SETTINGS, topLevel); 341 context.startActivity(intent); 342 } 343 344 @Override 345 public void launchPerSubscriptionSettingsActivity(final Context context, final int subId, 346 final String settingTitle) { 347 final Intent intent = getPerSubscriptionSettingsIntent(context, subId, settingTitle); 348 context.startActivity(intent); 349 } 350 351 @Override 352 public Intent getViewUrlIntent(final String url) { 353 final Uri uri = Uri.parse(url); 354 return new Intent(Intent.ACTION_VIEW, uri); 355 } 356 357 @Override 358 public void broadcastConversationSelfIdChange(final Context context, 359 final String conversationId, final String conversationSelfId) { 360 final Intent intent = new Intent(CONVERSATION_SELF_ID_CHANGE_BROADCAST_ACTION); 361 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId); 362 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_SELF_ID, conversationSelfId); 363 LocalBroadcastManager.getInstance(context).sendBroadcast(intent); 364 } 365 366 @Override 367 public PendingIntent getPendingIntentForConversationListActivity(final Context context) { 368 final Intent intent = getConversationListActivityIntent(context); 369 return getPendingIntentWithParentStack(context, intent, 0); 370 } 371 372 @Override 373 public PendingIntent getPendingIntentForConversationActivity(final Context context, 374 final String conversationId, final MessageData draft) { 375 final Intent intent = getConversationActivityIntent(context, conversationId, draft, 376 false /* withCustomTransition */); 377 // Ensure that the platform doesn't reuse PendingIntents across conversations 378 intent.setData(MessagingContentProvider.buildConversationMetadataUri(conversationId)); 379 return getPendingIntentWithParentStack(context, intent, 0); 380 } 381 382 @Override 383 public Intent getIntentForConversationActivity(final Context context, 384 final String conversationId, final MessageData draft) { 385 final Intent intent = getConversationActivityIntent(context, conversationId, draft, 386 false /* withCustomTransition */); 387 return intent; 388 } 389 390 @Override 391 public PendingIntent getPendingIntentForSendingMessageToConversation(final Context context, 392 final String conversationId, final String selfId, final boolean requiresMms, 393 final int requestCode) { 394 final Intent intent = new Intent(context, RemoteInputEntrypointActivity.class); 395 intent.setAction(Intent.ACTION_SENDTO); 396 // Ensure that the platform doesn't reuse PendingIntents across conversations 397 intent.setData(MessagingContentProvider.buildConversationMetadataUri(conversationId)); 398 intent.putExtra(UIIntents.UI_INTENT_EXTRA_CONVERSATION_ID, conversationId); 399 intent.putExtra(UIIntents.UI_INTENT_EXTRA_SELF_ID, selfId); 400 intent.putExtra(UIIntents.UI_INTENT_EXTRA_REQUIRES_MMS, requiresMms); 401 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 402 return getPendingIntentWithParentStack(context, intent, requestCode); 403 } 404 405 @Override 406 public PendingIntent getPendingIntentForClearingNotifications(final Context context, 407 final int updateTargets, final ConversationIdSet conversationIdSet, 408 final int requestCode) { 409 final Intent intent = new Intent(context, NotificationReceiver.class); 410 intent.setAction(ACTION_RESET_NOTIFICATIONS); 411 intent.putExtra(UI_INTENT_EXTRA_NOTIFICATIONS_UPDATE, updateTargets); 412 if (conversationIdSet != null) { 413 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID_SET, 414 conversationIdSet.getDelimitedString()); 415 } 416 return PendingIntent.getBroadcast(context, 417 requestCode, intent, 418 PendingIntent.FLAG_UPDATE_CURRENT); 419 } 420 421 /** 422 * Gets a PendingIntent associated with an Intent to start an Activity. All notifications 423 * that starts an Activity must use this method to get a PendingIntent, which achieves two 424 * goals: 425 * 1. The target activities will be created, with any existing ones destroyed. This ensures 426 * we don't end up with multiple instances of ConversationListActivity, for example. 427 * 2. The target activity, when launched, will have its backstack correctly constructed so 428 * back navigation will work correctly. 429 */ 430 private static PendingIntent getPendingIntentWithParentStack(final Context context, 431 final Intent intent, final int requestCode) { 432 final TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 433 // Adds the back stack for the Intent (plus the Intent itself) 434 stackBuilder.addNextIntentWithParentStack(intent); 435 final PendingIntent resultPendingIntent = 436 stackBuilder.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT); 437 return resultPendingIntent; 438 } 439 440 @Override 441 public Intent getRingtonePickerIntent(final String title, final Uri existingUri, 442 final Uri defaultUri, final int toneType) { 443 return new Intent(RingtoneManager.ACTION_RINGTONE_PICKER) 444 .putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, toneType) 445 .putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, title) 446 .putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, existingUri) 447 .putExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI, defaultUri); 448 } 449 450 @Override 451 public PendingIntent getPendingIntentForLowStorageNotifications(final Context context) { 452 final TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context); 453 final Intent conversationListIntent = getConversationListActivityIntent(context); 454 taskStackBuilder.addNextIntent(conversationListIntent); 455 taskStackBuilder.addNextIntentWithParentStack( 456 getSmsStorageLowWarningActivityIntent(context)); 457 458 return taskStackBuilder.getPendingIntent( 459 0, PendingIntent.FLAG_UPDATE_CURRENT); 460 } 461 462 @Override 463 public PendingIntent getPendingIntentForSecondaryUserNewMessageNotification( 464 final Context context) { 465 return getPendingIntentForConversationListActivity(context); 466 } 467 468 @Override 469 public Intent getWirelessAlertsIntent() { 470 final Intent intent = new Intent(Intent.ACTION_MAIN); 471 intent.setComponent(new ComponentName(CMAS_COMPONENT, CELL_BROADCAST_LIST_ACTIVITY)); 472 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 473 return intent; 474 } 475 476 @Override 477 public Intent getApnEditorIntent(final Context context, final String rowId, final int subId) { 478 final Intent intent = new Intent(context, ApnEditorActivity.class); 479 intent.putExtra(UI_INTENT_EXTRA_APN_ROW_ID, rowId); 480 intent.putExtra(UI_INTENT_EXTRA_SUB_ID, subId); 481 return intent; 482 } 483 484 @Override 485 public Intent getApnSettingsIntent(final Context context, final int subId) { 486 final Intent intent = new Intent(context, ApnSettingsActivity.class) 487 .putExtra(UI_INTENT_EXTRA_SUB_ID, subId); 488 return intent; 489 } 490 491 @Override 492 public Intent getAdvancedSettingsIntent(final Context context) { 493 return getPerSubscriptionSettingsIntent(context, ParticipantData.DEFAULT_SELF_SUB_ID, null); 494 } 495 496 @Override 497 public Intent getChangeDefaultSmsAppIntent(final Activity activity) { 498 final Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); 499 intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, activity.getPackageName()); 500 return intent; 501 } 502 503 @Override 504 public void launchBrowserForUrl(final Context context, final String url) { 505 final Intent intent = getViewUrlIntent(url); 506 startExternalActivity(context, intent); 507 } 508 509 /** 510 * Provides a safe way to handle external activities which may not exist. 511 */ 512 private void startExternalActivity(final Context context, final Intent intent) { 513 try { 514 context.startActivity(intent); 515 } catch (final ActivityNotFoundException ex) { 516 LogUtil.w(LogUtil.BUGLE_TAG, "Couldn't find activity:", ex); 517 UiUtils.showToastAtBottom(R.string.activity_not_found_message); 518 } 519 } 520 521 private Intent getPerSubscriptionSettingsIntent(final Context context, final int subId, 522 @Nullable final String settingTitle) { 523 return new Intent(context, PerSubscriptionSettingsActivity.class) 524 .putExtra(UI_INTENT_EXTRA_SUB_ID, subId) 525 .putExtra(UI_INTENT_EXTRA_PER_SUBSCRIPTION_SETTING_TITLE, settingTitle); 526 } 527 528 @Override 529 public Intent getLaunchConversationActivityIntent(final Context context) { 530 final Intent intent = new Intent(context, LaunchConversationActivity.class); 531 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY); 532 return intent; 533 } 534 535 @Override 536 public void kickMediaScanner(final Context context, final String volume) { 537 final Intent intent = new Intent(MEDIA_SCANNER_SCAN_ACTION) 538 .putExtra(MediaStore.MEDIA_SCANNER_VOLUME, volume) 539 .setClassName(MEDIA_SCANNER_PACKAGE, MEDIA_SCANNER_CLASS); 540 context.startService(intent); 541 } 542 543 @Override 544 public PendingIntent getWidgetPendingIntentForConversationActivity(final Context context, 545 final String conversationId, final int requestCode) { 546 final Intent intent = getConversationActivityIntent(context, null, null, 547 false /* withCustomTransition */); 548 if (conversationId != null) { 549 intent.putExtra(UI_INTENT_EXTRA_CONVERSATION_ID, conversationId); 550 551 // Set the action to something unique to this conversation so if someone calls this 552 // function again on a different conversation, they'll get a new PendingIntent instead 553 // of the old one. 554 intent.setAction(ACTION_WIDGET_CONVERSATION + conversationId); 555 } 556 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 557 return getPendingIntentWithParentStack(context, intent, requestCode); 558 } 559 560 @Override 561 public PendingIntent getWidgetPendingIntentForConversationListActivity( 562 final Context context) { 563 final Intent intent = getConversationListActivityIntent(context); 564 return getPendingIntentWithParentStack(context, intent, 0); 565 } 566 567 @Override 568 public PendingIntent getWidgetPendingIntentForConfigurationActivity(final Context context, 569 final int appWidgetId) { 570 final Intent configureIntent = new Intent(context, WidgetPickConversationActivity.class); 571 configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 572 configureIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); 573 configureIntent.setData(Uri.parse(configureIntent.toUri(Intent.URI_INTENT_SCHEME))); 574 configureIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY); 575 return getPendingIntentWithParentStack(context, configureIntent, 0); 576 } 577} 578