/** * When we come upon an ignored tag, we mark it with an Annotation object with a specific key * and value as above. We don't really need to be checking these values since Html.fromHtml() * doesn't use Annotation spans, but we should do it now to be safe in case they do start using * it in the future. * @param opening If this is an opening tag or not. * @param output Spannable string that we're working with. */ private void handleIgnoredTag(boolean opening, Editable output) { int len = output.length(); if (opening) { output.setSpan(new Annotation(IGNORED_ANNOTATION_KEY, IGNORED_ANNOTATION_VALUE), len, len, Spannable.SPAN_MARK_MARK); } else { Object start = getOpeningAnnotation(output); if (start != null) { int where = output.getSpanStart(start); // Remove the temporary Annotation span. output.removeSpan(start); // Delete everything between the start of the Annotation and the end of the string // (what we've generated so far). output.delete(where, len); } } }
private static Recipient getRecipientAt(Spanned sp, int start, int end) { Annotation[] a = sp.getSpans(start, end, Annotation.class); String person_id = getAnnotation(a, "person_id"); String name = getAnnotation(a, "name"); String label = getAnnotation(a, "label"); String bcc = getAnnotation(a, "bcc"); String number = getAnnotation(a, "number"); Recipient r = new Recipient(); r.name = name; r.label = label; r.bcc = bcc.equals("true"); r.number = TextUtils.isEmpty(number) ? TextUtils.substring(sp, start, end) : number; r.nameAndNumber = Recipient.buildNameAndNumber(r.name, r.number); if (person_id.length() > 0) { r.person_id = Long.parseLong(person_id); } else { r.person_id = -1; } return r; }
/** * When we come upon an ignored tag, we mark it with an Annotation object with a specific key * and value as above. We don't really need to be checking these values since Html.fromHtml() * doesn't use Annotation spans, but we should do it now to be safe in case they do start using * it in the future. * * @param opening If this is an opening tag or not. * @param output Spannable string that we're working with. */ private void handleIgnoredTag(boolean opening, Editable output) { int len = output.length(); if (opening) { output.setSpan(new Annotation(IGNORED_ANNOTATION_KEY, IGNORED_ANNOTATION_VALUE), len, len, Spanned.SPAN_MARK_MARK); } else { Object start = getOpeningAnnotation(output); if (start != null) { int where = output.getSpanStart(start); // Remove the temporary Annotation span. output.removeSpan(start); // Delete everything between the start of the Annotation and the end of the string // (what we've generated so far). output.delete(where, len); } } }
/** * Fetch the matching opening Annotation object and verify that it's the one added by QMail. * @param output Spannable string we're working with. * @return Starting Annotation object. */ private Object getOpeningAnnotation(Editable output) { Object[] objs = output.getSpans(0, output.length(), Annotation.class); for (int i = objs.length - 1; i >= 0; i--) { Annotation span = (Annotation) objs[i]; if (output.getSpanFlags(objs[i]) == Spannable.SPAN_MARK_MARK && span.getKey().equals(IGNORED_ANNOTATION_KEY) && span.getValue().equals(IGNORED_ANNOTATION_VALUE)) { return objs[i]; } } return null; }
public static CharSequence contactToToken(Recipient c) { String name = c.getName(); String number = c.getNumber(); SpannableString s = new SpannableString(RecipientsFormatter.formatNameAndNumber(name, number)); int len = s.length(); if (len == 0) { return s; } s.setSpan(new Annotation("number", c.getNumber()), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return s; }
private static int getSpanLength(Spanned sp, int start, int end, Context context) { // TODO: there's a situation where the span can lose its annotations: // - add an auto-complete contact // - add another auto-complete contact // - delete that second contact and keep deleting into the first // - we lose the annotation and can no longer get the span. // Need to fix this case because it breaks auto-complete contacts with commas in the name. Annotation[] a = sp.getSpans(start, end, Annotation.class); if (a.length > 0) { return sp.getSpanEnd(a[0]); } return 0; }
private static String getFieldAt(String field, Spanned sp, int start, int end, Context context) { Annotation[] a = sp.getSpans(start, end, Annotation.class); String fieldValue = getAnnotation(a, field); if (TextUtils.isEmpty(fieldValue)) { fieldValue = TextUtils.substring(sp, start, end); } return fieldValue; }
private static String getAnnotation(Annotation[] a, String key) { for (int i = 0; i < a.length; i++) { if (a[i].getKey().equals(key)) { return a[i].getValue(); } } return ""; }
public CharSequence toToken() { SpannableString s = new SpannableString(this.nameAndNumber); int len = s.length(); if (len == 0) { return s; } if (person_id != -1) { s.setSpan(new Annotation("person_id", String.valueOf(person_id)), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (name != null) { s.setSpan(new Annotation("name", name), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (label != null) { s.setSpan(new Annotation("label", label.toString()), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (number != null) { s.setSpan(new Annotation("number", number), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } s.setSpan(new Annotation("bcc", String.valueOf(bcc)), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return s; }
@Override public final CharSequence convertToString(Cursor cursor) { String name = cursor.getString(RecipientsAdapter.NAME_INDEX); int type = cursor.getInt(RecipientsAdapter.TYPE_INDEX); String number = cursor.getString(RecipientsAdapter.NUMBER_INDEX).trim(); String label = cursor.getString(RecipientsAdapter.LABEL_INDEX); CharSequence displayLabel = Phones.getDisplayLabel(mContext, type, label); if (number.length() == 0) { return number; } SpannableString out = new SpannableString(RecipientList.Recipient.buildNameAndNumber(name, number)); int len = out.length(); if (!TextUtils.isEmpty(name)) { out.setSpan(new Annotation("name", name), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } else { out.setSpan(new Annotation("name", number), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } String person_id = cursor.getString(RecipientsAdapter.PERSON_ID_INDEX); out.setSpan(new Annotation("person_id", person_id), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); out.setSpan(new Annotation("label", displayLabel.toString()), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); out.setSpan(new Annotation("number", number), 0, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return out; }
/** * Fetch the matching opening Annotation object and verify that it's the one added by us. * * @param output Spannable string we're working with. * @return Starting Annotation object. */ private Object getOpeningAnnotation(Editable output) { Object[] objs = output.getSpans(0, output.length(), Annotation.class); for (int i = objs.length - 1; i >= 0; i--) { Annotation span = (Annotation) objs[i]; if (output.getSpanFlags(objs[i]) == Spanned.SPAN_MARK_MARK && span.getKey().equals(IGNORED_ANNOTATION_KEY) && span.getValue().equals(IGNORED_ANNOTATION_VALUE)) { return objs[i]; } } return null; }
@Override public CharSequence convertToString(Cursor cursor) { SpannableString receiver = new SpannableString( cursor.getString(2) + " <" + cursor.getString(3) + ">"); // FIXME may be related to issue 17 // http://code.google.com/p/esms/issues/detail?id=17 receiver.setSpan(new Annotation("number", cursor.getString(3)), 0, receiver.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); receiver.setSpan(new Annotation("name", cursor.getString(2)), 0, receiver.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return receiver; }
public List<Receiver> getReceivers() { List<Receiver> receivers = new LinkedList<Receiver>(); if (listSize == 0) { String name = null; String number = receiverText.getText().toString(); Spannable s = receiverText.getText(); Annotation[] annotations = s.getSpans(0, s.length(), Annotation.class); for (Annotation a : annotations) { if (a.getKey().equals("name")) name = a.getValue(); if (a.getKey().equals("number")) number = a.getValue(); } receivers.add(new Receiver(name, number)); } else { for (int i = 0; i < listSize; ++i) { View listItem = listLinear.getChildAt(i); TextView listItemName = (TextView) listItem .findViewById(R.id.list_item_name); TextView listItemNumber = (TextView) listItem .findViewById(R.id.list_item_number); receivers.add(new Receiver( listItemName.getText().toString(), listItemNumber.getText().toString())); } } return receivers; }
@Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if (bundle != null) { Object[] pdus = (Object[]) bundle.get("pdus"); for (Object pdu : pdus) { SmsMessage message = SmsMessage.createFromPdu((byte[]) pdu); if (listSize == 0) { // only if one receiver is selected String number = receiverText.getText().toString(); Spannable s = receiverText.getText(); Annotation[] annotations = s.getSpans(0, s.length(), Annotation.class); for (Annotation a : annotations) if (a.getKey().equals("number")) number = a.getValue(); String address = message.getOriginatingAddress(); int addressLength = address.length(); if (addressLength > 10) address = address.substring(addressLength-10, addressLength); int numberLength = number.length(); if (numberLength > 10) number = number.substring(numberLength-10, numberLength); if (number.equals(address)) { replyContent.setText(message.getMessageBody()); long date = message.getTimestampMillis(); replyDate.setText(new Date(date).toLocaleString()); } } } } }