Example usage for android.text.style StyleSpan StyleSpan

List of usage examples for android.text.style StyleSpan StyleSpan

Introduction

In this page you can find the example usage for android.text.style StyleSpan StyleSpan.

Prototype

public StyleSpan(@NonNull Parcel src) 

Source Link

Document

Creates a StyleSpan from a parcel.

Usage

From source file:org.awesomeapp.messenger.ui.MessageListItem.java

private CharSequence formatPresenceUpdates(String contact, int type, Date date, boolean isGroupChat,
        boolean scrolling) {
    String body;//from   w w  w.  j a v a  2s . c  o m

    Resources resources = getResources();

    switch (type) {
    case Imps.MessageType.PRESENCE_AVAILABLE:
        body = resources.getString(isGroupChat ? R.string.contact_joined : R.string.contact_online, contact);
        break;

    case Imps.MessageType.PRESENCE_AWAY:
        body = resources.getString(R.string.contact_away, contact);
        break;

    case Imps.MessageType.PRESENCE_DND:
        body = resources.getString(R.string.contact_busy, contact);
        break;

    case Imps.MessageType.PRESENCE_UNAVAILABLE:
        body = resources.getString(isGroupChat ? R.string.contact_left : R.string.contact_offline, contact);
        break;

    default:
        return null;
    }

    body += " - ";
    body += formatTimeStamp(date, type, null, EncryptionState.NONE, null);

    if (scrolling) {
        return body;
    } else {
        SpannableString spanText = new SpannableString(body);
        int len = spanText.length();
        spanText.setSpan(new StyleSpan(Typeface.ITALIC), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        spanText.setSpan(new RelativeSizeSpan((float) 0.8), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spanText;
    }
}

From source file:org.miaowo.miaowo.util.Html.java

private static void endHeading(Editable text) {
    // RelativeSizeSpan and StyleSpan are CharacterStyles
    // Their ranges should not include the newlines at the end
    Heading h = getLast(text, Heading.class);
    if (h != null) {
        setSpanFromMark(text, h, new RelativeSizeSpan(HEADING_SIZES[h.mLevel]), new StyleSpan(Typeface.BOLD));
    }//from w ww.  ja  v a2  s  .c o m

    endBlockElement(text);
}

From source file:com.juick.android.JuickMessagesAdapter.java

private static void setStyleSpans(SpannableStringBuilder ssb, int ssbOffset, Object what, String styleChar) {
    String txt;/*from   www  . j  a  v a2  s. co  m*/
    txt = ssb.subSequence(ssbOffset, ssb.length()).toString();
    txt = " " + txt + " ";
    ssbOffset -= 1;
    //
    int scan = 0;
    int cnt = 0;
    while (cnt++ < 20) { // don't need bugs in production.
        int ix = txt.indexOf(styleChar, scan);
        if (ix < 0)
            break;
        if (" \n".indexOf(txt.charAt(ix - 1)) != -1) {
            int ix2 = txt.indexOf(styleChar, ix + 1);
            if (ix2 < 0)
                break;
            if (" \n".indexOf(txt.charAt(ix2 + 1)) == -1 // not ends with space
                    || txt.substring(ix, ix2).indexOf("\n") != -1) { // spans several lines
                scan = ix2; // not ok
                continue;
            } else {
                CharacterStyle span = null;
                CharacterStyle span2 = null;
                // found needed stuff
                if (what instanceof Integer && (((Integer) what) == Typeface.BOLD)) {
                    span = new StyleSpan(Typeface.BOLD);
                    if (helvNueFonts) {
                        span2 = new CustomTypefaceSpan("", JuickAdvancedApplication.helvNueBold);
                    }
                }
                if (what instanceof Integer && (((Integer) what) == Typeface.ITALIC)) {
                    span = new StyleSpan(Typeface.ITALIC);
                }
                if (what == UnderlineSpan.class) {
                    span = new UnderlineSpan();
                }
                if (span != null && ix2 - ix > 1) {
                    ssb.delete(ssbOffset + ix, ssbOffset + ix + 1); // delete styling char
                    txt = stringDelete(txt, ix, ix + 1);
                    ix2--; // moves, too
                    ssb.delete(ssbOffset + ix2, ssbOffset + ix2 + 1); // second char deleted
                    txt = stringDelete(txt, ix2, ix2 + 1);
                    ssb.setSpan(span, ssbOffset + ix, ssbOffset + ix2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    if (span2 != null) {
                        ssb.setSpan(span2, ssbOffset + ix, ssbOffset + ix2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                }
                scan = ix2;
            }
        }
    }
}

From source file:org.sirimangalo.meditationplus.ActivityMain.java

private void populateOnline(JSONArray onlines) {

    if (onlines.length() == 0) {
        onlineList.setVisibility(View.GONE);
        return;//  ww w  . ja  va 2  s .  c  om
    }

    onlineList.setVisibility(View.VISIBLE);

    ArrayList<JSONObject> onlineArray = new ArrayList<JSONObject>();
    ArrayList<String> onlineNamesArray = new ArrayList<String>();

    // collect into array

    for (int i = 0; i < onlines.length(); i++) {
        try {
            JSONObject a = onlines.getJSONObject(i);
            onlineArray.add(a);
            onlineNamesArray.add(a.getString("username"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    String text = getString(R.string.online) + " ";

    // add spans

    int pos = text.length(); // start after "Online: "

    text += TextUtils.join(", ", onlineNamesArray);
    Spannable span = new SpannableString(text);

    span.setSpan(new StyleSpan(Typeface.BOLD), 0, pos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // bold the "Online: "

    Drawable android = context.getResources().getDrawable(R.drawable.android);
    android.setBounds(0, 0, 48, 32);

    for (JSONObject oneOnA : onlineArray) {
        try {
            final String oneOn = oneOnA.getString("username");

            int end = pos + oneOn.length();

            boolean isMed = false;

            for (int j = 0; j < jsonList.length(); j++) {
                JSONObject user = jsonList.getJSONObject(j);
                String username = user.getString("username");
                if (username.equals(oneOn))
                    isMed = true;
            }

            if (oneOnA.getString("source").equals("android")) {
                ImageSpan image = new ImageSpan(android, ImageSpan.ALIGN_BASELINE);
                span.setSpan(image, pos - 1, pos, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
            }

            ClickableSpan clickable = new ClickableSpan() {

                @Override
                public void onClick(View widget) {
                    showProfile(oneOn);
                }

            };
            span.setSpan(clickable, pos, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

            span.setSpan(new UnderlineSpan() {
                public void updateDrawState(TextPaint tp) {
                    tp.setUnderlineText(false);
                }
            }, pos, end, 0);

            span.setSpan(new ForegroundColorSpan(isMed ? 0xFF009900 : 0xFFFF9900), pos, end,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            pos += oneOn.length() + 2;

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    onlineList.setText(span);
    onlineList.setMovementMethod(LinkMovementMethod.getInstance());

}

From source file:org.getlantern.firetweet.provider.FiretweetDataProvider.java

private void showMentionsNotification(AccountPreferences pref, long position) {
    final long accountId = pref.getAccountId();
    final Context context = getContext();
    final Resources resources = context.getResources();
    final NotificationManager nm = getNotificationManager();
    final Expression selection;
    if (pref.isNotificationFollowingOnly()) {
        selection = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
                Expression.greaterThan(Statuses.STATUS_ID, position),
                Expression.equals(Statuses.IS_FOLLOWING, 1));
    } else {/*from  w w  w.ja v  a  2 s .  c  o m*/
        selection = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, accountId),
                Expression.greaterThan(Statuses.STATUS_ID, position));
    }
    final String filteredSelection = Utils.buildStatusFilterWhereClause(Mentions.TABLE_NAME, selection)
            .getSQL();
    final String[] userProjection = { Statuses.USER_ID, Statuses.USER_NAME, Statuses.USER_SCREEN_NAME };
    final String[] statusProjection = { Statuses.STATUS_ID, Statuses.USER_ID, Statuses.USER_NAME,
            Statuses.USER_SCREEN_NAME, Statuses.TEXT_UNESCAPED, Statuses.STATUS_TIMESTAMP };
    final Cursor statusCursor = mDatabaseWrapper.query(Mentions.TABLE_NAME, statusProjection, filteredSelection,
            null, null, null, Statuses.SORT_ORDER_TIMESTAMP_DESC);
    final Cursor userCursor = mDatabaseWrapper.query(Mentions.TABLE_NAME, userProjection, filteredSelection,
            null, Statuses.USER_ID, null, Statuses.SORT_ORDER_TIMESTAMP_DESC);
    try {
        final int usersCount = userCursor.getCount();
        final int statusesCount = statusCursor.getCount();
        if (statusesCount == 0 || usersCount == 0)
            return;
        final String accountName = Utils.getAccountName(context, accountId);
        final String accountScreenName = Utils.getAccountScreenName(context, accountId);
        final int idxStatusText = statusCursor.getColumnIndex(Statuses.TEXT_UNESCAPED),
                idxStatusId = statusCursor.getColumnIndex(Statuses.STATUS_ID),
                idxStatusTimestamp = statusCursor.getColumnIndex(Statuses.STATUS_TIMESTAMP),
                idxStatusUserName = statusCursor.getColumnIndex(Statuses.USER_NAME),
                idxStatusUserScreenName = statusCursor.getColumnIndex(Statuses.USER_SCREEN_NAME),
                idxUserName = userCursor.getColumnIndex(Statuses.USER_NAME),
                idxUserScreenName = userCursor.getColumnIndex(Statuses.USER_NAME),
                idxUserId = userCursor.getColumnIndex(Statuses.USER_NAME);

        final CharSequence notificationTitle = resources.getQuantityString(R.plurals.N_new_mentions,
                statusesCount, statusesCount);
        final String notificationContent;
        userCursor.moveToFirst();
        final String displayName = UserColorNameUtils.getUserNickname(context, userCursor.getLong(idxUserId),
                mNameFirst ? userCursor.getString(idxUserName) : userCursor.getString(idxUserScreenName));
        if (usersCount == 1) {
            notificationContent = context.getString(R.string.notification_mention, displayName);
        } else {
            notificationContent = context.getString(R.string.notification_mention_multiple, displayName,
                    usersCount - 1);
        }

        // Add rich notification and get latest tweet timestamp
        long when = -1, statusId = -1;
        final InboxStyle style = new InboxStyle();
        for (int i = 0, j = Math.min(statusesCount, 5); statusCursor.moveToPosition(i) && i < j; i++) {
            if (when == -1) {
                when = statusCursor.getLong(idxStatusTimestamp);
            }
            if (statusId == -1) {
                statusId = statusCursor.getLong(idxStatusId);
            }
            final SpannableStringBuilder sb = new SpannableStringBuilder();
            sb.append(UserColorNameUtils.getUserNickname(context, statusCursor.getLong(idxUserId),
                    mNameFirst ? statusCursor.getString(idxStatusUserName)
                            : statusCursor.getString(idxStatusUserScreenName)));
            sb.setSpan(new StyleSpan(Typeface.BOLD), 0, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            sb.append(' ');
            sb.append(statusCursor.getString(idxStatusText));
            style.addLine(sb);
        }
        if (mNameFirst) {
            style.setSummaryText(accountName);
        } else {
            style.setSummaryText("@" + accountScreenName);
        }

        // Setup notification
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_stat_mention);
        builder.setTicker(notificationTitle);
        builder.setContentTitle(notificationTitle);
        builder.setContentText(notificationContent);
        builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
        builder.setContentIntent(getContentIntent(context, AUTHORITY_MENTIONS, accountId));
        builder.setDeleteIntent(getDeleteIntent(context, AUTHORITY_MENTIONS, accountId, statusId));
        builder.setNumber(statusesCount);
        builder.setWhen(when);
        builder.setStyle(style);
        builder.setColor(pref.getNotificationLightColor());
        setNotificationPreferences(builder, pref, pref.getMentionsNotificationType());
        nm.notify("mentions_" + accountId, NOTIFICATION_ID_MENTIONS_TIMELINE, builder.build());
        Utils.sendPebbleNotification(context, notificationContent);
    } finally {
        statusCursor.close();
        userCursor.close();
    }
}

From source file:com.android.messaging.datamodel.BugleNotifications.java

/**
 * buildBoldedMessage - build a formatted message where the title is bold, there's a
 * separator, then the message.//www.  j ava  2 s  .c  o  m
 */
private static CharSequence buildBoldedMessage(final String title, final CharSequence message,
        final Uri attachmentUri, final String attachmentType, final int separatorId) {
    final Context context = Factory.get().getApplicationContext();
    final SpannableStringBuilder spanBuilder = new SpannableStringBuilder();

    // Boldify the title (which is the sender's name)
    if (!TextUtils.isEmpty(title)) {
        spanBuilder.append(title);
        spanBuilder.setSpan(new StyleSpan(Typeface.BOLD), 0, title.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
    if (!TextUtils.isEmpty(message)) {
        if (spanBuilder.length() > 0) {
            spanBuilder.append(context.getString(separatorId));
        }
        spanBuilder.append(message);
    }
    if (attachmentUri != null) {
        if (spanBuilder.length() > 0) {
            final String separator = context.getString(R.string.notification_separator);
            spanBuilder.append(separator);
        }
        spanBuilder.append(formatAttachmentTag(null, attachmentType));
    }
    return spanBuilder;
}

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

protected static CharSequence buildTickerMessage(Context context, String address, String subject, String body) {
    String displayAddress = Contact.get(address, true).getName();

    StringBuilder buf = new StringBuilder(
            displayAddress == null ? "" : displayAddress.replace('\n', ' ').replace('\r', ' '));
    buf.append(':').append(' ');

    int offset = buf.length();
    if (!TextUtils.isEmpty(subject)) {
        subject = subject.replace('\n', ' ').replace('\r', ' ');
        buf.append(subject);/*from   w w w .ja v  a2  s.c om*/
        buf.append(' ');
    }

    if (!TextUtils.isEmpty(body)) {
        body = body.replace('\n', ' ').replace('\r', ' ');
        buf.append(body);
    }

    SpannableString spanText = new SpannableString(buf.toString());
    spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    return spanText;
}

From source file:org.getlantern.firetweet.provider.FiretweetDataProvider.java

private void showMessagesNotification(AccountPreferences pref, StringLongPair[] pairs,
        ContentValues[] valuesArray) {/*  w ww .ja  va 2s.  c  o m*/
    final long accountId = pref.getAccountId();
    final long prevOldestId = mReadStateManager.getPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountId));
    long oldestId = -1;
    for (final ContentValues contentValues : valuesArray) {
        final long messageId = contentValues.getAsLong(DirectMessages.MESSAGE_ID);
        oldestId = oldestId < 0 ? messageId : Math.min(oldestId, messageId);
        if (messageId <= prevOldestId)
            return;
    }
    mReadStateManager.setPosition(TAG_OLDEST_MESSAGES, String.valueOf(accountId), oldestId, false);
    final Context context = getContext();
    final Resources resources = context.getResources();
    final NotificationManager nm = getNotificationManager();
    final ArrayList<Expression> orExpressions = new ArrayList<>();
    final String prefix = accountId + "-";
    final int prefixLength = prefix.length();
    final Set<Long> senderIds = new CompactHashSet<>();
    for (StringLongPair pair : pairs) {
        final String key = pair.getKey();
        if (key.startsWith(prefix)) {
            final long senderId = Long.parseLong(key.substring(prefixLength));
            senderIds.add(senderId);
            final Expression expression = Expression.and(Expression.equals(DirectMessages.SENDER_ID, senderId),
                    Expression.greaterThan(DirectMessages.MESSAGE_ID, pair.getValue()));
            orExpressions.add(expression);
        }
    }
    orExpressions
            .add(Expression.notIn(new Column(DirectMessages.SENDER_ID), new RawItemArray(senderIds.toArray())));
    final Expression selection = Expression.and(Expression.equals(DirectMessages.ACCOUNT_ID, accountId),
            Expression.greaterThan(DirectMessages.MESSAGE_ID, prevOldestId),
            Expression.or(orExpressions.toArray(new Expression[orExpressions.size()])));
    final String filteredSelection = selection.getSQL();
    final String[] userProjection = { DirectMessages.SENDER_ID, DirectMessages.SENDER_NAME,
            DirectMessages.SENDER_SCREEN_NAME };
    final String[] messageProjection = { DirectMessages.MESSAGE_ID, DirectMessages.SENDER_ID,
            DirectMessages.SENDER_NAME, DirectMessages.SENDER_SCREEN_NAME, DirectMessages.TEXT_UNESCAPED,
            DirectMessages.MESSAGE_TIMESTAMP };
    final Cursor messageCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME, messageProjection,
            filteredSelection, null, null, null, DirectMessages.DEFAULT_SORT_ORDER);
    final Cursor userCursor = mDatabaseWrapper.query(DirectMessages.Inbox.TABLE_NAME, userProjection,
            filteredSelection, null, DirectMessages.SENDER_ID, null, DirectMessages.DEFAULT_SORT_ORDER);
    try {
        final int usersCount = userCursor.getCount();
        final int messagesCount = messageCursor.getCount();
        if (messagesCount == 0 || usersCount == 0)
            return;
        final String accountName = Utils.getAccountName(context, accountId);
        final String accountScreenName = Utils.getAccountScreenName(context, accountId);
        final int idxMessageText = messageCursor.getColumnIndex(DirectMessages.TEXT_UNESCAPED),
                idxMessageTimestamp = messageCursor.getColumnIndex(DirectMessages.MESSAGE_TIMESTAMP),
                idxMessageId = messageCursor.getColumnIndex(DirectMessages.MESSAGE_ID),
                idxMessageUserId = messageCursor.getColumnIndex(DirectMessages.SENDER_ID),
                idxMessageUserName = messageCursor.getColumnIndex(DirectMessages.SENDER_NAME),
                idxMessageUserScreenName = messageCursor.getColumnIndex(DirectMessages.SENDER_SCREEN_NAME),
                idxUserName = userCursor.getColumnIndex(DirectMessages.SENDER_NAME),
                idxUserScreenName = userCursor.getColumnIndex(DirectMessages.SENDER_NAME),
                idxUserId = userCursor.getColumnIndex(DirectMessages.SENDER_NAME);

        final CharSequence notificationTitle = resources.getQuantityString(R.plurals.N_new_messages,
                messagesCount, messagesCount);
        final String notificationContent;
        userCursor.moveToFirst();
        final String displayName = UserColorNameUtils.getUserNickname(context, userCursor.getLong(idxUserId),
                mNameFirst ? userCursor.getString(idxUserName) : userCursor.getString(idxUserScreenName));
        if (usersCount == 1) {
            if (messagesCount == 1) {
                notificationContent = context.getString(R.string.notification_direct_message, displayName);
            } else {
                notificationContent = context.getString(R.string.notification_direct_message_multiple_messages,
                        displayName, messagesCount);
            }
        } else {
            notificationContent = context.getString(R.string.notification_direct_message_multiple_users,
                    displayName, usersCount - 1, messagesCount);
        }

        final LongSparseArray<Long> idsMap = new LongSparseArray<>();
        // Add rich notification and get latest tweet timestamp
        long when = -1;
        final InboxStyle style = new InboxStyle();
        for (int i = 0; messageCursor.moveToPosition(i) && i < messagesCount; i++) {
            if (when < 0) {
                when = messageCursor.getLong(idxMessageTimestamp);
            }
            if (i < 5) {
                final SpannableStringBuilder sb = new SpannableStringBuilder();
                sb.append(UserColorNameUtils.getUserNickname(context, messageCursor.getLong(idxUserId),
                        mNameFirst ? messageCursor.getString(idxMessageUserName)
                                : messageCursor.getString(idxMessageUserScreenName)));
                sb.setSpan(new StyleSpan(Typeface.BOLD), 0, sb.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                sb.append(' ');
                sb.append(messageCursor.getString(idxMessageText));
                style.addLine(sb);
            }
            final long userId = messageCursor.getLong(idxMessageUserId);
            final long messageId = messageCursor.getLong(idxMessageId);
            idsMap.put(userId, Math.max(idsMap.get(userId, -1L), messageId));
        }
        if (mNameFirst) {
            style.setSummaryText(accountName);
        } else {
            style.setSummaryText("@" + accountScreenName);
        }
        final StringLongPair[] positions = new StringLongPair[idsMap.size()];
        for (int i = 0, j = idsMap.size(); i < j; i++) {
            positions[i] = new StringLongPair(String.valueOf(idsMap.keyAt(i)), idsMap.valueAt(i));
        }

        // Setup notification
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
        builder.setAutoCancel(true);
        builder.setSmallIcon(R.drawable.ic_stat_direct_message);
        builder.setTicker(notificationTitle);
        builder.setContentTitle(notificationTitle);
        builder.setContentText(notificationContent);
        builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
        builder.setContentIntent(getContentIntent(context, AUTHORITY_DIRECT_MESSAGES, accountId));
        builder.setContentIntent(getDeleteIntent(context, AUTHORITY_DIRECT_MESSAGES, accountId, positions));
        builder.setNumber(messagesCount);
        builder.setWhen(when);
        builder.setStyle(style);
        builder.setColor(pref.getNotificationLightColor());
        setNotificationPreferences(builder, pref, pref.getDirectMessagesNotificationType());
        nm.notify("messages_" + accountId, NOTIFICATION_ID_DIRECT_MESSAGES, builder.build());
        Utils.sendPebbleNotification(context, notificationContent);
    } finally {
        messageCursor.close();
        userCursor.close();
    }
}

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

protected static CharSequence buildTickerMessage(Context context, String address, String subject, String body) {
    String displayAddress = Contact.get(address, true).getName();

    StringBuilder buf = new StringBuilder(
            displayAddress == null ? "" : displayAddress.replace('\n', ' ').replace('\r', ' '));
    if (!TextUtils.isEmpty(subject) && !TextUtils.isEmpty(body)) {
        buf.append(':').append(' ');
    }// w w w .j a va 2s  . co  m

    int offset = buf.length();
    if (!TextUtils.isEmpty(subject)) {
        subject = subject.replace('\n', ' ').replace('\r', ' ');
        buf.append(subject);
        buf.append(' ');
    }

    if (!TextUtils.isEmpty(body)) {
        body = body.replace('\n', ' ').replace('\r', ' ');
        buf.append(body);
    }

    SpannableString spanText = new SpannableString(buf.toString());
    spanText.setSpan(new StyleSpan(Typeface.BOLD), 0, offset, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    return spanText;
}

From source file:ru.valle.btc.MainActivity.java

private void tryToGenerateSpendingTransaction() {
    final ArrayList<UnspentOutputInfo> unspentOutputs = verifiedUnspentOutputsForTx;
    final String outputAddress = verifiedRecipientAddressForTx;
    final long requestedAmountToSend = verifiedAmountToSendForTx;
    final KeyPair keyPair = verifiedKeyPairForTx;
    final boolean inputsComesFromJson = verifiedUnspentOutputsComesFromJson;
    final int predefinedConfirmationsCount = verifiedConfirmationsCount;

    spendTxDescriptionView.setVisibility(View.GONE);
    spendTxWarningView.setVisibility(View.GONE);
    spendTxEdit.setText("");
    spendTxEdit.setVisibility(View.GONE);
    sendTxInBrowserButton.setVisibility(View.GONE);
    findViewById(R.id.spend_tx_required_age_for_free_tx).setVisibility(View.GONE);
    //        https://blockchain.info/pushtx

    if (unspentOutputs != null && !unspentOutputs.isEmpty() && !TextUtils.isEmpty(outputAddress)
            && keyPair != null && requestedAmountToSend >= SEND_MAX && requestedAmountToSend != 0
            && !TextUtils.isEmpty(keyPair.address)) {
        cancelAllRunningTasks();/*from w w  w  .  ja  va  2  s . c  o m*/
        generateTransactionTask = new AsyncTask<Void, Void, GenerateTransactionResult>() {

            @Override
            protected GenerateTransactionResult doInBackground(Void... voids) {
                final Transaction spendTx;
                try {
                    long availableAmount = 0;
                    for (UnspentOutputInfo unspentOutputInfo : unspentOutputs) {
                        availableAmount += unspentOutputInfo.value;
                    }
                    long amount;
                    if (availableAmount == requestedAmountToSend || requestedAmountToSend == SEND_MAX) {
                        //transfer maximum possible amount
                        amount = -1;
                    } else {
                        amount = requestedAmountToSend;
                    }
                    long extraFee;
                    SharedPreferences preferences = PreferenceManager
                            .getDefaultSharedPreferences(MainActivity.this);
                    try {
                        extraFee = preferences.getLong(PreferencesActivity.PREF_EXTRA_FEE,
                                FeePreference.PREF_EXTRA_FEE_DEFAULT);
                    } catch (ClassCastException e) {
                        preferences.edit().remove(PreferencesActivity.PREF_EXTRA_FEE)
                                .putLong(PreferencesActivity.PREF_EXTRA_FEE,
                                        FeePreference.PREF_EXTRA_FEE_DEFAULT)
                                .commit();
                        extraFee = FeePreference.PREF_EXTRA_FEE_DEFAULT;
                    }
                    spendTx = BTCUtils.createTransaction(unspentOutputs, outputAddress, keyPair.address, amount,
                            extraFee, keyPair.publicKey, keyPair.privateKey);

                    //6. double check that generated transaction is valid
                    Transaction.Script[] relatedScripts = new Transaction.Script[spendTx.inputs.length];
                    for (int i = 0; i < spendTx.inputs.length; i++) {
                        Transaction.Input input = spendTx.inputs[i];
                        for (UnspentOutputInfo unspentOutput : unspentOutputs) {
                            if (Arrays.equals(unspentOutput.txHash, input.outPoint.hash)
                                    && unspentOutput.outputIndex == input.outPoint.index) {
                                relatedScripts[i] = unspentOutput.script;
                                break;
                            }
                        }
                    }
                    BTCUtils.verify(relatedScripts, spendTx);
                } catch (BitcoinException e) {
                    switch (e.errorCode) {
                    case BitcoinException.ERR_INSUFFICIENT_FUNDS:
                        return new GenerateTransactionResult(getString(R.string.error_not_enough_funds),
                                GenerateTransactionResult.ERROR_SOURCE_AMOUNT_FIELD);
                    case BitcoinException.ERR_FEE_IS_TOO_BIG:
                        return new GenerateTransactionResult(getString(R.string.generated_tx_have_too_big_fee),
                                GenerateTransactionResult.ERROR_SOURCE_INPUT_TX_FIELD);
                    case BitcoinException.ERR_MEANINGLESS_OPERATION://input, output and change addresses are same.
                        return new GenerateTransactionResult(getString(R.string.output_address_same_as_input),
                                GenerateTransactionResult.ERROR_SOURCE_ADDRESS_FIELD);
                    //                            case BitcoinException.ERR_INCORRECT_PASSWORD
                    //                            case BitcoinException.ERR_WRONG_TYPE:
                    //                            case BitcoinException.ERR_FEE_IS_LESS_THEN_ZERO
                    //                            case BitcoinException.ERR_CHANGE_IS_LESS_THEN_ZERO
                    //                            case BitcoinException.ERR_AMOUNT_TO_SEND_IS_LESS_THEN_ZERO
                    default:
                        return new GenerateTransactionResult(
                                getString(R.string.error_failed_to_create_transaction) + ": " + e.getMessage(),
                                GenerateTransactionResult.ERROR_SOURCE_UNKNOWN);
                    }
                } catch (Exception e) {
                    return new GenerateTransactionResult(
                            getString(R.string.error_failed_to_create_transaction) + ": " + e,
                            GenerateTransactionResult.ERROR_SOURCE_UNKNOWN);
                }

                long inValue = 0;
                for (Transaction.Input input : spendTx.inputs) {
                    for (UnspentOutputInfo unspentOutput : unspentOutputs) {
                        if (Arrays.equals(unspentOutput.txHash, input.outPoint.hash)
                                && unspentOutput.outputIndex == input.outPoint.index) {
                            inValue += unspentOutput.value;
                        }
                    }
                }
                long outValue = 0;
                for (Transaction.Output output : spendTx.outputs) {
                    outValue += output.value;
                }
                long fee = inValue - outValue;
                return new GenerateTransactionResult(spendTx, fee);
            }

            @Override
            protected void onPostExecute(GenerateTransactionResult result) {
                super.onPostExecute(result);
                generateTransactionTask = null;
                if (result != null) {
                    final TextView rawTxToSpendErr = (TextView) findViewById(R.id.err_raw_tx);
                    if (result.tx != null) {
                        String amountStr = null;
                        Transaction.Script out = null;
                        try {
                            out = Transaction.Script.buildOutput(outputAddress);
                        } catch (BitcoinException ignore) {
                        }
                        if (result.tx.outputs[0].script.equals(out)) {
                            amountStr = BTCUtils.formatValue(result.tx.outputs[0].value);
                        }
                        if (amountStr == null) {
                            rawTxToSpendErr.setText(R.string.error_unknown);
                        } else {
                            String descStr;
                            String feeStr = BTCUtils.formatValue(result.fee);
                            String changeStr;
                            if (result.tx.outputs.length == 1) {
                                changeStr = null;
                                descStr = getString(R.string.spend_tx_description, amountStr, keyPair.address,
                                        outputAddress, feeStr);
                            } else if (result.tx.outputs.length == 2) {
                                changeStr = BTCUtils.formatValue(result.tx.outputs[1].value);
                                descStr = getString(R.string.spend_tx_with_change_description, amountStr,
                                        keyPair.address, outputAddress, feeStr, changeStr);
                            } else {
                                throw new RuntimeException();
                            }
                            SpannableStringBuilder descBuilder = new SpannableStringBuilder(descStr);

                            int spanBegin = descStr.indexOf(keyPair.address);
                            if (spanBegin >= 0) {//from
                                ForegroundColorSpan addressColorSpan = new ForegroundColorSpan(
                                        getColor(MainActivity.this, R.color.dark_orange));
                                descBuilder.setSpan(addressColorSpan, spanBegin,
                                        spanBegin + keyPair.address.length(),
                                        SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
                            }
                            if (spanBegin >= 0) {
                                spanBegin = descStr.indexOf(keyPair.address, spanBegin + 1);
                                if (spanBegin >= 0) {//change
                                    ForegroundColorSpan addressColorSpan = new ForegroundColorSpan(
                                            getColor(MainActivity.this, R.color.dark_orange));
                                    descBuilder.setSpan(addressColorSpan, spanBegin,
                                            spanBegin + keyPair.address.length(),
                                            SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
                                }
                            }
                            spanBegin = descStr.indexOf(outputAddress);
                            if (spanBegin >= 0) {//dest
                                ForegroundColorSpan addressColorSpan = new ForegroundColorSpan(
                                        getColor(MainActivity.this, R.color.dark_green));
                                descBuilder.setSpan(addressColorSpan, spanBegin,
                                        spanBegin + outputAddress.length(),
                                        SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
                            }
                            final String nbspBtc = "\u00a0BTC";
                            spanBegin = descStr.indexOf(amountStr + nbspBtc);
                            if (spanBegin >= 0) {
                                descBuilder.setSpan(new StyleSpan(Typeface.BOLD), spanBegin,
                                        spanBegin + amountStr.length() + nbspBtc.length(),
                                        SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
                            }
                            spanBegin = descStr.indexOf(feeStr + nbspBtc, spanBegin);
                            if (spanBegin >= 0) {
                                descBuilder.setSpan(new StyleSpan(Typeface.BOLD), spanBegin,
                                        spanBegin + feeStr.length() + nbspBtc.length(),
                                        SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
                            }
                            if (changeStr != null) {
                                spanBegin = descStr.indexOf(changeStr + nbspBtc, spanBegin);
                                if (spanBegin >= 0) {
                                    descBuilder.setSpan(new StyleSpan(Typeface.BOLD), spanBegin,
                                            spanBegin + changeStr.length() + nbspBtc.length(),
                                            SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
                                }
                            }
                            spendTxDescriptionView.setText(descBuilder);
                            spendTxDescriptionView.setVisibility(View.VISIBLE);
                            spendTxWarningView.setVisibility(View.VISIBLE);
                            spendTxEdit.setText(BTCUtils.toHex(result.tx.getBytes()));
                            spendTxEdit.setVisibility(View.VISIBLE);
                            sendTxInBrowserButton.setVisibility(View.VISIBLE);

                            TextView maxAgeView = (TextView) findViewById(
                                    R.id.spend_tx_required_age_for_free_tx);
                            CheckBox maxAgeCheckBox = (CheckBox) findViewById(
                                    R.id.spend_tx_required_age_for_free_tx_checkbox);
                            if (!inputsComesFromJson) {
                                if (!showNotEligibleForNoFeeBecauseOfBasicConstrains(maxAgeView, result.tx)) {
                                    final int confirmations = (int) (BTCUtils.MIN_PRIORITY_FOR_NO_FEE
                                            * result.tx.getBytes().length / unspentOutputs.get(0).value);
                                    float daysFloat = confirmations / BTCUtils.EXPECTED_BLOCKS_PER_DAY;
                                    String timePeriodStr;
                                    if (daysFloat <= 1) {
                                        int hours = (int) Math.round(Math.ceil(daysFloat / 24));
                                        timePeriodStr = getResources().getQuantityString(R.plurals.hours, hours,
                                                hours);
                                    } else {
                                        int days = (int) Math.round(Math.ceil(daysFloat));
                                        timePeriodStr = getResources().getQuantityString(R.plurals.days, days,
                                                days);
                                    }
                                    maxAgeCheckBox.setText(getString(R.string.input_tx_is_old_enough,
                                            getResources().getQuantityString(R.plurals.confirmations,
                                                    confirmations, confirmations),
                                            timePeriodStr));
                                    maxAgeCheckBox.setVisibility(View.VISIBLE);
                                    maxAgeCheckBox.setOnCheckedChangeListener(null);
                                    maxAgeCheckBox.setChecked(predefinedConfirmationsCount > 0);
                                    maxAgeCheckBox.setOnCheckedChangeListener(
                                            new CompoundButton.OnCheckedChangeListener() {
                                                @Override
                                                public void onCheckedChanged(CompoundButton buttonView,
                                                        boolean isChecked) {
                                                    verifiedConfirmationsCount = isChecked ? confirmations : -1;
                                                    onUnspentOutputsInfoChanged();
                                                }
                                            });
                                } else {
                                    maxAgeCheckBox.setVisibility(View.GONE);
                                }
                            } else {
                                showNotEligibleForNoFeeBecauseOfBasicConstrains(maxAgeView, result.tx);
                            }
                        }
                    } else if (result.errorSource == GenerateTransactionResult.ERROR_SOURCE_INPUT_TX_FIELD) {
                        rawTxToSpendErr.setText(result.errorMessage);
                    } else if (result.errorSource == GenerateTransactionResult.ERROR_SOURCE_ADDRESS_FIELD
                            || result.errorSource == GenerateTransactionResult.HINT_FOR_ADDRESS_FIELD) {
                        ((TextView) findViewById(R.id.err_recipient_address)).setText(result.errorMessage);
                    } else if (!TextUtils.isEmpty(result.errorMessage)
                            && result.errorSource == GenerateTransactionResult.ERROR_SOURCE_UNKNOWN) {
                        new AlertDialog.Builder(MainActivity.this).setMessage(result.errorMessage)
                                .setPositiveButton(android.R.string.ok, null).show();
                    }

                    ((TextView) findViewById(R.id.err_amount))
                            .setText(result.errorSource == GenerateTransactionResult.ERROR_SOURCE_AMOUNT_FIELD
                                    ? result.errorMessage
                                    : "");
                }
            }

            private boolean showNotEligibleForNoFeeBecauseOfBasicConstrains(TextView maxAgeView,
                    Transaction tx) {
                long minOutput = Long.MAX_VALUE;
                for (Transaction.Output output : tx.outputs) {
                    minOutput = Math.min(output.value, minOutput);
                }
                int txLen = tx.getBytes().length;
                if (txLen >= BTCUtils.MAX_TX_LEN_FOR_NO_FEE) {
                    maxAgeView.setText(
                            getResources().getQuantityText(R.plurals.tx_size_too_big_to_be_free, txLen));
                    maxAgeView.setVisibility(View.VISIBLE);
                    return true;
                } else if (minOutput < BTCUtils.MIN_MIN_OUTPUT_VALUE_FOR_NO_FEE) {
                    maxAgeView
                            .setText(getString(R.string.tx_output_is_too_small, BTCUtils.formatValue(minOutput),
                                    BTCUtils.formatValue(BTCUtils.MIN_MIN_OUTPUT_VALUE_FOR_NO_FEE)));
                    maxAgeView.setVisibility(View.VISIBLE);
                    return true;
                }
                maxAgeView.setVisibility(View.GONE);
                return false;
            }
        }.execute();
    }
}