List of usage examples for android.text SpannableStringBuilder SpannableStringBuilder
public SpannableStringBuilder(CharSequence text)
From source file:android_network.hetnet.vpn_service.ActivitySettings.java
private void markPro(Preference pref, String sku) { if (sku == null) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean dark = prefs.getBoolean("dark_theme", false); SpannableStringBuilder ssb = new SpannableStringBuilder(" " + pref.getTitle()); ssb.setSpan(//from ww w . j a v a2s. c om new ImageSpan(this, dark ? R.drawable.ic_shopping_cart_white_24dp : R.drawable.ic_shopping_cart_black_24dp), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); pref.setTitle(ssb); } }
From source file:org.telegram.ui.ArticleViewer.java
private CharSequence getText(TLRPC.RichText parentRichText, TLRPC.RichText richText, TLRPC.PageBlock parentBlock) {//from w ww . jav a 2s . co m if (richText instanceof TLRPC.TL_textFixed) { return getText(parentRichText, ((TLRPC.TL_textFixed) richText).text, parentBlock); } else if (richText instanceof TLRPC.TL_textItalic) { return getText(parentRichText, ((TLRPC.TL_textItalic) richText).text, parentBlock); } else if (richText instanceof TLRPC.TL_textBold) { return getText(parentRichText, ((TLRPC.TL_textBold) richText).text, parentBlock); } else if (richText instanceof TLRPC.TL_textUnderline) { return getText(parentRichText, ((TLRPC.TL_textUnderline) richText).text, parentBlock); } else if (richText instanceof TLRPC.TL_textStrike) { return getText(parentRichText, ((TLRPC.TL_textStrike) richText).text, parentBlock); } else if (richText instanceof TLRPC.TL_textEmail) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder( getText(parentRichText, ((TLRPC.TL_textEmail) richText).text, parentBlock)); MetricAffectingSpan innerSpans[] = spannableStringBuilder.getSpans(0, spannableStringBuilder.length(), MetricAffectingSpan.class); spannableStringBuilder.setSpan( new TextPaintUrlSpan(innerSpans == null || innerSpans.length == 0 ? getTextPaint(parentRichText, richText, parentBlock) : null, getUrl(richText)), 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return spannableStringBuilder; } else if (richText instanceof TLRPC.TL_textUrl) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder( getText(parentRichText, ((TLRPC.TL_textUrl) richText).text, parentBlock)); MetricAffectingSpan innerSpans[] = spannableStringBuilder.getSpans(0, spannableStringBuilder.length(), MetricAffectingSpan.class); spannableStringBuilder.setSpan( new TextPaintUrlSpan(innerSpans == null || innerSpans.length == 0 ? getTextPaint(parentRichText, richText, parentBlock) : null, getUrl(richText)), 0, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return spannableStringBuilder; } else if (richText instanceof TLRPC.TL_textPlain) { return ((TLRPC.TL_textPlain) richText).text; } else if (richText instanceof TLRPC.TL_textEmpty) { return ""; } else if (richText instanceof TLRPC.TL_textConcat) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); int count = richText.texts.size(); for (int a = 0; a < count; a++) { TLRPC.RichText innerRichText = richText.texts.get(a); CharSequence innerText = getText(parentRichText, innerRichText, parentBlock); int flags = getTextFlags(innerRichText); int startLength = spannableStringBuilder.length(); spannableStringBuilder.append(innerText); if (flags != 0 && !(innerText instanceof SpannableStringBuilder)) { if ((flags & TEXT_FLAG_URL) != 0) { String url = getUrl(innerRichText); if (url == null) { url = getUrl(parentRichText); } spannableStringBuilder.setSpan( new TextPaintUrlSpan(getTextPaint(parentRichText, innerRichText, parentBlock), url), startLength, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } else { spannableStringBuilder.setSpan( new TextPaintSpan(getTextPaint(parentRichText, innerRichText, parentBlock)), startLength, spannableStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } return spannableStringBuilder; } return "not supported " + richText; }
From source file:org.telegram.ui.ChannelCreateActivity.java
@Override public View createView(Context context) { searching = false;/*from w w w .j a va2 s .com*/ searchWas = false; actionBar.setBackButtonImage(R.drawable.ic_ab_back); actionBar.setAllowOverlayTitle(true); actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { @Override public void onItemClick(int id) { if (id == -1) { finishFragment(); } else if (id == done_button) { if (currentStep == 0) { if (donePressed) { return; } if (nameTextView.length() == 0) { Vibrator v = (Vibrator) getParentActivity().getSystemService(Context.VIBRATOR_SERVICE); if (v != null) { v.vibrate(200); } AndroidUtilities.shakeView(nameTextView, 2, 0); return; } donePressed = true; if (avatarUpdater.uploadingAvatar != null) { createAfterUpload = true; progressDialog = new ProgressDialog(getParentActivity()); progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); progressDialog.setCanceledOnTouchOutside(false); progressDialog.setCancelable(false); progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { createAfterUpload = false; progressDialog = null; donePressed = false; try { dialog.dismiss(); } catch (Exception e) { FileLog.e("tmessages", e); } } }); progressDialog.show(); return; } final int reqId = MessagesController.getInstance().createChat( nameTextView.getText().toString(), new ArrayList<Integer>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, ChannelCreateActivity.this); progressDialog = new ProgressDialog(getParentActivity()); progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading)); progressDialog.setCanceledOnTouchOutside(false); progressDialog.setCancelable(false); progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ConnectionsManager.getInstance().cancelRequest(reqId, true); donePressed = false; try { dialog.dismiss(); } catch (Exception e) { FileLog.e("tmessages", e); } } }); progressDialog.show(); } else if (currentStep == 1) { if (!isPrivate) { if (nameTextView.length() == 0) { AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setMessage(LocaleController.getString("ChannelPublicEmptyUsername", R.string.ChannelPublicEmptyUsername)); builder.setPositiveButton(LocaleController.getString("Close", R.string.Close), null); showDialog(builder.create()); return; } else { if (!lastNameAvailable) { Vibrator v = (Vibrator) getParentActivity() .getSystemService(Context.VIBRATOR_SERVICE); if (v != null) { v.vibrate(200); } AndroidUtilities.shakeView(checkTextView, 2, 0); return; } else { MessagesController.getInstance().updateChannelUserName(chatId, lastCheckName); } } } Bundle args = new Bundle(); args.putInt("step", 2); args.putInt("chat_id", chatId); presentFragment(new ChannelCreateActivity(args), true); } else { ArrayList<TLRPC.InputUser> result = new ArrayList<>(); for (Integer uid : selectedContacts.keySet()) { TLRPC.InputUser user = MessagesController .getInputUser(MessagesController.getInstance().getUser(uid)); if (user != null) { result.add(user); } } MessagesController.getInstance().addUsersToChannel(chatId, result, null); NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); Bundle args2 = new Bundle(); args2.putInt("chat_id", chatId); presentFragment(new ChatActivity(args2), true); } } } }); ActionBarMenu menu = actionBar.createMenu(); doneButton = menu.addItemWithWidth(done_button, R.drawable.ic_done, AndroidUtilities.dp(56)); if (currentStep != 2) { fragmentView = new ScrollView(context); ScrollView scrollView = (ScrollView) fragmentView; scrollView.setFillViewport(true); linearLayout = new LinearLayout(context); scrollView.addView(linearLayout, new ScrollView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } else { fragmentView = new LinearLayout(context); fragmentView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); linearLayout = (LinearLayout) fragmentView; } linearLayout.setOrientation(LinearLayout.VERTICAL); if (currentStep == 0) { actionBar.setTitle(LocaleController.getString("NewChannel", R.string.NewChannel)); fragmentView.setBackgroundColor(ContextCompat.getColor(context, R.color.card_background)); FrameLayout frameLayout = new FrameLayout(context); linearLayout.addView(frameLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); avatarImage = new BackupImageView(context); avatarImage.setRoundRadius(AndroidUtilities.dp(32)); avatarDrawable.setInfo(5, null, null, false); avatarDrawable.setDrawPhoto(true); avatarImage.setImageDrawable(avatarDrawable); frameLayout.addView(avatarImage, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12)); avatarImage.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (getParentActivity() == null) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); CharSequence[] items; if (avatar != null) { items = new CharSequence[] { LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley), LocaleController.getString("DeletePhoto", R.string.DeletePhoto) }; } else { items = new CharSequence[] { LocaleController.getString("FromCamera", R.string.FromCamera), LocaleController.getString("FromGalley", R.string.FromGalley) }; } builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { if (i == 0) { avatarUpdater.openCamera(); } else if (i == 1) { avatarUpdater.openGallery(); } else if (i == 2) { avatar = null; uploadedAvatar = null; avatarImage.setImage(avatar, "50_50", avatarDrawable); } } }); showDialog(builder.create()); } }); nameTextView = new EditText(context); nameTextView.setHint(LocaleController.getString("EnterChannelName", R.string.EnterChannelName)); if (nameToSet != null) { nameTextView.setText(nameToSet); nameToSet = null; } nameTextView.setMaxLines(4); nameTextView .setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)); nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); //nameTextView.setHintTextColor(0xff979797); nameTextView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); nameTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); InputFilter[] inputFilters = new InputFilter[1]; inputFilters[0] = new InputFilter.LengthFilter(100); nameTextView.setFilters(inputFilters); nameTextView.setPadding(0, 0, 0, AndroidUtilities.dp(8)); AndroidUtilities.clearCursorDrawable(nameTextView); nameTextView.setTextColor(ContextCompat.getColor(context, R.color.primary_text)); frameLayout.addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, LocaleController.isRTL ? 16 : 96, 0, LocaleController.isRTL ? 96 : 16, 0)); nameTextView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable s) { avatarDrawable.setInfo(5, nameTextView.length() > 0 ? nameTextView.getText().toString() : null, null, false); avatarImage.invalidate(); } }); descriptionTextView = new EditText(context); descriptionTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); //descriptionTextView.setHintTextColor(0xff979797); descriptionTextView.setTextColor(ContextCompat.getColor(context, R.color.primary_text)); descriptionTextView.setPadding(0, 0, 0, AndroidUtilities.dp(6)); descriptionTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); descriptionTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); descriptionTextView.setImeOptions(EditorInfo.IME_ACTION_DONE); inputFilters = new InputFilter[1]; inputFilters[0] = new InputFilter.LengthFilter(120); descriptionTextView.setFilters(inputFilters); descriptionTextView .setHint(LocaleController.getString("DescriptionPlaceholder", R.string.DescriptionPlaceholder)); AndroidUtilities.clearCursorDrawable(descriptionTextView); linearLayout.addView(descriptionTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 24, 18, 24, 0)); descriptionTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { if (i == EditorInfo.IME_ACTION_DONE && doneButton != null) { doneButton.performClick(); return true; } return false; } }); descriptionTextView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void afterTextChanged(Editable editable) { } }); TextView helpTextView = new TextView(context); helpTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); //helpTextView.setTextColor(0xff6d6d72); helpTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); helpTextView.setText(LocaleController.getString("DescriptionInfo", R.string.DescriptionInfo)); linearLayout.addView(helpTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 24, 10, 24, 20)); } else if (currentStep == 1) { actionBar.setTitle(LocaleController.getString("ChannelSettings", R.string.ChannelSettings)); fragmentView.setBackgroundColor(ContextCompat.getColor(context, R.color.settings_background)); LinearLayout linearLayout2 = new LinearLayout(context); linearLayout2.setOrientation(LinearLayout.VERTICAL); linearLayout2.setBackgroundColor(ContextCompat.getColor(context, R.color.card_background)); linearLayout2.setElevation(AndroidUtilities.dp(2)); linearLayout.addView(linearLayout2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); radioButtonCell1 = new RadioButtonCell(context); radioButtonCell1.setElevation(0); radioButtonCell1.setForeground(R.drawable.list_selector); radioButtonCell1.setTextAndValue(LocaleController.getString("ChannelPublic", R.string.ChannelPublic), LocaleController.getString("ChannelPublicInfo", R.string.ChannelPublicInfo), !isPrivate, false); linearLayout2.addView(radioButtonCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); radioButtonCell1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!isPrivate) { return; } isPrivate = false; updatePrivatePublic(); } }); radioButtonCell2 = new RadioButtonCell(context); radioButtonCell2.setElevation(0); radioButtonCell2.setForeground(R.drawable.list_selector); radioButtonCell2.setTextAndValue(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate), LocaleController.getString("ChannelPrivateInfo", R.string.ChannelPrivateInfo), isPrivate, false); linearLayout2.addView(radioButtonCell2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); radioButtonCell2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isPrivate) { return; } isPrivate = true; updatePrivatePublic(); } }); sectionCell = new ShadowSectionCell(context); linearLayout.addView(sectionCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); linkContainer = new LinearLayout(context); linkContainer.setOrientation(LinearLayout.VERTICAL); linkContainer.setBackgroundColor(ContextCompat.getColor(context, R.color.card_background)); linkContainer.setElevation(AndroidUtilities.dp(2)); linearLayout.addView(linkContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); headerCell = new HeaderCell(context); linkContainer.addView(headerCell); publicContainer = new LinearLayout(context); publicContainer.setOrientation(LinearLayout.HORIZONTAL); linkContainer.addView(publicContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, 17, 7, 17, 0)); EditText editText = new EditText(context); editText.setText("telegram.me/"); editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); //editText.setHintTextColor(0xff979797); editText.setTextColor(ContextCompat.getColor(context, R.color.primary_text)); editText.setMaxLines(1); editText.setLines(1); editText.setEnabled(false); editText.setBackgroundDrawable(null); editText.setPadding(0, 0, 0, 0); editText.setSingleLine(true); editText.setInputType(InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); editText.setImeOptions(EditorInfo.IME_ACTION_DONE); publicContainer.addView(editText, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, 36)); nameTextView = new EditText(context); nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18); //nameTextView.setHintTextColor(0xff979797); nameTextView.setTextColor(ContextCompat.getColor(context, R.color.primary_text)); nameTextView.setMaxLines(1); nameTextView.setLines(1); nameTextView.setBackgroundDrawable(null); nameTextView.setPadding(0, 0, 0, 0); nameTextView.setSingleLine(true); nameTextView.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); nameTextView.setImeOptions(EditorInfo.IME_ACTION_DONE); nameTextView.setHint( LocaleController.getString("ChannelUsernamePlaceholder", R.string.ChannelUsernamePlaceholder)); AndroidUtilities.clearCursorDrawable(nameTextView); publicContainer.addView(nameTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36)); nameTextView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { checkUserName(nameTextView.getText().toString()); } @Override public void afterTextChanged(Editable editable) { } }); privateContainer = new TextBlockCell(context); privateContainer.setForeground(R.drawable.list_selector); privateContainer.setElevation(0); linkContainer.addView(privateContainer); privateContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (invite == null) { return; } try { android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext .getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("label", invite.link); clipboard.setPrimaryClip(clip); Toast.makeText(getParentActivity(), LocaleController.getString("LinkCopied", R.string.LinkCopied), Toast.LENGTH_SHORT) .show(); } catch (Exception e) { FileLog.e("tmessages", e); } } }); checkTextView = new TextView(context); checkTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); checkTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT); checkTextView.setVisibility(View.GONE); linkContainer.addView(checkTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 17, 3, 17, 7)); typeInfoCell = new TextInfoPrivacyCell(context); //typeInfoCell.setBackgroundResource(R.drawable.greydivider_bottom); linearLayout.addView(typeInfoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); loadingAdminedCell = new LoadingCell(context); linearLayout.addView(loadingAdminedCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); adminedInfoCell = new TextInfoPrivacyCell(context); //adminedInfoCell.setBackgroundResource(R.drawable.greydivider_bottom); linearLayout.addView(adminedInfoCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); updatePrivatePublic(); } else if (currentStep == 2) { actionBar.setTitle(LocaleController.getString("ChannelAddMembers", R.string.ChannelAddMembers)); actionBar.setSubtitle(LocaleController.formatPluralString("Members", selectedContacts.size())); searchListViewAdapter = new SearchAdapter(context, null, false, false, false, false); searchListViewAdapter.setCheckedMap(selectedContacts); searchListViewAdapter.setUseUserCell(true); listViewAdapter = new ContactsAdapter(context, 1, false, null, false); listViewAdapter.setCheckedMap(selectedContacts); FrameLayout frameLayout = new FrameLayout(context); frameLayout.setBackgroundColor(ContextCompat.getColor(context, R.color.chat_list_background)); linearLayout.addView(frameLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT)); nameTextView = new EditText(context); nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16); //nameTextView.setHintTextColor(0xff979797); nameTextView.setTextColor(ContextCompat.getColor(context, R.color.primary_text)); nameTextView.setInputType(InputType.TYPE_TEXT_VARIATION_FILTER | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_MULTI_LINE); nameTextView.setMinimumHeight(AndroidUtilities.dp(54)); nameTextView.setSingleLine(false); nameTextView.setLines(2); nameTextView.setMaxLines(2); nameTextView.setVerticalScrollBarEnabled(true); nameTextView.setHorizontalScrollBarEnabled(false); nameTextView.setPadding(0, 0, 0, 0); nameTextView.setHint(LocaleController.getString("AddMutual", R.string.AddMutual)); nameTextView.setTextIsSelectable(false); nameTextView.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI); nameTextView .setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL); AndroidUtilities.clearCursorDrawable(nameTextView); frameLayout.addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 10, 0, 10, 0)); nameTextView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { if (!ignoreChange) { beforeChangeIndex = nameTextView.getSelectionStart(); changeString = new SpannableString(charSequence); } } @Override public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { } @Override public void afterTextChanged(Editable editable) { if (!ignoreChange) { boolean search = false; int afterChangeIndex = nameTextView.getSelectionEnd(); if (editable.toString().length() < changeString.toString().length()) { String deletedString = ""; try { deletedString = changeString.toString().substring(afterChangeIndex, beforeChangeIndex); } catch (Exception e) { FileLog.e("tmessages", e); } if (deletedString.length() > 0) { if (searching && searchWas) { search = true; } Spannable span = nameTextView.getText(); for (int a = 0; a < allSpans.size(); a++) { ChipSpan sp = allSpans.get(a); if (span.getSpanStart(sp) == -1) { allSpans.remove(sp); selectedContacts.remove(sp.uid); } } actionBar.setSubtitle( LocaleController.formatPluralString("Members", selectedContacts.size())); listView.invalidateViews(); } else { search = true; } } else { search = true; } if (search) { String text = nameTextView.getText().toString().replace("<", ""); if (text.length() != 0) { searching = true; searchWas = true; if (listView != null) { listView.setAdapter(searchListViewAdapter); searchListViewAdapter.notifyDataSetChanged(); listView.setFastScrollAlwaysVisible(false); listView.setFastScrollEnabled(false); listView.setVerticalScrollBarEnabled(true); } if (emptyTextView != null) { emptyTextView .setText(LocaleController.getString("NoResult", R.string.NoResult)); } searchListViewAdapter.searchDialogs(text); } else { searchListViewAdapter.searchDialogs(null); searching = false; searchWas = false; listView.setAdapter(listViewAdapter); listViewAdapter.notifyDataSetChanged(); listView.setFastScrollAlwaysVisible(true); listView.setFastScrollEnabled(true); listView.setVerticalScrollBarEnabled(false); emptyTextView .setText(LocaleController.getString("NoContacts", R.string.NoContacts)); } } } } }); LinearLayout emptyTextLayout = new LinearLayout(context); emptyTextLayout.setVisibility(View.INVISIBLE); emptyTextLayout.setOrientation(LinearLayout.VERTICAL); linearLayout.addView(emptyTextLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); emptyTextLayout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); emptyTextView = new TextView(context); emptyTextView.setTextColor(0xff808080); emptyTextView.setTextSize(20); emptyTextView.setGravity(Gravity.CENTER); emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); emptyTextLayout.addView(emptyTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0.5f)); FrameLayout frameLayout2 = new FrameLayout(context); emptyTextLayout.addView(frameLayout2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0.5f)); listView = new LetterSectionsListView(context); listView.setEmptyView(emptyTextLayout); listView.setVerticalScrollBarEnabled(false); listView.setDivider(null); listView.setDividerHeight(0); listView.setFastScrollEnabled(true); listView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); listView.setAdapter(listViewAdapter); listView.setFastScrollAlwaysVisible(true); listView.setVerticalScrollbarPosition( LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT); linearLayout.addView(listView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { TLRPC.User user; if (searching && searchWas) { user = (TLRPC.User) searchListViewAdapter.getItem(i); } else { int section = listViewAdapter.getSectionForPosition(i); int row = listViewAdapter.getPositionInSectionForPosition(i); if (row < 0 || section < 0) { return; } user = (TLRPC.User) listViewAdapter.getItem(section, row); } if (user == null) { return; } boolean check = true; if (selectedContacts.containsKey(user.id)) { check = false; try { ChipSpan span = selectedContacts.get(user.id); selectedContacts.remove(user.id); SpannableStringBuilder text = new SpannableStringBuilder(nameTextView.getText()); text.delete(text.getSpanStart(span), text.getSpanEnd(span)); allSpans.remove(span); ignoreChange = true; nameTextView.setText(text); nameTextView.setSelection(text.length()); ignoreChange = false; } catch (Exception e) { FileLog.e("tmessages", e); } } else { ignoreChange = true; ChipSpan span = createAndPutChipForUser(user); if (span != null) { span.uid = user.id; } ignoreChange = false; if (span == null) { return; } } actionBar.setSubtitle(LocaleController.formatPluralString("Members", selectedContacts.size())); if (searching || searchWas) { ignoreChange = true; SpannableStringBuilder ssb = new SpannableStringBuilder(""); for (ImageSpan sp : allSpans) { ssb.append("<<"); ssb.setSpan(sp, ssb.length() - 2, ssb.length(), SpannableStringBuilder.SPAN_EXCLUSIVE_EXCLUSIVE); } nameTextView.setText(ssb); nameTextView.setSelection(ssb.length()); ignoreChange = false; searchListViewAdapter.searchDialogs(null); searching = false; searchWas = false; listView.setAdapter(listViewAdapter); listViewAdapter.notifyDataSetChanged(); listView.setFastScrollAlwaysVisible(true); listView.setFastScrollEnabled(true); listView.setVerticalScrollBarEnabled(false); emptyTextView.setText(LocaleController.getString("NoContacts", R.string.NoContacts)); } else { if (view instanceof UserCell) { ((UserCell) view).setChecked(check, true); } } } }); listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView absListView, int i) { if (i == SCROLL_STATE_TOUCH_SCROLL) { AndroidUtilities.hideKeyboard(nameTextView); } if (listViewAdapter != null) { listViewAdapter.setIsScrolling(i != SCROLL_STATE_IDLE); } } @Override public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (absListView.isFastScrollEnabled()) { AndroidUtilities.clearDrawableAnimation(absListView); } } }); } return fragmentView; }
From source file:com.edible.ocr.CaptureActivity.java
/** * Given either a Spannable String or a regular String and a token, apply * the given CharacterStyle to the span between the tokens. * // www . ja v a 2 s . co m * NOTE: This method was adapted from: * http://www.androidengineer.com/2010/08/easy-method-for-formatting-android.html * * <p> * For example, {@code setSpanBetweenTokens("Hello ##world##!", "##", new * ForegroundColorSpan(0xFFFF0000));} will return a CharSequence {@code * "Hello world!"} with {@code world} in red. * */ private CharSequence setSpanBetweenTokens(CharSequence text, String token, CharacterStyle... cs) { // Start and end refer to the points where the span will apply int tokenLen = token.length(); int start = text.toString().indexOf(token) + tokenLen; int end = text.toString().indexOf(token, start); if (start > -1 && end > -1) { // Copy the spannable string to a mutable spannable string SpannableStringBuilder ssb = new SpannableStringBuilder(text); for (CharacterStyle c : cs) ssb.setSpan(c, start, end, 0); text = ssb; } return text; }
From source file:com.android.mail.utils.NotificationUtils.java
private static void configureLatestEventInfoFromConversation(final Context context, final Account account, final FolderPreferences folderPreferences, final NotificationCompat.Builder notificationBuilder, final NotificationCompat.WearableExtender wearableExtender, final Map<Integer, NotificationBuilders> msgNotifications, final int summaryNotificationId, final Cursor conversationCursor, final PendingIntent clickIntent, final Intent notificationIntent, final int unreadCount, final int unseenCount, final Folder folder, final long when, final ContactFetcher contactFetcher) { final Resources res = context.getResources(); final boolean multipleUnseen = unseenCount > 1; LogUtils.i(LOG_TAG, "Showing notification with unreadCount of %d and unseenCount of %d", unreadCount, unseenCount);//from ww w.jav a2 s. c om String notificationTicker = null; // Boolean indicating that this notification is for a non-inbox label. final boolean isInbox = folder.folderUri.fullUri.equals(account.settings.defaultInbox); // Notification label name for user label notifications. final String notificationLabelName = isInbox ? null : folder.name; if (multipleUnseen) { // Build the string that describes the number of new messages final String newMessagesString = createTitle(context, unseenCount); // The ticker initially start as the new messages string. notificationTicker = newMessagesString; // The title of the notification is the new messages string notificationBuilder.setContentTitle(newMessagesString); // TODO(skennedy) Can we remove this check? if (com.android.mail.utils.Utils.isRunningJellybeanOrLater()) { // For a new-style notification final int maxNumDigestItems = context.getResources() .getInteger(R.integer.max_num_notification_digest_items); // The body of the notification is the account name, or the label name. notificationBuilder.setSubText(isInbox ? account.getDisplayName() : notificationLabelName); final NotificationCompat.InboxStyle digest = new NotificationCompat.InboxStyle(notificationBuilder); // Group by account and folder final String notificationGroupKey = createGroupKey(account, folder); // Track all senders to later tag them along with the digest notification final HashSet<String> senderAddressesSet = new HashSet<String>(); notificationBuilder.setGroup(notificationGroupKey).setGroupSummary(true); ConfigResult firstResult = null; int numDigestItems = 0; do { final Conversation conversation = new Conversation(conversationCursor); if (!conversation.read) { boolean multipleUnreadThread = false; // TODO(cwren) extract this pattern into a helper Cursor cursor = null; MessageCursor messageCursor = null; try { final Uri.Builder uriBuilder = conversation.messageListUri.buildUpon(); uriBuilder.appendQueryParameter(UIProvider.LABEL_QUERY_PARAMETER, notificationLabelName); cursor = context.getContentResolver().query(uriBuilder.build(), UIProvider.MESSAGE_PROJECTION, null, null, null); messageCursor = new MessageCursor(cursor); String from = ""; String fromAddress = ""; if (messageCursor.moveToPosition(messageCursor.getCount() - 1)) { final Message message = messageCursor.getMessage(); fromAddress = message.getFrom(); if (fromAddress == null) { fromAddress = ""; } from = getDisplayableSender(fromAddress); addEmailAddressToSet(fromAddress, senderAddressesSet); } while (messageCursor.moveToPosition(messageCursor.getPosition() - 1)) { final Message message = messageCursor.getMessage(); if (!message.read && !fromAddress.contentEquals(message.getFrom())) { multipleUnreadThread = true; addEmailAddressToSet(message.getFrom(), senderAddressesSet); } } final SpannableStringBuilder sendersBuilder; if (multipleUnreadThread) { final int sendersLength = res.getInteger(R.integer.swipe_senders_length); sendersBuilder = getStyledSenders(context, conversationCursor, sendersLength, account); } else { sendersBuilder = new SpannableStringBuilder(getWrappedFromString(from)); } final CharSequence digestLine = getSingleMessageInboxLine(context, sendersBuilder.toString(), ConversationItemView.filterTag(context, conversation.subject), conversation.getSnippet()); digest.addLine(digestLine); numDigestItems++; // Adding conversation notification for Wear. NotificationCompat.Builder conversationNotif = new NotificationCompat.Builder(context); conversationNotif.setCategory(NotificationCompat.CATEGORY_EMAIL); conversationNotif.setSmallIcon(R.drawable.ic_notification_multiple_mail_24dp); if (com.android.mail.utils.Utils.isRunningLOrLater()) { conversationNotif .setColor(context.getResources().getColor(R.color.notification_icon_color)); } conversationNotif.setContentText(digestLine); Intent conversationNotificationIntent = createViewConversationIntent(context, account, folder, conversationCursor); PendingIntent conversationClickIntent = createClickPendingIntent(context, conversationNotificationIntent); conversationNotif.setContentIntent(conversationClickIntent); conversationNotif.setAutoCancel(true); // Conversations are sorted in descending order, but notification sort // key is in ascending order. Invert the order key to get the right // order. Left pad 19 zeros because it's a long. String groupSortKey = String.format("%019d", (Long.MAX_VALUE - conversation.orderKey)); conversationNotif.setGroup(notificationGroupKey); conversationNotif.setSortKey(groupSortKey); conversationNotif.setWhen(conversation.dateMs); int conversationNotificationId = getNotificationId(summaryNotificationId, conversation.hashCode()); final NotificationCompat.WearableExtender conversationWearExtender = new NotificationCompat.WearableExtender(); final ConfigResult result = configureNotifForOneConversation(context, account, folderPreferences, conversationNotif, conversationWearExtender, conversationCursor, notificationIntent, folder, when, res, isInbox, notificationLabelName, conversationNotificationId, contactFetcher); msgNotifications.put(conversationNotificationId, NotificationBuilders.of(conversationNotif, conversationWearExtender)); if (firstResult == null) { firstResult = result; } } finally { if (messageCursor != null) { messageCursor.close(); } if (cursor != null) { cursor.close(); } } } } while (numDigestItems <= maxNumDigestItems && conversationCursor.moveToNext()); // Tag main digest notification with the senders tagNotificationsWithPeople(notificationBuilder, senderAddressesSet); if (firstResult != null && firstResult.contactIconInfo != null) { wearableExtender.setBackground(firstResult.contactIconInfo.wearableBg); } else { LogUtils.w(LOG_TAG, "First contact icon is null!"); wearableExtender.setBackground(getDefaultWearableBg(context)); } } else { // The body of the notification is the account name, or the label name. notificationBuilder.setContentText(isInbox ? account.getDisplayName() : notificationLabelName); } } else { // For notifications for a single new conversation, we want to get the information // from the conversation // Move the cursor to the most recent unread conversation seekToLatestUnreadConversation(conversationCursor); final ConfigResult result = configureNotifForOneConversation(context, account, folderPreferences, notificationBuilder, wearableExtender, conversationCursor, notificationIntent, folder, when, res, isInbox, notificationLabelName, summaryNotificationId, contactFetcher); notificationTicker = result.notificationTicker; if (result.contactIconInfo != null) { wearableExtender.setBackground(result.contactIconInfo.wearableBg); } else { wearableExtender.setBackground(getDefaultWearableBg(context)); } } // Build the notification ticker if (notificationLabelName != null && notificationTicker != null) { // This is a per label notification, format the ticker with that information notificationTicker = res.getString(R.string.label_notification_ticker, notificationLabelName, notificationTicker); } if (notificationTicker != null) { // If we didn't generate a notification ticker, it will default to account name notificationBuilder.setTicker(notificationTicker); } // Set the number in the notification if (unreadCount > 1) { notificationBuilder.setNumber(unreadCount); } notificationBuilder.setContentIntent(clickIntent); }
From source file:com.nttec.everychan.ui.gallery.GalleryActivity.java
private Spanned getSpannedText(String message) { message = " " + message + " "; SpannableStringBuilder spanned = new SpannableStringBuilder(message); for (Object span : new Object[] { new ForegroundColorSpan(Color.WHITE), new BackgroundColorSpan(Color.parseColor("#88000000")) }) { spanned.setSpan(span, 0, message.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }/*from w ww .j a v a 2s. com*/ return spanned; }
From source file:com.tct.mail.browse.ConversationItemView.java
private void createSubject(final boolean isUnread) { final String badgeText = mHeader.badgeText == null ? "" : mHeader.badgeText; String subject = filterTag(getContext(), mHeader.conversation.subject); subject = Conversation.getSubjectForDisplay(mContext, badgeText, subject); /// TCT: add for search term highlight // process subject and snippet respectively @{ SpannableStringBuilder subjectToHighlight = new SpannableStringBuilder(subject); boolean hasFilter = (mSearchParams != null && !TextUtils.isEmpty(mSearchParams.mFilter)); if (hasFilter) { boolean fieldMatchedSubject = (mSearchParams != null && (SearchParams.SEARCH_FIELD_SUBJECT.equals(mSearchParams.mField) || SearchParams.SEARCH_FIELD_ALL.equals(mSearchParams.mField))); /// TCT: Only highlight un-empty subject if (fieldMatchedSubject && !TextUtils.isEmpty(subject)) { CharSequence subjectChars = TextUtilities.highlightTermsInText(subject, mSearchParams.mFilter); subjectToHighlight.replace(0, subject.length(), subjectChars); }// w w w . j ava2 s . c o m } /// @} final Spannable displayedStringBuilder = new SpannableString(subjectToHighlight); // since spans affect text metrics, add spans to the string before measure/layout or fancy // ellipsizing final int badgeTextLength = formatBadgeText(displayedStringBuilder, badgeText); if (!TextUtils.isEmpty(subject)) { displayedStringBuilder.setSpan( TextAppearanceSpan.wrap(isUnread ? sSubjectTextUnreadSpan : sSubjectTextReadSpan), badgeTextLength, subject.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (isActivated() && showActivatedText()) { displayedStringBuilder.setSpan(sActivatedTextSpan, badgeTextLength, displayedStringBuilder.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); } final int subjectWidth = mSubjectWidth;//TS: yanhua.chen 2015-9-2 EMAIL CR_540046 MOD final int subjectHeight = mCoordinates.subjectHeight; mSubjectTextView.setLayoutParams(new ViewGroup.LayoutParams(subjectWidth, subjectHeight)); mSubjectTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mCoordinates.subjectFontSize); layoutViewExactly(mSubjectTextView, subjectWidth, subjectHeight); //[FEATURE]-Mod-BEGIN by CDTS.zhonghua.tuo,05/29/2014,FR 670064 SpannableStringBuilder builder = new SpannableStringBuilder(); boolean filterSubject = false; if (mField == UIProvider.LOCAL_SEARCH_ALL || mField == UIProvider.LOCAL_SEARCH_SUBJECT) { filterSubject = true; } if (mQueryText != null && filterSubject) { CharSequence formatSubject = displayedStringBuilder; formatSubject = TextUtilities.highlightTermsInText(subject, mQueryText); builder.append(formatSubject); mSubjectTextView.setText(builder); // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_S //store the displayed subject for calculate the statusView's X and width mHeader.subjectText = builder.toString(); // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_E } else { mSubjectTextView.setText(displayedStringBuilder); // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_S mHeader.subjectText = displayedStringBuilder.toString(); // TS: chao.zhang 2015-09-14 EMAIL FEATURE-585337 ADD_E } //[FEATURE]-Mod-END by CDTS.zhonghua.tuo }
From source file:com.tct.mail.browse.ConversationItemView.java
private void createSnippet() { final String snippet = mHeader.conversation.getSnippet(); /// TCT: add for search term highlight // process subject and snippet respectively @{ SpannableStringBuilder snippetToHighlight = new SpannableStringBuilder(snippet); boolean hasFilter = (mSearchParams != null && !TextUtils.isEmpty(mSearchParams.mFilter)); if (hasFilter) { boolean fieldMatchedSnippet = (mSearchParams != null && (SearchParams.SEARCH_FIELD_BODY.equals(mSearchParams.mField) || SearchParams.SEARCH_FIELD_ALL.equals(mSearchParams.mField))); /// TCT: Only highlight un-empty snippet if (fieldMatchedSnippet && !TextUtils.isEmpty(snippet)) { CharSequence snippetChars = TextUtilities.highlightTermsInText(snippet, mSearchParams.mFilter); snippetToHighlight.replace(0, snippet.length(), snippetChars); }// w ww . j a va 2 s. c o m } /// @} final Spannable displayedStringBuilder = new SpannableString(snippetToHighlight); // measure the width of the folders which overlap the snippet view final int folderWidth = mHeader.folderDisplayer.measureFolders(mCoordinates); // size the snippet view by subtracting the folder width from the maximum snippet width final int snippetWidth = mCoordinates.maxSnippetWidth - folderWidth; final int snippetHeight = mCoordinates.snippetHeight; mSnippetTextView.setLayoutParams(new ViewGroup.LayoutParams(snippetWidth, snippetHeight)); mSnippetTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mCoordinates.snippetFontSize); layoutViewExactly(mSnippetTextView, snippetWidth, snippetHeight); mSnippetTextView.setText(displayedStringBuilder); }
From source file:com.tct.mail.utils.NotificationUtils.java
private static void configureLatestEventInfoFromConversation(final Context context, final Account account, final FolderPreferences folderPreferences, final NotificationCompat.Builder notification, final NotificationCompat.WearableExtender wearableExtender, final Map<Integer, NotificationBuilders> msgNotifications, final int summaryNotificationId, final Cursor conversationCursor, final PendingIntent clickIntent, final Intent notificationIntent, final int unreadCount, final int unseenCount, final Folder folder, final long when, final ContactPhotoFetcher photoFetcher) { final Resources res = context.getResources(); final String notificationAccountDisplayName = account.getDisplayName(); final String notificationAccountEmail = account.getEmailAddress(); final boolean multipleUnseen = unseenCount > 1; LogUtils.i(LOG_TAG, "Showing notification with unreadCount of %d and unseenCount of %d", unreadCount, unseenCount);/*from w ww.j a v a 2 s . c o m*/ String notificationTicker = null; // Boolean indicating that this notification is for a non-inbox label. final boolean isInbox = folder.folderUri.fullUri.equals(account.settings.defaultInbox); // Notification label name for user label notifications. final String notificationLabelName = isInbox ? null : folder.name; if (multipleUnseen) { // Build the string that describes the number of new messages final String newMessagesString = createTitle(context, unseenCount); // Use the default notification icon notification .setLargeIcon(getDefaultNotificationIcon(context, folder, true /* multiple new messages */)); // The ticker initially start as the new messages string. notificationTicker = newMessagesString; // The title of the notification is the new messages string notification.setContentTitle(newMessagesString); // TODO(skennedy) Can we remove this check? if (com.tct.mail.utils.Utils.isRunningJellybeanOrLater()) { // For a new-style notification final int maxNumDigestItems = context.getResources() .getInteger(R.integer.max_num_notification_digest_items); // The body of the notification is the account name, or the label name. notification.setSubText(isInbox ? notificationAccountDisplayName : notificationLabelName); final NotificationCompat.InboxStyle digest = new NotificationCompat.InboxStyle(notification); // Group by account and folder final String notificationGroupKey = createGroupKey(account, folder); notification.setGroup(notificationGroupKey).setGroupSummary(true); ConfigResult firstResult = null; int numDigestItems = 0; do { final Conversation conversation = new Conversation(conversationCursor); if (!conversation.read) { boolean multipleUnreadThread = false; // TODO(cwren) extract this pattern into a helper Cursor cursor = null; MessageCursor messageCursor = null; try { final Uri.Builder uriBuilder = conversation.messageListUri.buildUpon(); uriBuilder.appendQueryParameter(UIProvider.LABEL_QUERY_PARAMETER, notificationLabelName); cursor = context.getContentResolver().query(uriBuilder.build(), UIProvider.MESSAGE_PROJECTION, null, null, null); messageCursor = new MessageCursor(cursor); String from = ""; String fromAddress = ""; if (messageCursor.moveToPosition(messageCursor.getCount() - 1)) { final Message message = messageCursor.getMessage(); fromAddress = message.getFrom(); if (fromAddress == null) { fromAddress = ""; } from = getDisplayableSender(fromAddress); } while (messageCursor.moveToPosition(messageCursor.getPosition() - 1)) { final Message message = messageCursor.getMessage(); if (!message.read && !fromAddress.contentEquals(message.getFrom())) { multipleUnreadThread = true; break; } } final SpannableStringBuilder sendersBuilder; if (multipleUnreadThread) { final int sendersLength = res.getInteger(R.integer.swipe_senders_length); sendersBuilder = getStyledSenders(context, conversationCursor, sendersLength, notificationAccountEmail); } else { sendersBuilder = new SpannableStringBuilder(getWrappedFromString(from)); } //TS: zheng.zou 2015-03-20 EMAIL BUGFIX_-954980 MOD_S CharSequence digestLine = getSingleMessageInboxLine(context, sendersBuilder.toString(), ConversationItemView.filterTag(context, conversation.subject), conversation.getSnippet()); if (digestLine == null) { digestLine = ""; } //TS: zheng.zou 2015-03-20 EMAIL BUGFIX_-954980 MOD_E digest.addLine(digestLine); numDigestItems++; // Adding conversation notification for Wear. NotificationCompat.Builder conversationNotif = new NotificationCompat.Builder(context); // TODO(shahrk) - fix for multiple mail // Check that the group's folder is assigned an icon res (one of the // 4 sections). If it is, we can add the gmail badge. If not, it is // accompanied by the multiple_mail_24dp icon and we don't want a badge // if (folder.notificationIconResId != 0) { conversationNotif.setSmallIcon(R.drawable.ic_notification_mail_24dp); if (com.tct.mail.utils.Utils.isRunningLOrLater()) { conversationNotif.setColor( context.getResources().getColor(R.color.notification_icon_mail_orange)); } conversationNotif.setContentText(digestLine); Intent conversationNotificationIntent = createViewConversationIntent(context, account, folder, conversationCursor); PendingIntent conversationClickIntent = createClickPendingIntent(context, conversationNotificationIntent); conversationNotif.setContentIntent(conversationClickIntent); conversationNotif.setAutoCancel(true); // Conversations are sorted in descending order, but notification sort // key is in ascending order. Invert the order key to get the right // order. Left pad 19 zeros because it's a long. String groupSortKey = String.format("%019d", (Long.MAX_VALUE - conversation.orderKey)); conversationNotif.setGroup(notificationGroupKey); conversationNotif.setSortKey(groupSortKey); int conversationNotificationId = getNotificationId(summaryNotificationId, conversation.hashCode()); final NotificationCompat.WearableExtender conversationWearExtender = new NotificationCompat.WearableExtender(); final ConfigResult result = configureNotifForOneConversation(context, account, folderPreferences, conversationNotif, conversationWearExtender, conversationCursor, notificationIntent, folder, when, res, notificationAccountDisplayName, notificationAccountEmail, isInbox, notificationLabelName, conversationNotificationId, photoFetcher); // TS: chenyanhua 2015-02-11 EMAIL BUGFIX-926747 ADD_S result.contactIconInfo = getContactIcon(context, folder, photoFetcher); notification.setLargeIcon(result.contactIconInfo.icon); // TS: chenyanhua 2015-02-11 EMAIL BUGFIX-926747 ADD_E msgNotifications.put(conversationNotificationId, NotificationBuilders.of(conversationNotif, conversationWearExtender)); if (firstResult == null) { firstResult = result; } } finally { if (messageCursor != null) { messageCursor.close(); } if (cursor != null) { cursor.close(); } } } } while (numDigestItems <= maxNumDigestItems && conversationCursor.moveToNext()); if (firstResult != null && firstResult.contactIconInfo != null) { wearableExtender.setBackground(firstResult.contactIconInfo.wearableBg); } else { LogUtils.w(LOG_TAG, "First contact icon is null!"); wearableExtender.setBackground(getDefaultWearableBg(context)); } } else { // The body of the notification is the account name, or the label name. notification.setContentText(isInbox ? notificationAccountDisplayName : notificationLabelName); } } else { // For notifications for a single new conversation, we want to get the information // from the conversation // Move the cursor to the most recent unread conversation seekToLatestUnreadConversation(conversationCursor); final ConfigResult result = configureNotifForOneConversation(context, account, folderPreferences, notification, wearableExtender, conversationCursor, notificationIntent, folder, when, res, notificationAccountDisplayName, notificationAccountEmail, isInbox, notificationLabelName, summaryNotificationId, photoFetcher); notificationTicker = result.notificationTicker; if (result.contactIconInfo != null) { wearableExtender.setBackground(result.contactIconInfo.wearableBg); } else { wearableExtender.setBackground(getDefaultWearableBg(context)); } } // Build the notification ticker if (notificationLabelName != null && notificationTicker != null) { // This is a per label notification, format the ticker with that information notificationTicker = res.getString(R.string.label_notification_ticker, notificationLabelName, notificationTicker); } if (notificationTicker != null) { // If we didn't generate a notification ticker, it will default to account name notification.setTicker(notificationTicker); } // Set the number in the notification if (unreadCount > 1) { notification.setNumber(unreadCount); } notification.setContentIntent(clickIntent); }
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 .java 2 s . c om*/ 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(); } }