Example usage for android.content Intent FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

List of usage examples for android.content Intent FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

Introduction

In this page you can find the example usage for android.content Intent FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.

Prototype

int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

To view the source code for android.content Intent FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS.

Click Source Link

Document

If set, the new activity is not kept in the list of recently launched activities.

Usage

From source file:org.wso2.emm.system.service.EMMSystemService.java

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void enableHardLock() {
    String message = context.getResources().getString(R.string.txt_lock_activity);
    if (appUri != null && !appUri.isEmpty()) {
        message = appUri;//from   ww w  .  j  a  v  a2 s.c o  m
    }
    if (SettingsManager.isDeviceOwner()) {
        devicePolicyManager.setLockTaskPackages(cdmDeviceAdmin, AUTHORIZED_PINNING_APPS);
        Intent intent = new Intent(context, LockActivity.class);
        intent.setFlags(
                Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        intent.putExtra(Constants.ADMIN_MESSAGE, message);
        intent.putExtra(Constants.IS_LOCKED, true);
        context.startActivity(intent);
    } else {
        Log.e(TAG, "Device owner is not set, hence executing default lock");
        devicePolicyManager.lockNow();
    }
}

From source file:org.wso2.emm.agent.services.operationMgt.OperationManager.java

/**
 * Display notification.//from w  ww . j av a2 s.c  o m
 *
 * @param operation - Operation object.
 */
public void displayNotification(org.wso2.emm.agent.beans.Operation operation) throws AndroidAgentException {
    try {

        operation.setStatus(resources.getString(R.string.operation_value_progress));
        boolean isLocked = Preference.getBoolean(context, Constants.IS_LOCKED);
        if (isLocked) {
            operation.setOperationResponse(
                    "Alert is received to locked device: " + Calendar.getInstance().getTime().toString());
        } else {
            operation.setOperationResponse("Alert is received: " + Calendar.getInstance().getTime().toString());
        }

        resultBuilder.build(operation);
        JSONObject inputData = new JSONObject(operation.getPayLoad().toString());
        String message = inputData.getString(resources.getString(R.string.intent_extra_message));

        if (message != null && !message.isEmpty()) {
            addNotification(operation.getId(), message, Notification.Status.PENDING); //adding notification to the db
            if (deviceInfo.getSdkVersion() >= Build.VERSION_CODES.LOLLIPOP) {
                initNotification(operation.getId(), message);
            } else {
                Intent intent = new Intent(context, AlertActivity.class);
                intent.putExtra(resources.getString(R.string.intent_extra_message), message);
                intent.putExtra(resources.getString(R.string.intent_extra_operation_id), operation.getId());
                intent.putExtra(resources.getString(R.string.intent_extra_type),
                        resources.getString(R.string.intent_extra_alert));
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP
                        | Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                context.startActivity(intent);

            }
        }
        if (Constants.DEBUG_MODE_ENABLED) {
            Log.d(TAG, "Notification received");
        }
    } catch (JSONException e) {
        operation.setStatus(resources.getString(R.string.operation_value_error));
        resultBuilder.build(operation);
        throw new AndroidAgentException("Invalid JSON format.", e);
    }
}

From source file:com.synox.android.files.services.FileUploader.java

/**
 * Updates the status notification with the result of an upload operation.
 *
 * @param uploadResult Result of the upload operation.
 * @param upload Finished upload operation
 *///w  w w . j a  v a  2  s  . c  o m
private void notifyUploadResult(RemoteOperationResult uploadResult, UploadFileOperation upload) {
    Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
    // / cancelled operation or success -> silent removal of progress notification
    mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);

    // Show the result: success or fail notification
    if (!uploadResult.isCancelled()) {
        int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker
                : R.string.uploader_upload_failed_ticker;

        String content;

        // check credentials error
        boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED
                || uploadResult.isIdPRedirection());
        tickerId = (needsToUpdateCredentials) ? R.string.uploader_upload_failed_credentials_error : tickerId;

        mNotificationBuilder.setTicker(getString(tickerId)).setContentTitle(getString(tickerId))
                .setAutoCancel(true).setOngoing(false).setProgress(0, 0, false);

        content = ErrorMessageAdapter.getErrorCauseMessage(uploadResult, upload, getResources());

        if (needsToUpdateCredentials) {
            // let the user update credentials with one click
            Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
            updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount());
            updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
                    AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
            updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
            mNotificationBuilder.setContentIntent(PendingIntent.getActivity(this,
                    (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT));

            mUploadClient = null;
            // grant that future retries on the same account will get the fresh credentials
        } else {
            mNotificationBuilder.setContentText(content);

            if (upload.isInstant()) {
                DbHandler db = null;
                try {
                    db = new DbHandler(this.getBaseContext());
                    String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode();
                    Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
                    if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
                        //message = getString(R.string.failed_upload_quota_exceeded_text);
                        if (db.updateFileState(upload.getOriginalStoragePath(), message) == 0) {
                            db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name,
                                    message);
                        }
                    }
                } finally {
                    if (db != null) {
                        db.close();
                    }
                }
            }
        }

        mNotificationBuilder.setContentText(content);
        mNotificationManager.notify(tickerId, mNotificationBuilder.build());

        if (uploadResult.isSuccess()) {

            DbHandler db = new DbHandler(this.getBaseContext());
            db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
            db.close();

            // remove success notification, with a delay of 2 seconds
            NotificationDelayer.cancelWithDelay(mNotificationManager, R.string.uploader_upload_succeeded_ticker,
                    2000);

        }
    }
}

From source file:com.cerema.cloud2.files.services.FileUploader.java

/**
 * Updates the status notification with the result of an upload operation.
 *
 * @param uploadResult  Result of the upload operation.
 * @param upload        Finished upload operation
 *//*from www .  j  ava 2  s. c  o  m*/
private void notifyUploadResult(UploadFileOperation upload, RemoteOperationResult uploadResult) {
    Log_OC.d(TAG, "NotifyUploadResult with resultCode: " + uploadResult.getCode());
    // / cancelled operation or success -> silent removal of progress notification
    mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker);

    // Show the result: success or fail notification
    if (!uploadResult.isCancelled()) {
        int tickerId = (uploadResult.isSuccess()) ? R.string.uploader_upload_succeeded_ticker
                : R.string.uploader_upload_failed_ticker;

        String content;

        // check credentials error
        boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED
                || uploadResult.isIdPRedirection());
        tickerId = (needsToUpdateCredentials) ? R.string.uploader_upload_failed_credentials_error : tickerId;

        mNotificationBuilder.setTicker(getString(tickerId)).setContentTitle(getString(tickerId))
                .setAutoCancel(true).setOngoing(false).setProgress(0, 0, false);

        content = ErrorMessageAdapter.getErrorCauseMessage(uploadResult, upload, getResources());

        if (needsToUpdateCredentials) {
            // let the user update credentials with one click
            Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
            updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, upload.getAccount());
            updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACTION,
                    AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN);
            updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND);
            mNotificationBuilder.setContentIntent(PendingIntent.getActivity(this,
                    (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT));

            mUploadClient = null;
            // grant that future retries on the same account will get the fresh credentials
        } else {
            mNotificationBuilder.setContentText(content);

            if (upload.isInstant()) {
                DbHandler db = null;
                try {
                    db = new DbHandler(this.getBaseContext());
                    String message = uploadResult.getLogMessage() + " errorCode: " + uploadResult.getCode();
                    Log_OC.e(TAG, message + " Http-Code: " + uploadResult.getHttpCode());
                    if (uploadResult.getCode() == ResultCode.QUOTA_EXCEEDED) {
                        //message = getString(R.string.failed_upload_quota_exceeded_text);
                        if (db.updateFileState(upload.getOriginalStoragePath(),
                                DbHandler.UPLOAD_STATUS_UPLOAD_FAILED, message) == 0) {
                            db.putFileForLater(upload.getOriginalStoragePath(), upload.getAccount().name,
                                    message);
                        }
                    }
                } finally {
                    if (db != null) {
                        db.close();
                    }
                }
            }
        }

        mNotificationBuilder.setContentText(content);
        mNotificationManager.notify(tickerId, mNotificationBuilder.build());

        if (uploadResult.isSuccess()) {

            DbHandler db = new DbHandler(this.getBaseContext());
            db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath());
            db.close();

            // remove success notification, with a delay of 2 seconds
            NotificationDelayer.cancelWithDelay(mNotificationManager, R.string.uploader_upload_succeeded_ticker,
                    2000);

        }
    }
}

From source file:com.synox.android.ui.activity.Uploader.java

protected void requestCredentialsUpdate() {
    Intent updateAccountCredentials = new Intent(this, AuthenticatorActivity.class);
    updateAccountCredentials.putExtra(AuthenticatorActivity.EXTRA_ACCOUNT, getAccount())
            .putExtra(AuthenticatorActivity.EXTRA_ACTION, AuthenticatorActivity.ACTION_UPDATE_EXPIRED_TOKEN)
            .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    startActivity(updateAccountCredentials);
}

From source file:org.wso2.emm.agent.services.operationMgt.OperationManager.java

/**
 * Configure device VPN profile.// w ww  .  j  a va 2 s. c  om
 *
 * @param operation - Operation object.
 */
public void configureVPN(org.wso2.emm.agent.beans.Operation operation) throws AndroidAgentException {
    String serverAddress = null;
    JSONObject result = new JSONObject();

    try {
        JSONObject vpnData = new JSONObject(operation.getPayLoad().toString());
        if (!vpnData.isNull(resources.getString(R.string.intent_extra_server))) {
            serverAddress = (String) vpnData.get(resources.getString(R.string.intent_extra_server));
        }

    } catch (JSONException e) {
        operation.setStatus(resources.getString(R.string.operation_value_error));
        resultBuilder.build(operation);
        throw new AndroidAgentException("Invalid JSON format.", e);
    }

    if (serverAddress != null) {
        Intent intent = new Intent(context, AlertActivity.class);
        intent.putExtra(resources.getString(R.string.intent_extra_message),
                resources.getString(R.string.toast_message_vpn));
        intent.putExtra(resources.getString(R.string.intent_extra_operation_id), operation.getId());
        intent.putExtra(resources.getString(R.string.intent_extra_payload), operation.getPayLoad().toString());
        intent.putExtra(resources.getString(R.string.intent_extra_type), Constants.Operation.VPN);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(intent);
    }

    if (Constants.DEBUG_MODE_ENABLED) {
        Log.d(TAG, "VPN configured");
    }
    operation.setStatus(resources.getString(R.string.operation_value_completed));
    operation.setPayLoad(result.toString());
    resultBuilder.build(operation);
}

From source file:org.wso2.iot.agent.services.operation.OperationManager.java

/**
 * Configure device VPN profile.//  w ww  .  ja v a2 s. com
 *
 * @param operation - Operation object.
 */
public void configureVPN(org.wso2.iot.agent.beans.Operation operation) throws AndroidAgentException {
    String serverAddress = null;
    JSONObject result = new JSONObject();

    try {
        JSONObject vpnData = new JSONObject(operation.getPayLoad().toString());
        if (!vpnData.isNull(resources.getString(R.string.intent_extra_server))) {
            serverAddress = (String) vpnData.get(resources.getString(R.string.intent_extra_server));
        }

    } catch (JSONException e) {
        operation.setStatus(resources.getString(R.string.operation_value_error));
        operation.setOperationResponse("Error in parsing VPN payload.");
        resultBuilder.build(operation);
        throw new AndroidAgentException("Invalid JSON format.", e);
    }

    if (serverAddress != null) {
        Intent intent = new Intent(context, AlertActivity.class);
        intent.putExtra(resources.getString(R.string.intent_extra_message_text),
                resources.getString(R.string.toast_message_vpn));
        intent.putExtra(resources.getString(R.string.intent_extra_operation_id), operation.getId());
        intent.putExtra(resources.getString(R.string.intent_extra_payload), operation.getPayLoad().toString());
        intent.putExtra(resources.getString(R.string.intent_extra_type), Constants.Operation.VPN);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(intent);
    }

    if (Constants.DEBUG_MODE_ENABLED) {
        Log.d(TAG, "VPN configured");
    }
    operation.setStatus(resources.getString(R.string.operation_value_completed));
    operation.setPayLoad(result.toString());
    resultBuilder.build(operation);
}

From source file:com.partypoker.poker.engagement.reach.EngagementReachAgent.java

/**
 * Show or refresh loading activity.//from  w  ww. j  a  v a2  s. com
 * @param content campaign being loaded.
 * @param flags additional activity flags.
 */
private void showOrRefreshLoading(EngagementReachContent content, int... flags) {
    Intent intent = new Intent(INTENT_ACTION_LOADING);
    String category = content.getCategory();
    if (category != null)
        intent.addCategory(category);
    filterIntentWithCategory(intent);
    setContentIdExtra(intent, content);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    for (int flag : flags)
        intent.addFlags(flag);
    mContext.startActivity(intent);
}

From source file:org.wso2.emm.agent.services.operation.OperationManager.java

/**
 * Configure device VPN profile.//from  w w w  .  ja v  a2  s .  c o m
 *
 * @param operation - Operation object.
 */
public void configureVPN(org.wso2.emm.agent.beans.Operation operation) throws AndroidAgentException {
    String serverAddress = null;
    JSONObject result = new JSONObject();

    try {
        JSONObject vpnData = new JSONObject(operation.getPayLoad().toString());
        if (!vpnData.isNull(resources.getString(R.string.intent_extra_server))) {
            serverAddress = (String) vpnData.get(resources.getString(R.string.intent_extra_server));
        }

    } catch (JSONException e) {
        operation.setStatus(resources.getString(R.string.operation_value_error));
        operation.setOperationResponse("Error in parsing VPN payload.");
        resultBuilder.build(operation);
        throw new AndroidAgentException("Invalid JSON format.", e);
    }

    if (serverAddress != null) {
        Intent intent = new Intent(context, AlertActivity.class);
        intent.putExtra(resources.getString(R.string.intent_extra_message_text),
                resources.getString(R.string.toast_message_vpn));
        intent.putExtra(resources.getString(R.string.intent_extra_operation_id), operation.getId());
        intent.putExtra(resources.getString(R.string.intent_extra_payload), operation.getPayLoad().toString());
        intent.putExtra(resources.getString(R.string.intent_extra_type), Constants.Operation.VPN);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        context.startActivity(intent);
    }

    if (Constants.DEBUG_MODE_ENABLED) {
        Log.d(TAG, "VPN configured");
    }
    operation.setStatus(resources.getString(R.string.operation_value_completed));
    operation.setPayLoad(result.toString());
    resultBuilder.build(operation);
}

From source file:com.android.mms.transaction.MessagingNotification.java

/**
 * updateNotification is *the* main function for building the actual notification handed to
 * the NotificationManager/*  ww w  .  j ava2s .c  om*/
 * @param context
 * @param newThreadId the new thread id
 * @param uniqueThreadCount
 * @param notificationSet the set of notifications to display
 */
private static void updateNotification(Context context, long newThreadId, int uniqueThreadCount,
        SortedSet<NotificationInfo> notificationSet) {
    boolean isNew = newThreadId != THREAD_NONE;
    CMConversationSettings conversationSettings = CMConversationSettings.getOrNew(context, newThreadId);

    // If the user has turned off notifications in settings, don't do any notifying.
    if ((isNew && !conversationSettings.getNotificationEnabled())
            || !MessagingPreferenceActivity.getNotificationEnabled(context)) {
        if (DEBUG) {
            Log.d(TAG, "updateNotification: notifications turned off in prefs, bailing");
        }
        return;
    }

    // Figure out what we've got -- whether all sms's, mms's, or a mixture of both.
    final int messageCount = notificationSet.size();
    NotificationInfo mostRecentNotification = notificationSet.first();

    final NotificationCompat.Builder noti = new NotificationCompat.Builder(context)
            .setWhen(mostRecentNotification.mTimeMillis);

    if (isNew) {
        noti.setTicker(mostRecentNotification.mTicker);
    }

    // If we have more than one unique thread, change the title (which would
    // normally be the contact who sent the message) to a generic one that
    // makes sense for multiple senders, and change the Intent to take the
    // user to the conversation list instead of the specific thread.

    // Cases:
    //   1) single message from single thread - intent goes to ComposeMessageActivity
    //   2) multiple messages from single thread - intent goes to ComposeMessageActivity
    //   3) messages from multiple threads - intent goes to ConversationList

    final Resources res = context.getResources();
    String title = null;
    Bitmap avatar = null;
    PendingIntent pendingIntent = null;
    boolean isMultiNewMessages = MessageUtils.isMailboxMode() ? messageCount > 1 : uniqueThreadCount > 1;
    if (isMultiNewMessages) { // messages from multiple threads
        Intent mainActivityIntent = getMultiThreadsViewIntent(context);
        pendingIntent = PendingIntent.getActivity(context, 0, mainActivityIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        title = context.getString(R.string.message_count_notification, messageCount);
    } else { // same thread, single or multiple messages
        title = mostRecentNotification.mTitle;
        avatar = mostRecentNotification.mSender.getAvatar(context);
        noti.setSubText(mostRecentNotification.mSimName); // no-op in single SIM case
        if (avatar != null) {
            // Show the sender's avatar as the big icon. Contact bitmaps are 96x96 so we
            // have to scale 'em up to 128x128 to fill the whole notification large icon.
            final int idealIconHeight = res
                    .getDimensionPixelSize(android.R.dimen.notification_large_icon_height);
            final int idealIconWidth = res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width);
            noti.setLargeIcon(BitmapUtil.getRoundedBitmap(avatar, idealIconWidth, idealIconHeight));
        }

        pendingIntent = PendingIntent.getActivity(context, 0, mostRecentNotification.mClickIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }
    // Always have to set the small icon or the notification is ignored
    noti.setSmallIcon(R.drawable.stat_notify_sms);

    NotificationManagerCompat nm = NotificationManagerCompat.from(context);

    // Update the notification.
    noti.setContentTitle(title).setContentIntent(pendingIntent)
            .setColor(context.getResources().getColor(R.color.mms_theme_color))
            .setCategory(Notification.CATEGORY_MESSAGE).setPriority(Notification.PRIORITY_DEFAULT); // TODO: set based on contact coming
                                                                                                                                                                                                                                  // from a favorite.

    // Tag notification with all senders.
    for (NotificationInfo info : notificationSet) {
        Uri peopleReferenceUri = info.mSender.getPeopleReferenceUri();
        if (peopleReferenceUri != null) {
            noti.addPerson(peopleReferenceUri.toString());
        }
    }

    int defaults = 0;

    if (isNew) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);

        if (conversationSettings.getVibrateEnabled()) {
            String pattern = conversationSettings.getVibratePattern();

            if (!TextUtils.isEmpty(pattern)) {
                noti.setVibrate(parseVibratePattern(pattern));
            } else {
                defaults |= Notification.DEFAULT_VIBRATE;
            }
        }

        String ringtoneStr = conversationSettings.getNotificationTone();
        noti.setSound(TextUtils.isEmpty(ringtoneStr) ? null : Uri.parse(ringtoneStr));
        Log.d(TAG, "updateNotification: new message, adding sound to the notification");
    }

    defaults |= Notification.DEFAULT_LIGHTS;

    noti.setDefaults(defaults);

    // set up delete intent
    noti.setDeleteIntent(PendingIntent.getBroadcast(context, 0, sNotificationOnDeleteIntent, 0));

    // See if QuickMessage pop-up support is enabled in preferences
    boolean qmPopupEnabled = MessagingPreferenceActivity.getQuickMessageEnabled(context);

    // Set up the QuickMessage intent
    Intent qmIntent = null;
    if (mostRecentNotification.mIsSms) {
        // QuickMessage support is only for SMS
        qmIntent = new Intent();
        qmIntent.setClass(context, QuickMessagePopup.class);
        qmIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        qmIntent.putExtra(QuickMessagePopup.SMS_FROM_NAME_EXTRA, mostRecentNotification.mSender.getName());
        qmIntent.putExtra(QuickMessagePopup.SMS_FROM_NUMBER_EXTRA, mostRecentNotification.mSender.getNumber());
        qmIntent.putExtra(QuickMessagePopup.SMS_NOTIFICATION_OBJECT_EXTRA, mostRecentNotification);
    }

    // Start getting the notification ready
    final Notification notification;

    //Create a WearableExtender to add actions too
    WearableExtender wearableExtender = new WearableExtender();

    if (messageCount == 1 || uniqueThreadCount == 1) {
        // Add the Quick Reply action only if the pop-up won't be shown already
        if (!qmPopupEnabled && qmIntent != null) {

            // This is a QR, we should show the keyboard when the user taps to reply
            qmIntent.putExtra(QuickMessagePopup.QR_SHOW_KEYBOARD_EXTRA, true);

            // Create the pending intent and add it to the notification
            CharSequence qmText = context.getText(R.string.menu_reply);
            PendingIntent qmPendingIntent = PendingIntent.getActivity(context, 0, qmIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
            noti.addAction(R.drawable.ic_reply, qmText, qmPendingIntent);

            //Wearable
            noti.extend(wearableExtender.addAction(
                    new NotificationCompat.Action.Builder(R.drawable.ic_reply, qmText, qmPendingIntent)
                            .build()));
        }

        // Add the 'Mark as read' action
        CharSequence markReadText = context.getText(R.string.qm_mark_read);
        Intent mrIntent = new Intent();
        mrIntent.setClass(context, QmMarkRead.class);
        mrIntent.putExtra(QmMarkRead.SMS_THREAD_ID, mostRecentNotification.mThreadId);
        PendingIntent mrPendingIntent = PendingIntent.getBroadcast(context, 0, mrIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        noti.addAction(R.drawable.ic_mark_read, markReadText, mrPendingIntent);

        // Add the Call action
        CharSequence callText = context.getText(R.string.menu_call);
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        callIntent.setData(Uri.parse("tel:" + mostRecentNotification.mSender.getNumber()));
        PendingIntent callPendingIntent = PendingIntent.getActivity(context, 0, callIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        noti.addAction(R.drawable.ic_menu_call, callText, callPendingIntent);

        //Wearable
        noti.extend(wearableExtender.addAction(
                new NotificationCompat.Action.Builder(R.drawable.ic_menu_call, callText, callPendingIntent)
                        .build()));

        //Set up remote input
        String replyLabel = context.getString(R.string.qm_wear_voice_reply);
        RemoteInput remoteInput = new RemoteInput.Builder(QuickMessageWear.EXTRA_VOICE_REPLY)
                .setLabel(replyLabel).build();
        //Set up pending intent for voice reply
        Intent voiceReplyIntent = new Intent(context, QuickMessageWear.class);
        voiceReplyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        voiceReplyIntent.putExtra(QuickMessageWear.SMS_CONATCT, mostRecentNotification.mSender.getName());
        voiceReplyIntent.putExtra(QuickMessageWear.SMS_SENDER, mostRecentNotification.mSender.getNumber());
        voiceReplyIntent.putExtra(QuickMessageWear.SMS_THEAD_ID, mostRecentNotification.mThreadId);
        PendingIntent voiceReplyPendingIntent = PendingIntent.getActivity(context, 0, voiceReplyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        //Wearable voice reply action
        NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply,
                context.getString(R.string.qm_wear_reply_by_voice), voiceReplyPendingIntent)
                        .addRemoteInput(remoteInput).build();
        noti.extend(wearableExtender.addAction(action));
    }

    if (messageCount == 1) {
        // We've got a single message

        // This sets the text for the collapsed form:
        noti.setContentText(mostRecentNotification.formatBigMessage(context));

        if (mostRecentNotification.mAttachmentBitmap != null) {
            // The message has a picture, show that

            NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle(noti)
                    .bigPicture(mostRecentNotification.mAttachmentBitmap)
                    .setSummaryText(mostRecentNotification.formatPictureMessage(context));

            notification = noti.setStyle(bigPictureStyle).build();
        } else {
            // Show a single notification -- big style with the text of the whole message
            NotificationCompat.BigTextStyle bigTextStyle1 = new NotificationCompat.BigTextStyle(noti)
                    .bigText(mostRecentNotification.formatBigMessage(context));

            notification = noti.setStyle(bigTextStyle1).build();
        }
        if (DEBUG) {
            Log.d(TAG, "updateNotification: single message notification");
        }
    } else {
        // We've got multiple messages
        if (!isMultiNewMessages) {
            // We've got multiple messages for the same thread.
            // Starting with the oldest new message, display the full text of each message.
            // Begin a line for each subsequent message.
            SpannableStringBuilder buf = new SpannableStringBuilder();
            NotificationInfo infos[] = notificationSet.toArray(new NotificationInfo[messageCount]);
            int len = infos.length;
            for (int i = len - 1; i >= 0; i--) {
                NotificationInfo info = infos[i];

                buf.append(info.formatBigMessage(context));

                if (i != 0) {
                    buf.append('\n');
                }
            }

            noti.setContentText(context.getString(R.string.message_count_notification, messageCount));

            // Show a single notification -- big style with the text of all the messages
            NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
            bigTextStyle.bigText(buf)
                    // Forcibly show the last line, with the app's smallIcon in it, if we
                    // kicked the smallIcon out with an avatar bitmap
                    .setSummaryText((avatar == null) ? null : " ");
            notification = noti.setStyle(bigTextStyle).build();
            if (DEBUG) {
                Log.d(TAG, "updateNotification: multi messages for single thread");
            }
        } else {
            // Build a set of the most recent notification per threadId.
            HashSet<Long> uniqueThreads = new HashSet<Long>(messageCount);
            ArrayList<NotificationInfo> mostRecentNotifPerThread = new ArrayList<NotificationInfo>();
            Iterator<NotificationInfo> notifications = notificationSet.iterator();
            while (notifications.hasNext()) {
                NotificationInfo notificationInfo = notifications.next();
                if (!uniqueThreads.contains(notificationInfo.mThreadId)) {
                    uniqueThreads.add(notificationInfo.mThreadId);
                    mostRecentNotifPerThread.add(notificationInfo);
                }
            }
            // When collapsed, show all the senders like this:
            //     Fred Flinstone, Barry Manilow, Pete...
            noti.setContentText(formatSenders(context, mostRecentNotifPerThread));
            NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(noti);

            // We have to set the summary text to non-empty so the content text doesn't show
            // up when expanded.
            inboxStyle.setSummaryText(" ");

            // At this point we've got multiple messages in multiple threads. We only
            // want to show the most recent message per thread, which are in
            // mostRecentNotifPerThread.
            int uniqueThreadMessageCount = mostRecentNotifPerThread.size();
            int maxMessages = Math.min(MAX_MESSAGES_TO_SHOW, uniqueThreadMessageCount);

            for (int i = 0; i < maxMessages; i++) {
                NotificationInfo info = mostRecentNotifPerThread.get(i);
                inboxStyle.addLine(info.formatInboxMessage(context));
            }
            notification = inboxStyle.build();

            uniqueThreads.clear();
            mostRecentNotifPerThread.clear();

            if (DEBUG) {
                Log.d(TAG, "updateNotification: multi messages," + " showing inboxStyle notification");
            }
        }
    }

    notifyUserIfFullScreen(context, title);
    nm.notify(NOTIFICATION_ID, notification);

    // Trigger the QuickMessage pop-up activity if enabled
    // But don't show the QuickMessage if the user is in a call or the phone is ringing
    if (qmPopupEnabled && qmIntent != null) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE && !ConversationList.mIsRunning
                && !ComposeMessageActivity.mIsRunning) {
            context.startActivity(qmIntent);
        }
    }
}