Home | History | Annotate | Download | only in style
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.text.style;
     18 
     19 import android.os.Parcel;
     20 import android.os.PersistableBundle;
     21 import android.text.ParcelableSpan;
     22 import android.text.TextUtils;
     23 
     24 import java.text.NumberFormat;
     25 import java.util.Locale;
     26 
     27 /**
     28  * A span that supplies additional meta-data for the associated text intended
     29  * for text-to-speech engines. If the text is being processed by a
     30  * text-to-speech engine, the engine may use the data in this span in addition
     31  * to or instead of its associated text.
     32  *
     33  * Each instance of a TtsSpan has a type, for example {@link #TYPE_DATE}
     34  * or {@link #TYPE_MEASURE}. And a list of arguments, provided as
     35  * key-value pairs in a bundle.
     36  *
     37  * The inner classes are there for convenience and provide builders for each
     38  * TtsSpan type.
     39  */
     40 public class TtsSpan implements ParcelableSpan {
     41     private final String mType;
     42     private final PersistableBundle mArgs;
     43 
     44     /**
     45      * This span type can be used to add morphosyntactic features to the text it
     46      * spans over, or synthesize a something else than the spanned text. Use
     47      * the argument {@link #ARG_TEXT} to set a different text.
     48      * Accepts the arguments {@link #ARG_GENDER},
     49      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
     50      * {@link #ARG_CASE}.
     51      */
     52     public static final String TYPE_TEXT = "android.type.text";
     53 
     54     /**
     55      * The text associated with this span is a cardinal. Must include the
     56      * number to be synthesized with {@link #ARG_NUMBER}.
     57      * Also accepts the arguments {@link #ARG_GENDER},
     58      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
     59      * {@link #ARG_CASE}.
     60      */
     61     public static final String TYPE_CARDINAL = "android.type.cardinal";
     62 
     63     /**
     64      * The text associated with this span is an ordinal. Must include the
     65      * number to be synthesized with {@link #ARG_NUMBER}.
     66      * Also accepts the arguments {@link #ARG_GENDER},
     67      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
     68      * {@link #ARG_CASE}.
     69      */
     70     public static final String TYPE_ORDINAL = "android.type.ordinal";
     71 
     72     /**
     73      * The text associated with this span is a decimal number. Must include the
     74      * number to be synthesized with {@link #ARG_INTEGER_PART} and
     75      * {@link #ARG_FRACTIONAL_PART}.
     76      * Also accepts the arguments {@link #ARG_GENDER},
     77      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
     78      * {@link #ARG_CASE}.
     79      */
     80     public static final String TYPE_DECIMAL = "android.type.decimal";
     81 
     82     /**
     83      * The text associated with this span is a fractional number. Must include
     84      * the number to be synthesized with {@link #ARG_NUMERATOR} and
     85      * {@link #ARG_DENOMINATOR}. {@link #ARG_INTEGER_PART} is optional
     86      * Also accepts the arguments {@link #ARG_GENDER},
     87      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
     88      * {@link #ARG_CASE}.
     89      */
     90     public static final String TYPE_FRACTION = "android.type.fraction";
     91 
     92     /**
     93      * The text associated with this span is a measure, consisting of a number
     94      * and a unit. The number can be a cardinal, decimal or a fraction. Set the
     95      * number with the same arguments as {@link #TYPE_CARDINAL},
     96      * {@link #TYPE_DECIMAL} or {@link #TYPE_FRACTION}. The unit can be
     97      * specified with {@link #ARG_UNIT}.
     98      * Also accepts the arguments {@link #ARG_GENDER},
     99      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
    100      * {@link #ARG_CASE}.
    101      */
    102     public static final String TYPE_MEASURE = "android.type.measure";
    103 
    104     /**
    105      * The text associated with this span is a time, consisting of a number of
    106      * hours and minutes, specified with {@link #ARG_HOURS} and
    107      * {@link #ARG_MINUTES}.
    108      * Also accepts the arguments {@link #ARG_GENDER},
    109      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and
    110      * {@link #ARG_CASE}.
    111      */
    112     public static final String TYPE_TIME = "android.type.time";
    113 
    114     /**
    115      * The text associated with this span is a date. At least one of the
    116      * arguments {@link #ARG_MONTH} and {@link #ARG_YEAR} has to be provided.
    117      * The argument {@link #ARG_DAY} is optional if {@link #ARG_MONTH} is set.
    118      * The argument {@link #ARG_WEEKDAY} is optional if {@link #ARG_DAY} is set.
    119      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
    120      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
    121      */
    122     public static final String TYPE_DATE = "android.type.date";
    123 
    124     /**
    125      * The text associated with this span is a telephone number. The argument
    126      * {@link #ARG_NUMBER_PARTS} is required. {@link #ARG_COUNTRY_CODE} and
    127      * {@link #ARG_EXTENSION} are optional.
    128      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
    129      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
    130      */
    131     public static final String TYPE_TELEPHONE = "android.type.telephone";
    132 
    133     /**
    134      * The text associated with this span is a URI (can be used for URLs and
    135      * email addresses). The full schema for URLs, which email addresses can
    136      * effectively be seen as a subset of, is:
    137      * protocol://username:password@domain:port/path?query_string#fragment_id
    138      * Hence populating just username and domain will read as an email address.
    139      * All arguments are optional, but at least one has to be provided:
    140      * {@link #ARG_PROTOCOL}, {@link #ARG_USERNAME}, {@link #ARG_PASSWORD},
    141      * {@link #ARG_DOMAIN}, {@link #ARG_PORT}, {@link #ARG_PATH},
    142      * {@link #ARG_QUERY_STRING} and {@link #ARG_FRAGMENT_ID}.
    143      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
    144      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
    145      */
    146     public static final String TYPE_ELECTRONIC = "android.type.electronic";
    147 
    148     /**
    149      * The text associated with this span is an amount of money. Set the amount
    150      * with the same arguments as {@link #TYPE_DECIMAL}.
    151      * {@link #ARG_CURRENCY} is used to set the currency. {@link #ARG_QUANTITY}
    152      * is optional.
    153      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
    154      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
    155      */
    156     public static final String TYPE_MONEY = "android.type.money";
    157 
    158     /**
    159      * The text associated with this span is a series of digits that have to be
    160      * read sequentially. The digits can be set with {@link #ARG_DIGITS}.
    161      * Also accepts the arguments {@link #ARG_GENDER}, {@link #ARG_ANIMACY},
    162      * {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
    163      */
    164     public static final String TYPE_DIGITS = "android.type.digits";
    165 
    166     /**
    167      * The text associated with this span is a series of characters that have to
    168      * be read verbatim. The engine will attempt to read out any character like
    169      * punctuation but excluding whitespace. {@link #ARG_VERBATIM} is required.
    170      * Also accepts the arguments {@link #ARG_GENDER},
    171      * {@link #ARG_ANIMACY}, {@link #ARG_MULTIPLICITY} and {@link #ARG_CASE}.
    172      */
    173     public static final String TYPE_VERBATIM = "android.type.verbatim";
    174 
    175     /**
    176      * String argument supplying gender information. Can be any of
    177      * {@link #GENDER_NEUTRAL}, {@link #GENDER_MALE} and
    178      * {@link #GENDER_FEMALE}.
    179      */
    180     public static final String ARG_GENDER = "android.arg.gender";
    181 
    182     public static final String GENDER_NEUTRAL = "android.neutral";
    183     public static final String GENDER_MALE = "android.male";
    184     public static final String GENDER_FEMALE = "android.female";
    185 
    186     /**
    187      * String argument supplying animacy information. Can be
    188      * {@link #ANIMACY_ANIMATE} or
    189      * {@link #ANIMACY_INANIMATE}
    190      */
    191     public static final String ARG_ANIMACY = "android.arg.animacy";
    192 
    193     public static final String ANIMACY_ANIMATE = "android.animate";
    194     public static final String ANIMACY_INANIMATE = "android.inanimate";
    195 
    196     /**
    197      * String argument supplying multiplicity information. Can be any of
    198      * {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
    199      * {@link #MULTIPLICITY_PLURAL}
    200      */
    201     public static final String ARG_MULTIPLICITY = "android.arg.multiplicity";
    202 
    203     public static final String MULTIPLICITY_SINGLE = "android.single";
    204     public static final String MULTIPLICITY_DUAL = "android.dual";
    205     public static final String MULTIPLICITY_PLURAL = "android.plural";
    206 
    207     /**
    208      * String argument supplying case information. Can be any of
    209      * {@link #CASE_NOMINATIVE}, {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
    210      * {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE}, {@link #CASE_VOCATIVE},
    211      * {@link #CASE_LOCATIVE} and {@link #CASE_INSTRUMENTAL}
    212      */
    213     public static final String ARG_CASE = "android.arg.case";
    214 
    215     public static final String CASE_NOMINATIVE = "android.nominative";
    216     public static final String CASE_ACCUSATIVE = "android.accusative";
    217     public static final String CASE_DATIVE = "android.dative";
    218     public static final String CASE_ABLATIVE = "android.ablative";
    219     public static final String CASE_GENITIVE = "android.genitive";
    220     public static final String CASE_VOCATIVE = "android.vocative";
    221     public static final String CASE_LOCATIVE = "android.locative";
    222     public static final String CASE_INSTRUMENTAL = "android.instrumental";
    223 
    224     /**
    225      * String supplying the text to be synthesized. The synthesizer is free
    226      * to decide how to interpret the text.
    227      * Can be used with {@link #TYPE_TEXT}.
    228      */
    229     public static final String ARG_TEXT = "android.arg.text";
    230 
    231     /**
    232      * Argument used to specify a whole number. The value can be a string of
    233      * digits of any size optionally prefixed with a - or +.
    234      * Can be used with {@link #TYPE_CARDINAL} and {@link #TYPE_ORDINAL}.
    235      */
    236     public static final String ARG_NUMBER = "android.arg.number";
    237 
    238     /**
    239      * Argument used to specify the integer part of a decimal or fraction. The
    240      * value can be a string of digits of any size optionally prefixed with
    241      * a - or +.
    242      * Can be used with {@link #TYPE_DECIMAL} and {@link #TYPE_FRACTION}.
    243      */
    244     public static final String ARG_INTEGER_PART = "android.arg.integer_part";
    245 
    246     /**
    247      * Argument used to specify the fractional part of a decimal. The value can
    248      * be a string of digits of any size.
    249      * Can be used with {@link #TYPE_DECIMAL}.
    250      */
    251     public static final String ARG_FRACTIONAL_PART =
    252         "android.arg.fractional_part";
    253 
    254     /**
    255      * Argument used to choose the suffix (thousand, million, etc) that is used
    256      * to pronounce large amounts of money. For example it can be used to
    257      * disambiguate between "two thousand five hundred dollars" and
    258      * "two point five thousand dollars".
    259      * If implemented, engines should support at least "1000", "1000000",
    260      * "1000000000" and "1000000000000".
    261      * Example: if the {@link #ARG_INTEGER_PART} argument is "10", the
    262      * {@link #ARG_FRACTIONAL_PART} argument is "4", the {@link #ARG_QUANTITY}
    263      * argument is "1000" and the {@link #ARG_CURRENCY} argument is "usd", the
    264      * TTS engine may pronounce the span as "ten point four thousand dollars".
    265      * With the same example but with the quantity set as "1000000" the TTS
    266      * engine may pronounce the span as "ten point four million dollars".
    267      * Can be used with {@link #TYPE_MONEY}.
    268      */
    269     public static final String ARG_QUANTITY =
    270             "android.arg.quantity";
    271 
    272     /**
    273      * Argument used to specify the numerator of a fraction. The value can be a
    274      * string of digits of any size optionally prefixed with a - or +.
    275      * Can be used with {@link #TYPE_FRACTION}.
    276      */
    277     public static final String ARG_NUMERATOR = "android.arg.numerator";
    278 
    279     /**
    280      * Argument used to specify the denominator of a fraction. The value can be
    281      * a string of digits of any size optionally prefixed with a + or -.
    282      * Can be used with {@link #TYPE_FRACTION}.
    283      */
    284     public static final String ARG_DENOMINATOR = "android.arg.denominator";
    285 
    286     /**
    287      * Argument used to specify the unit of a measure. The unit should always be
    288      * specified in English singular form. Prefixes may be used. Engines will do
    289      * their best to pronounce them correctly in the language used. Engines are
    290      * expected to at least support the most common ones like "meter", "second",
    291      * "degree celsius" and "degree fahrenheit" with some common prefixes like
    292      * "milli" and "kilo".
    293      * Can be used with {@link #TYPE_MEASURE}.
    294      */
    295     public static final String ARG_UNIT = "android.arg.unit";
    296 
    297     /**
    298      * Argument used to specify the hours of a time. The hours should be
    299      * provided as an integer in the range from 0 up to and including 24.
    300      * Can be used with {@link #TYPE_TIME}.
    301      */
    302     public static final String ARG_HOURS = "android.arg.hours";
    303 
    304     /**
    305      * Argument used to specify the minutes of a time. The hours should be
    306      * provided as an integer in the range from 0 up to and including 59.
    307      * Can be used with {@link #TYPE_TIME}.
    308      */
    309     public static final String ARG_MINUTES = "android.arg.minutes";
    310 
    311     /**
    312      * Argument used to specify the weekday of a date. The value should be
    313      * provided as an integer and can be any of {@link #WEEKDAY_SUNDAY},
    314      * {@link #WEEKDAY_MONDAY}, {@link #WEEKDAY_TUESDAY},
    315      * {@link #WEEKDAY_WEDNESDAY}, {@link #WEEKDAY_THURSDAY},
    316      * {@link #WEEKDAY_FRIDAY} and {@link #WEEKDAY_SATURDAY}.
    317      * Can be used with {@link #TYPE_DATE}.
    318      */
    319     public static final String ARG_WEEKDAY = "android.arg.weekday";
    320 
    321     public static final int WEEKDAY_SUNDAY = 1;
    322     public static final int WEEKDAY_MONDAY = 2;
    323     public static final int WEEKDAY_TUESDAY = 3;
    324     public static final int WEEKDAY_WEDNESDAY = 4;
    325     public static final int WEEKDAY_THURSDAY = 5;
    326     public static final int WEEKDAY_FRIDAY = 6;
    327     public static final int WEEKDAY_SATURDAY = 7;
    328 
    329     /**
    330      * Argument used to specify the day of the month of a date. The value should
    331      * be provided as an integer in the range from 1 up to and including 31.
    332      * Can be used with {@link #TYPE_DATE}.
    333      */
    334     public static final String ARG_DAY = "android.arg.day";
    335 
    336     /**
    337      * Argument used to specify the month of a date. The value should be
    338      * provided as an integer and can be any of {@link #MONTH_JANUARY},
    339      * {@link #MONTH_FEBRUARY},  {@link #MONTH_MARCH}, {@link #MONTH_APRIL},
    340      * {@link #MONTH_MAY}, {@link #MONTH_JUNE}, {@link #MONTH_JULY},
    341      * {@link #MONTH_AUGUST}, {@link #MONTH_SEPTEMBER}, {@link #MONTH_OCTOBER},
    342      * {@link #MONTH_NOVEMBER} and {@link #MONTH_DECEMBER}.
    343      * Can be used with {@link #TYPE_DATE}.
    344      */
    345     public static final String ARG_MONTH = "android.arg.month";
    346 
    347     public static final int MONTH_JANUARY = 0;
    348     public static final int MONTH_FEBRUARY = 1;
    349     public static final int MONTH_MARCH = 2;
    350     public static final int MONTH_APRIL = 3;
    351     public static final int MONTH_MAY = 4;
    352     public static final int MONTH_JUNE = 5;
    353     public static final int MONTH_JULY = 6;
    354     public static final int MONTH_AUGUST = 7;
    355     public static final int MONTH_SEPTEMBER = 8;
    356     public static final int MONTH_OCTOBER = 9;
    357     public static final int MONTH_NOVEMBER = 10;
    358     public static final int MONTH_DECEMBER = 11;
    359 
    360     /**
    361      * Argument used to specify the year of a date. The value should be provided
    362      * as a positive integer.
    363      * Can be used with {@link #TYPE_DATE}.
    364      */
    365     public static final String ARG_YEAR = "android.arg.year";
    366 
    367     /**
    368      * Argument used to specify the country code of a telephone number. Can be
    369      * a string of digits optionally prefixed with a "+".
    370      * Can be used with {@link #TYPE_TELEPHONE}.
    371      */
    372     public static final String ARG_COUNTRY_CODE = "android.arg.country_code";
    373 
    374     /**
    375      * Argument used to specify the main number part of a telephone number. Can
    376      * be a string of digits where the different parts of the telephone number
    377      * can be separated with a space, '-', '/' or '.'.
    378      * Can be used with {@link #TYPE_TELEPHONE}.
    379      */
    380     public static final String ARG_NUMBER_PARTS = "android.arg.number_parts";
    381 
    382     /**
    383      * Argument used to specify the extension part of a telephone number. Can be
    384      * a string of digits.
    385      * Can be used with {@link #TYPE_TELEPHONE}.
    386      */
    387     public static final String ARG_EXTENSION = "android.arg.extension";
    388 
    389     /**
    390      * Argument used to specify the protocol of a URI. Examples are "http" and
    391      * "ftp".
    392      * Can be used with {@link #TYPE_ELECTRONIC}.
    393      */
    394     public static final String ARG_PROTOCOL = "android.arg.protocol";
    395 
    396     /**
    397      * Argument used to specify the username part of a URI. Should be set as a
    398      * string.
    399      * Can be used with {@link #TYPE_ELECTRONIC}.
    400      */
    401     public static final String ARG_USERNAME = "android.arg.username";
    402 
    403     /**
    404      * Argument used to specify the password part of a URI. Should be set as a
    405      * string.
    406      * Can be used with {@link #TYPE_ELECTRONIC}.
    407      */
    408     public static final String ARG_PASSWORD = "android.arg.password";
    409 
    410     /**
    411      * Argument used to specify the domain part of a URI. For example
    412      * "source.android.com".
    413      * Can be used with {@link #TYPE_ELECTRONIC}.
    414      */
    415     public static final String ARG_DOMAIN = "android.arg.domain";
    416 
    417     /**
    418      * Argument used to specify the port number of a URI. Should be specified as
    419      * an integer.
    420      * Can be used with {@link #TYPE_ELECTRONIC}.
    421      */
    422     public static final String ARG_PORT = "android.arg.port";
    423 
    424     /**
    425      * Argument used to specify the path part of a URI. For example
    426      * "source/index.html".
    427      * Can be used with {@link #TYPE_ELECTRONIC}.
    428      */
    429     public static final String ARG_PATH = "android.arg.path";
    430 
    431     /**
    432      * Argument used to specify the query string of a URI. For example
    433      * "arg=value&argtwo=value".
    434      * Can be used with {@link #TYPE_ELECTRONIC}.
    435      */
    436     public static final String ARG_QUERY_STRING = "android.arg.query_string";
    437 
    438     /**
    439      * Argument used to specify the fragment id of a URI. Should be specified as
    440      * a string.
    441      * Can be used with {@link #TYPE_ELECTRONIC}.
    442      */
    443     public static final String ARG_FRAGMENT_ID = "android.arg.fragment_id";
    444 
    445     /**
    446      * Argument used to specify the currency. Should be a ISO4217 currency code,
    447      * e.g. "USD".
    448      * Can be used with {@link #TYPE_MONEY}.
    449      */
    450     public static final String ARG_CURRENCY = "android.arg.money";
    451 
    452     /**
    453      * Argument used to specify a string of digits.
    454      * Can be used with {@link #TYPE_DIGITS}.
    455      */
    456     public static final String ARG_DIGITS = "android.arg.digits";
    457 
    458     /**
    459      * Argument used to specify a string where the characters are read verbatim,
    460      * except whitespace.
    461      * Can be used with {@link #TYPE_VERBATIM}.
    462      */
    463     public static final String ARG_VERBATIM = "android.arg.verbatim";
    464 
    465     public TtsSpan(String type, PersistableBundle args) {
    466         mType = type;
    467         mArgs = args;
    468     }
    469 
    470     public TtsSpan(Parcel src) {
    471         mType = src.readString();
    472         mArgs = src.readPersistableBundle();
    473     }
    474 
    475     /**
    476      * Returns the type.
    477      * @return The type of this instance.
    478      */
    479     public String getType() {
    480         return mType;
    481     }
    482 
    483     /**
    484      * Returns a bundle of the arguments set.
    485      * @return The bundle of the arguments set.
    486      */
    487     public PersistableBundle getArgs() {
    488         return mArgs;
    489     }
    490 
    491     @Override
    492     public int describeContents() {
    493         return 0;
    494     }
    495 
    496     @Override
    497     public void writeToParcel(Parcel dest, int flags) {
    498         writeToParcelInternal(dest, flags);
    499     }
    500 
    501     /** @hide */
    502     public void writeToParcelInternal(Parcel dest, int flags) {
    503         dest.writeString(mType);
    504         dest.writePersistableBundle(mArgs);
    505     }
    506 
    507     @Override
    508     public int getSpanTypeId() {
    509         return getSpanTypeIdInternal();
    510     }
    511 
    512     /** @hide */
    513     public int getSpanTypeIdInternal() {
    514         return TextUtils.TTS_SPAN;
    515     }
    516 
    517     /**
    518      * A simple builder for TtsSpans.
    519      * This builder can be used directly, but the more specific subclasses of
    520      * this builder like {@link TtsSpan.TextBuilder} and
    521      * {@link TtsSpan.CardinalBuilder} are likely more useful.
    522      *
    523      * This class uses generics so methods from this class can return instances
    524      * of its child classes, resulting in a fluent API (CRTP pattern).
    525      */
    526     public static class Builder<C extends Builder<?>> {
    527         // Holds the type of this class.
    528         private final String mType;
    529 
    530         // Holds the arguments of this class. It only stores objects of type
    531         // String, Integer and Long.
    532         private PersistableBundle mArgs = new PersistableBundle();
    533 
    534         public Builder(String type) {
    535             mType = type;
    536         }
    537 
    538         /**
    539          * Returns a TtsSpan built from the parameters set by the setter
    540          * methods.
    541          * @return A TtsSpan built with parameters of this builder.
    542          */
    543         public TtsSpan build() {
    544             return new TtsSpan(mType, mArgs);
    545         }
    546 
    547         /**
    548          * Sets an argument to a string value.
    549          * @param arg The argument name.
    550          * @param value The value the argument should be set to.
    551          * @return This instance.
    552          */
    553         @SuppressWarnings("unchecked")
    554         public C setStringArgument(String arg, String value) {
    555             mArgs.putString(arg, value);
    556             return (C) this;
    557         }
    558 
    559         /**
    560          * Sets an argument to an int value.
    561          * @param arg The argument name.
    562          * @param value The value the argument should be set to.
    563          */
    564         @SuppressWarnings("unchecked")
    565         public C setIntArgument(String arg, int value) {
    566             mArgs.putInt(arg, value);
    567             return (C) this;
    568         }
    569 
    570         /**
    571          * Sets an argument to a long value.
    572          * @param arg The argument name.
    573          * @param value The value the argument should be set to.
    574          */
    575         @SuppressWarnings("unchecked")
    576         public C setLongArgument(String arg, long value) {
    577             mArgs.putLong(arg, value);
    578             return (C) this;
    579         }
    580     }
    581 
    582     /**
    583      * A builder for TtsSpans, has setters for morphosyntactic features.
    584      * This builder can be used directly, but the more specific subclasses of
    585      * this builder like {@link TtsSpan.TextBuilder} and
    586      * {@link TtsSpan.CardinalBuilder} are likely more useful.
    587      */
    588     public static class SemioticClassBuilder<C extends SemioticClassBuilder<?>>
    589             extends Builder<C> {
    590 
    591         public SemioticClassBuilder(String type) {
    592             super(type);
    593         }
    594 
    595         /**
    596          * Sets the gender information for this instance.
    597          * @param gender Can any of {@link #GENDER_NEUTRAL},
    598          *     {@link #GENDER_MALE} and {@link #GENDER_FEMALE}.
    599          * @return This instance.
    600          */
    601         public C setGender(String gender) {
    602             return setStringArgument(TtsSpan.ARG_GENDER, gender);
    603         }
    604 
    605         /**
    606          * Sets the animacy information for this instance.
    607          * @param animacy Can be any of {@link #ANIMACY_ANIMATE} and
    608          *     {@link #ANIMACY_INANIMATE}.
    609          * @return This instance.
    610          */
    611         public C setAnimacy(String animacy) {
    612             return setStringArgument(TtsSpan.ARG_ANIMACY, animacy);
    613         }
    614 
    615         /**
    616          * Sets the multiplicity information for this instance.
    617          * @param multiplicity Can be any of
    618          *     {@link #MULTIPLICITY_SINGLE}, {@link #MULTIPLICITY_DUAL} and
    619          *     {@link #MULTIPLICITY_PLURAL}.
    620          * @return This instance.
    621          */
    622         public C setMultiplicity(String multiplicity) {
    623             return setStringArgument(TtsSpan.ARG_MULTIPLICITY, multiplicity);
    624         }
    625 
    626         /**
    627          * Sets the grammatical case information for this instance.
    628          * @param grammaticalCase Can be any of {@link #CASE_NOMINATIVE},
    629          *     {@link #CASE_ACCUSATIVE}, {@link #CASE_DATIVE},
    630          *     {@link #CASE_ABLATIVE}, {@link #CASE_GENITIVE},
    631          *     {@link #CASE_VOCATIVE}, {@link #CASE_LOCATIVE} and
    632          *     {@link #CASE_INSTRUMENTAL}.
    633          * @return This instance.
    634          */
    635         public C setCase(String grammaticalCase) {
    636             return setStringArgument(TtsSpan.ARG_CASE, grammaticalCase);
    637         }
    638     }
    639 
    640     /**
    641      * A builder for TtsSpans of type {@link #TYPE_TEXT}.
    642      */
    643     public static class TextBuilder extends SemioticClassBuilder<TextBuilder> {
    644 
    645         /**
    646          * Creates a builder for a TtsSpan of type {@link #TYPE_TEXT}.
    647          */
    648         public TextBuilder() {
    649             super(TtsSpan.TYPE_TEXT);
    650         }
    651 
    652         /**
    653          * Creates a TtsSpan of type {@link #TYPE_TEXT} and sets the
    654          * {@link #ARG_TEXT} argument.
    655          * @param text The text to be synthesized.
    656          * @see #setText(String)
    657          */
    658         public TextBuilder(String text) {
    659             this();
    660             setText(text);
    661         }
    662 
    663         /**
    664          * Sets the {@link #ARG_TEXT} argument, the text to be synthesized.
    665          * @param text The string that will be synthesized.
    666          * @return This instance.
    667          */
    668         public TextBuilder setText(String text) {
    669             return setStringArgument(TtsSpan.ARG_TEXT, text);
    670         }
    671     }
    672 
    673     /**
    674      * A builder for TtsSpans of type {@link #TYPE_CARDINAL}.
    675      */
    676     public static class CardinalBuilder
    677             extends SemioticClassBuilder<CardinalBuilder> {
    678 
    679         /**
    680          * Creates a builder for a TtsSpan of type {@link #TYPE_CARDINAL}.
    681          */
    682         public CardinalBuilder() {
    683             super(TtsSpan.TYPE_CARDINAL);
    684         }
    685 
    686         /**
    687          * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
    688          * {@link #ARG_NUMBER} argument.
    689          * @param number The number to synthesize.
    690          * @see #setNumber(long)
    691          */
    692         public CardinalBuilder(long number) {
    693             this();
    694             setNumber(number);
    695         }
    696 
    697         /**
    698          * Creates a TtsSpan of type {@link #TYPE_CARDINAL} and sets the
    699          * {@link #ARG_NUMBER} argument.
    700          * @param number The number to synthesize.
    701          * @see #setNumber(String)
    702          */
    703         public CardinalBuilder(String number) {
    704             this();
    705             setNumber(number);
    706         }
    707 
    708         /**
    709          * Convenience method that converts the number to a String and set it to
    710          * the value for {@link #ARG_NUMBER}.
    711          * @param number The number that will be synthesized.
    712          * @return This instance.
    713          */
    714         public CardinalBuilder setNumber(long number) {
    715             return setNumber(String.valueOf(number));
    716         }
    717 
    718         /**
    719          * Sets the {@link #ARG_NUMBER} argument.
    720          * @param number A non-empty string of digits with an optional
    721          *     leading + or -.
    722          * @return This instance.
    723          */
    724         public CardinalBuilder setNumber(String number) {
    725             return setStringArgument(TtsSpan.ARG_NUMBER, number);
    726         }
    727     }
    728 
    729     /**
    730      * A builder for TtsSpans of type {@link #TYPE_ORDINAL}.
    731      */
    732     public static class OrdinalBuilder
    733             extends SemioticClassBuilder<OrdinalBuilder> {
    734 
    735         /**
    736          * Creates a builder for a TtsSpan of type {@link #TYPE_ORDINAL}.
    737          */
    738         public OrdinalBuilder() {
    739             super(TtsSpan.TYPE_ORDINAL);
    740         }
    741 
    742         /**
    743          * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
    744          * {@link #ARG_NUMBER} argument.
    745          * @param number The ordinal number to synthesize.
    746          * @see #setNumber(long)
    747          */
    748         public OrdinalBuilder(long number) {
    749             this();
    750             setNumber(number);
    751         }
    752 
    753         /**
    754          * Creates a TtsSpan of type {@link #TYPE_ORDINAL} and sets the
    755          * {@link #ARG_NUMBER} argument.
    756          * @param number The number to synthesize.
    757          * @see #setNumber(String)
    758          */
    759         public OrdinalBuilder(String number) {
    760             this();
    761             setNumber(number);
    762         }
    763 
    764         /**
    765          * Convenience method that converts the number to a String and sets it
    766          * to the value for {@link #ARG_NUMBER}.
    767          * @param number The ordinal number that will be synthesized.
    768          * @return This instance.
    769          */
    770         public OrdinalBuilder setNumber(long number) {
    771             return setNumber(String.valueOf(number));
    772         }
    773 
    774         /**
    775          * Sets the {@link #ARG_NUMBER} argument.
    776          * @param number A non-empty string of digits with an optional
    777          *     leading + or -.
    778          * @return This instance.
    779          */
    780         public OrdinalBuilder setNumber(String number) {
    781             return setStringArgument(TtsSpan.ARG_NUMBER, number);
    782         }
    783     }
    784 
    785     /**
    786      * A builder for TtsSpans of type {@link #TYPE_DECIMAL}.
    787      */
    788     public static class DecimalBuilder
    789             extends SemioticClassBuilder<DecimalBuilder> {
    790 
    791         /**
    792          * Creates a builder for a TtsSpan of type {@link #TYPE_DECIMAL}.
    793          */
    794         public DecimalBuilder() {
    795             super(TtsSpan.TYPE_DECIMAL);
    796         }
    797 
    798         /**
    799          * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
    800          * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
    801          * @see #setArgumentsFromDouble(double, int, int)
    802          */
    803         public DecimalBuilder(double number,
    804                               int minimumFractionDigits,
    805                               int maximumFractionDigits) {
    806             this();
    807             setArgumentsFromDouble(number,
    808                                    minimumFractionDigits,
    809                                    maximumFractionDigits);
    810         }
    811 
    812         /**
    813          * Creates a TtsSpan of type {@link #TYPE_DECIMAL} and sets the
    814          * {@link #ARG_INTEGER_PART} and {@link #ARG_FRACTIONAL_PART} arguments.
    815          */
    816         public DecimalBuilder(String integerPart, String fractionalPart) {
    817             this();
    818             setIntegerPart(integerPart);
    819             setFractionalPart(fractionalPart);
    820         }
    821 
    822         /**
    823          * Convenience method takes a double and a maximum number of fractional
    824          * digits, it sets the {@link #ARG_INTEGER_PART} and
    825          * {@link #ARG_FRACTIONAL_PART} arguments.
    826          * @param number The number to be synthesized.
    827          * @param minimumFractionDigits The minimum number of fraction digits
    828          *     that are pronounced.
    829          * @param maximumFractionDigits The maximum number of fraction digits
    830          *     that are pronounced. If maximumFractionDigits <
    831          *     minimumFractionDigits then minimumFractionDigits will be assumed
    832          *     to be equal to maximumFractionDigits.
    833          * @return This instance.
    834          */
    835         public DecimalBuilder setArgumentsFromDouble(
    836                 double number,
    837                 int minimumFractionDigits,
    838                 int maximumFractionDigits) {
    839             // Format double.
    840             NumberFormat formatter = NumberFormat.getInstance(Locale.US);
    841             formatter.setMinimumFractionDigits(maximumFractionDigits);
    842             formatter.setMaximumFractionDigits(maximumFractionDigits);
    843             formatter.setGroupingUsed(false);
    844             String str = formatter.format(number);
    845 
    846             // Split at decimal point.
    847             int i = str.indexOf('.');
    848             if (i >= 0) {
    849                 setIntegerPart(str.substring(0, i));
    850                 setFractionalPart(str.substring(i + 1));
    851             } else {
    852                 setIntegerPart(str);
    853             }
    854             return this;
    855         }
    856 
    857         /**
    858          * Convenience method that converts the number to a String and sets it
    859          * to the value for {@link #ARG_INTEGER_PART}.
    860          * @param integerPart The integer part of the decimal.
    861          * @return This instance.
    862          */
    863         public DecimalBuilder setIntegerPart(long integerPart) {
    864             return setIntegerPart(String.valueOf(integerPart));
    865         }
    866 
    867         /**
    868          * Sets the {@link #ARG_INTEGER_PART} argument.
    869          * @param integerPart A non-empty string of digits with an optional
    870          *     leading + or -.
    871          * @return This instance.
    872          */
    873         public DecimalBuilder setIntegerPart(String integerPart) {
    874             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
    875         }
    876 
    877         /**
    878          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
    879          * @param fractionalPart A non-empty string of digits.
    880          * @return This instance.
    881          */
    882         public DecimalBuilder setFractionalPart(String fractionalPart) {
    883             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
    884                                      fractionalPart);
    885         }
    886     }
    887 
    888     /**
    889      * A builder for TtsSpans of type {@link #TYPE_FRACTION}.
    890      */
    891     public static class FractionBuilder
    892             extends SemioticClassBuilder<FractionBuilder> {
    893 
    894         /**
    895          * Creates a builder for a TtsSpan of type {@link #TYPE_FRACTION}.
    896          */
    897         public FractionBuilder() {
    898             super(TtsSpan.TYPE_FRACTION);
    899         }
    900 
    901         /**
    902          * Creates a TtsSpan of type {@link #TYPE_FRACTION} and sets the
    903          * {@link #ARG_INTEGER_PART}, {@link #ARG_NUMERATOR}, and
    904          * {@link #ARG_DENOMINATOR} arguments.
    905          */
    906         public FractionBuilder(long integerPart,
    907                                long numerator,
    908                                long denominator) {
    909             this();
    910             setIntegerPart(integerPart);
    911             setNumerator(numerator);
    912             setDenominator(denominator);
    913         }
    914 
    915         /**
    916          * Convenience method that converts the integer to a String and sets the
    917          * argument {@link #ARG_NUMBER}.
    918          * @param integerPart The integer part.
    919          * @return This instance.
    920          */
    921         public FractionBuilder setIntegerPart(long integerPart) {
    922             return setIntegerPart(String.valueOf(integerPart));
    923         }
    924 
    925         /**
    926          * Sets the {@link #ARG_INTEGER_PART} argument.
    927          * @param integerPart A non-empty string of digits with an optional
    928          *     leading + or -.
    929          * @return This instance.
    930          */
    931         public FractionBuilder setIntegerPart(String integerPart) {
    932             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
    933         }
    934 
    935         /**
    936          * Convenience method that converts the numerator to a String and sets
    937          * the argument {@link #ARG_NUMERATOR}.
    938          * @param numerator The numerator.
    939          * @return This instance.
    940          */
    941         public FractionBuilder setNumerator(long numerator) {
    942             return setNumerator(String.valueOf(numerator));
    943         }
    944 
    945         /**
    946          * Sets the {@link #ARG_NUMERATOR} argument.
    947          * @param numerator A non-empty string of digits with an optional
    948          *     leading + or -.
    949          * @return This instance.
    950          */
    951         public FractionBuilder setNumerator(String numerator) {
    952             return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
    953         }
    954 
    955         /**
    956          * Convenience method that converts the denominator to a String and sets
    957          * the argument {@link #ARG_DENOMINATOR}.
    958          * @param denominator The denominator.
    959          * @return This instance.
    960          */
    961         public FractionBuilder setDenominator(long denominator) {
    962             return setDenominator(String.valueOf(denominator));
    963         }
    964 
    965         /**
    966          * Sets the {@link #ARG_DENOMINATOR} argument.
    967          * @param denominator A non-empty string of digits with an optional
    968          *     leading + or -.
    969          * @return This instance.
    970          */
    971         public FractionBuilder setDenominator(String denominator) {
    972             return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
    973         }
    974     }
    975 
    976     /**
    977      * A builder for TtsSpans of type {@link #TYPE_MEASURE}.
    978      */
    979     public static class MeasureBuilder
    980             extends SemioticClassBuilder<MeasureBuilder> {
    981 
    982         /**
    983          * Creates a builder for a TtsSpan of type {@link #TYPE_MEASURE}.
    984          */
    985         public MeasureBuilder() {
    986             super(TtsSpan.TYPE_MEASURE);
    987         }
    988 
    989         /**
    990          * Convenience method that converts the number to a String and set it to
    991          * the value for {@link #ARG_NUMBER}.
    992          * @param number The amount of the measure.
    993          * @return This instance.
    994          */
    995         public MeasureBuilder setNumber(long number) {
    996             return setNumber(String.valueOf(number));
    997         }
    998 
    999         /**
   1000          * Sets the {@link #ARG_NUMBER} argument.
   1001          * @param number A non-empty string of digits with an optional
   1002          *     leading + or -.
   1003          * @return This instance.
   1004          */
   1005         public MeasureBuilder setNumber(String number) {
   1006             return setStringArgument(TtsSpan.ARG_NUMBER, number);
   1007         }
   1008 
   1009         /**
   1010          * Convenience method that converts the integer part to a String and set
   1011          * it to the value for {@link #ARG_INTEGER_PART}.
   1012          * @param integerPart The integer part of a decimal or fraction.
   1013          * @return This instance.
   1014          */
   1015         public MeasureBuilder setIntegerPart(long integerPart) {
   1016             return setIntegerPart(String.valueOf(integerPart));
   1017         }
   1018 
   1019         /**
   1020          * Sets the {@link #ARG_INTEGER_PART} argument.
   1021          * @param integerPart The integer part of a decimal or fraction; a
   1022          * non-empty string of digits with an optional
   1023          *     leading + or -.
   1024          * @return This instance.
   1025          */
   1026         public MeasureBuilder setIntegerPart(String integerPart) {
   1027             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
   1028         }
   1029 
   1030         /**
   1031          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
   1032          * @param fractionalPart The fractional part of a decimal; a non-empty
   1033          *     string of digits with an optional leading + or -.
   1034          * @return This instance.
   1035          */
   1036         public MeasureBuilder setFractionalPart(String fractionalPart) {
   1037             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART,
   1038                                      fractionalPart);
   1039         }
   1040 
   1041         /**
   1042          * Convenience method that converts the numerator to a String and set it
   1043          * to the value for {@link #ARG_NUMERATOR}.
   1044          * @param numerator The numerator of a fraction.
   1045          * @return This instance.
   1046          */
   1047         public MeasureBuilder setNumerator(long numerator) {
   1048             return setNumerator(String.valueOf(numerator));
   1049         }
   1050 
   1051         /**
   1052          * Sets the {@link #ARG_NUMERATOR} argument.
   1053          * @param numerator The numerator of a fraction; a non-empty string of
   1054          *     digits with an optional leading + or -.
   1055          * @return This instance.
   1056          */
   1057         public MeasureBuilder setNumerator(String numerator) {
   1058             return setStringArgument(TtsSpan.ARG_NUMERATOR, numerator);
   1059         }
   1060 
   1061         /**
   1062          * Convenience method that converts the denominator to a String and set
   1063          * it to the value for {@link #ARG_DENOMINATOR}.
   1064          * @param denominator The denominator of a fraction.
   1065          * @return This instance.
   1066          */
   1067         public MeasureBuilder setDenominator(long denominator) {
   1068             return setDenominator(String.valueOf(denominator));
   1069         }
   1070 
   1071         /**
   1072          * Sets the {@link #ARG_DENOMINATOR} argument.
   1073          * @param denominator The denominator of a fraction; a non-empty string
   1074          *     of digits with an optional leading + or -.
   1075          * @return This instance.
   1076          */
   1077         public MeasureBuilder setDenominator(String denominator) {
   1078             return setStringArgument(TtsSpan.ARG_DENOMINATOR, denominator);
   1079         }
   1080 
   1081         /**
   1082          * Sets the {@link #ARG_UNIT} argument.
   1083          * @param unit The unit of the measure.
   1084          * @return This instance.
   1085          * @see TtsSpan.ARG_UNIT
   1086          */
   1087         public MeasureBuilder setUnit(String unit) {
   1088             return setStringArgument(TtsSpan.ARG_UNIT, unit);
   1089         }
   1090     }
   1091 
   1092     /**
   1093      * A builder for TtsSpans of type {@link #TYPE_TIME}.
   1094      */
   1095     public static class TimeBuilder
   1096             extends SemioticClassBuilder<TimeBuilder> {
   1097 
   1098         /**
   1099          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME}.
   1100          */
   1101         public TimeBuilder() {
   1102             super(TtsSpan.TYPE_TIME);
   1103         }
   1104 
   1105         /**
   1106          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
   1107          * sets the {@link #ARG_HOURS} and {@link #ARG_MINUTES} arguments.
   1108          */
   1109         public TimeBuilder(int hours, int minutes) {
   1110             this();
   1111             setHours(hours);
   1112             setMinutes(minutes);
   1113         }
   1114 
   1115         /**
   1116          * Sets the {@link #ARG_HOURS} argument.
   1117          * @param hours The value to be set for hours. See {@link #ARG_HOURS}.
   1118          * @return This instance.
   1119          * @see #ARG_HOURS
   1120          */
   1121         public TimeBuilder setHours(int hours) {
   1122             return setIntArgument(TtsSpan.ARG_HOURS, hours);
   1123         }
   1124 
   1125         /**
   1126          * Sets the {@link #ARG_MINUTES} argument.
   1127          * @param minutes The value to be set for minutes. See
   1128          *     {@link #ARG_MINUTES}.
   1129          * @return This instance.
   1130          * @see #ARG_MINUTES
   1131          */
   1132         public TimeBuilder setMinutes(int minutes) {
   1133             return setIntArgument(TtsSpan.ARG_MINUTES, minutes);
   1134         }
   1135     }
   1136 
   1137     /**
   1138      * A builder for TtsSpans of type {@link #TYPE_DATE}.
   1139      */
   1140     public static class DateBuilder
   1141             extends SemioticClassBuilder<DateBuilder> {
   1142 
   1143         /**
   1144          * Creates a builder for a TtsSpan of type {@link #TYPE_DATE}.
   1145          */
   1146         public DateBuilder() {
   1147             super(TtsSpan.TYPE_DATE);
   1148         }
   1149 
   1150         /**
   1151          * Creates a builder for a TtsSpan of type {@link #TYPE_TIME} and
   1152          * possibly sets the {@link #ARG_WEEKDAY}, {@link #ARG_DAY},
   1153          * {@link #ARG_MONTH} and {@link #ARG_YEAR} arguments. Pass null to any
   1154          * argument to leave it unset.
   1155          */
   1156         public DateBuilder(Integer weekday,
   1157                            Integer day,
   1158                            Integer month,
   1159                            Integer year) {
   1160             this();
   1161             if (weekday != null) {
   1162                 setWeekday(weekday);
   1163             }
   1164             if (day != null) {
   1165                 setDay(day);
   1166             }
   1167             if (month != null) {
   1168                 setMonth(month);
   1169             }
   1170             if (year != null) {
   1171                 setYear(year);
   1172             }
   1173         }
   1174 
   1175         /**
   1176          * Sets the {@link #ARG_WEEKDAY} argument.
   1177          * @param weekday The value to be set for weekday. See
   1178          *     {@link #ARG_WEEKDAY}.
   1179          * @return This instance.
   1180          * @see #ARG_WEEKDAY
   1181          */
   1182         public DateBuilder setWeekday(int weekday) {
   1183             return setIntArgument(TtsSpan.ARG_WEEKDAY, weekday);
   1184         }
   1185 
   1186         /**
   1187          * Sets the {@link #ARG_DAY} argument.
   1188          * @param day The value to be set for day. See {@link #ARG_DAY}.
   1189          * @return This instance.
   1190          * @see #ARG_DAY
   1191          */
   1192         public DateBuilder setDay(int day) {
   1193             return setIntArgument(TtsSpan.ARG_DAY, day);
   1194         }
   1195 
   1196         /**
   1197          * Sets the {@link #ARG_MONTH} argument.
   1198          * @param month The value to be set for month. See {@link #ARG_MONTH}.
   1199          * @return This instance.
   1200          * @see #ARG_MONTH
   1201          */
   1202         public DateBuilder setMonth(int month) {
   1203             return setIntArgument(TtsSpan.ARG_MONTH, month);
   1204         }
   1205 
   1206         /**
   1207          * Sets the {@link #ARG_YEAR} argument.
   1208          * @param year The value to be set for year. See {@link #ARG_YEAR}.
   1209          * @return This instance.
   1210          * @see #ARG_YEAR
   1211          */
   1212         public DateBuilder setYear(int year) {
   1213             return setIntArgument(TtsSpan.ARG_YEAR, year);
   1214         }
   1215     }
   1216 
   1217     /**
   1218      * A builder for TtsSpans of type {@link #TYPE_MONEY}.
   1219      */
   1220     public static class MoneyBuilder
   1221             extends SemioticClassBuilder<MoneyBuilder> {
   1222 
   1223         /**
   1224          * Creates a TtsSpan of type {@link #TYPE_MONEY}.
   1225          */
   1226         public MoneyBuilder() {
   1227             super(TtsSpan.TYPE_MONEY);
   1228         }
   1229 
   1230         /**
   1231          * Convenience method that converts the number to a String and set it to
   1232          * the value for {@link #ARG_INTEGER_PART}.
   1233          * @param integerPart The integer part of the amount.
   1234          * @return This instance.
   1235          */
   1236         public MoneyBuilder setIntegerPart(long integerPart) {
   1237             return setIntegerPart(String.valueOf(integerPart));
   1238         }
   1239 
   1240         /**
   1241          * Sets the {@link #ARG_INTEGER_PART} argument.
   1242          * @param integerPart A non-empty string of digits with an optional
   1243          *     leading + or -.
   1244          * @return This instance.
   1245          */
   1246         public MoneyBuilder setIntegerPart(String integerPart) {
   1247             return setStringArgument(TtsSpan.ARG_INTEGER_PART, integerPart);
   1248         }
   1249 
   1250         /**
   1251          * Sets the {@link #ARG_FRACTIONAL_PART} argument.
   1252          * @param fractionalPart Can be a string of digits of any size.
   1253          * @return This instance.
   1254          */
   1255         public MoneyBuilder setFractionalPart(String fractionalPart) {
   1256             return setStringArgument(TtsSpan.ARG_FRACTIONAL_PART, fractionalPart);
   1257         }
   1258 
   1259         /**
   1260          * Sets the {@link #ARG_CURRENCY} argument.
   1261          * @param currency Should be a ISO4217 currency code, e.g. "USD".
   1262          * @return This instance.
   1263          */
   1264         public MoneyBuilder setCurrency(String currency) {
   1265             return setStringArgument(TtsSpan.ARG_CURRENCY, currency);
   1266         }
   1267 
   1268         /**
   1269          * Sets the {@link #ARG_QUANTITY} argument.
   1270          * @param quantity
   1271          * @return This instance.
   1272          */
   1273         public MoneyBuilder setQuantity(String quantity) {
   1274             return setStringArgument(TtsSpan.ARG_QUANTITY, quantity);
   1275         }
   1276     }
   1277 
   1278     /**
   1279      * A builder for TtsSpans of type {@link #TYPE_TELEPHONE}.
   1280      */
   1281     public static class TelephoneBuilder
   1282             extends SemioticClassBuilder<TelephoneBuilder> {
   1283 
   1284         /**
   1285          * Creates a TtsSpan of type {@link #TYPE_TELEPHONE}.
   1286          */
   1287         public TelephoneBuilder() {
   1288             super(TtsSpan.TYPE_TELEPHONE);
   1289         }
   1290 
   1291         /**
   1292          * Creates a TtsSpan of type {@link #TYPE_TELEPHONE} and sets the
   1293          * {@link #ARG_NUMBER_PARTS} argument.
   1294          */
   1295         public TelephoneBuilder(String numberParts) {
   1296             this();
   1297             setNumberParts(numberParts);
   1298         }
   1299 
   1300         /**
   1301          * Sets the {@link #ARG_COUNTRY_CODE} argument.
   1302          * @param countryCode The country code can be a series of digits
   1303          * optionally prefixed with a "+".
   1304          * @return This instance.
   1305          */
   1306         public TelephoneBuilder setCountryCode(String countryCode) {
   1307             return setStringArgument(TtsSpan.ARG_COUNTRY_CODE, countryCode);
   1308         }
   1309 
   1310         /**
   1311          * Sets the {@link #ARG_NUMBER_PARTS} argument.
   1312          * @param numberParts The main telephone number. Can be a series of
   1313          *     digits and letters separated by spaces, "/", "-" or ".".
   1314          * @return This instance.
   1315          */
   1316         public TelephoneBuilder setNumberParts(String numberParts) {
   1317             return setStringArgument(TtsSpan.ARG_NUMBER_PARTS, numberParts);
   1318         }
   1319 
   1320         /**
   1321          * Sets the {@link #ARG_EXTENSION} argument.
   1322          * @param extension The extension can be a series of digits.
   1323          * @return This instance.
   1324          */
   1325         public TelephoneBuilder setExtension(String extension) {
   1326             return setStringArgument(TtsSpan.ARG_EXTENSION, extension);
   1327         }
   1328     }
   1329 
   1330     /**
   1331      * A builder for TtsSpans of type {@link #TYPE_ELECTRONIC}.
   1332      */
   1333     public static class ElectronicBuilder
   1334             extends SemioticClassBuilder<ElectronicBuilder> {
   1335 
   1336         /**
   1337          * Creates a TtsSpan of type {@link #TYPE_ELECTRONIC}.
   1338          */
   1339         public ElectronicBuilder() {
   1340             super(TtsSpan.TYPE_ELECTRONIC);
   1341         }
   1342 
   1343         /**
   1344          * Sets the {@link #ARG_USERNAME} and {@link #ARG_DOMAIN}
   1345          *     arguments, representing an email address.
   1346          * @param username The part before the @ in the email address.
   1347          * @param domain The part after the @ in the email address.
   1348          * @return This instance.
   1349          */
   1350         public ElectronicBuilder setEmailArguments(String username,
   1351                                                    String domain) {
   1352             return setDomain(domain).setUsername(username);
   1353         }
   1354 
   1355         /**
   1356          * Sets the {@link #ARG_PROTOCOL} argument.
   1357          * @param protocol The protocol of the URI. Examples are "http" and
   1358          *     "ftp".
   1359          * @return This instance.
   1360          */
   1361         public ElectronicBuilder setProtocol(String protocol) {
   1362             return setStringArgument(TtsSpan.ARG_PROTOCOL, protocol);
   1363         }
   1364 
   1365         /**
   1366          * Sets the {@link #ARG_USERNAME} argument.
   1367          * @return This instance.
   1368          */
   1369         public ElectronicBuilder setUsername(String username) {
   1370             return setStringArgument(TtsSpan.ARG_USERNAME, username);
   1371         }
   1372 
   1373         /**
   1374          * Sets the {@link #ARG_PASSWORD} argument.
   1375          * @return This instance.
   1376          */
   1377         public ElectronicBuilder setPassword(String password) {
   1378             return setStringArgument(TtsSpan.ARG_PASSWORD, password);
   1379         }
   1380 
   1381         /**
   1382          * Sets the {@link #ARG_DOMAIN} argument.
   1383          * @param domain The domain, for example "source.android.com".
   1384          * @return This instance.
   1385          */
   1386         public ElectronicBuilder setDomain(String domain) {
   1387             return setStringArgument(TtsSpan.ARG_DOMAIN, domain);
   1388         }
   1389 
   1390         /**
   1391          * Sets the {@link #ARG_PORT} argument.
   1392          * @return This instance.
   1393          */
   1394         public ElectronicBuilder setPort(int port) {
   1395             return setIntArgument(TtsSpan.ARG_PORT, port);
   1396         }
   1397 
   1398         /**
   1399          * Sets the {@link #ARG_PATH} argument.
   1400          * @param path For example "source/index.html".
   1401          * @return This instance.
   1402          */
   1403         public ElectronicBuilder setPath(String path) {
   1404             return setStringArgument(TtsSpan.ARG_PATH, path);
   1405         }
   1406 
   1407         /**
   1408          * Sets the {@link #ARG_QUERY_STRING} argument.
   1409          * @param queryString For example "arg=value&argtwo=value".
   1410          * @return This instance.
   1411          */
   1412         public ElectronicBuilder setQueryString(String queryString) {
   1413             return setStringArgument(TtsSpan.ARG_QUERY_STRING, queryString);
   1414         }
   1415 
   1416         /**
   1417          * Sets the {@link #ARG_FRAGMENT_ID} argument.
   1418          * @return This instance.
   1419          */
   1420         public ElectronicBuilder setFragmentId(String fragmentId) {
   1421             return setStringArgument(TtsSpan.ARG_FRAGMENT_ID, fragmentId);
   1422         }
   1423     }
   1424 
   1425     /**
   1426      * A builder for TtsSpans of type {@link #TYPE_DIGITS}.
   1427      */
   1428     public static class DigitsBuilder
   1429             extends SemioticClassBuilder<DigitsBuilder> {
   1430 
   1431         /**
   1432          * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}.
   1433          */
   1434         public DigitsBuilder() {
   1435             super(TtsSpan.TYPE_DIGITS);
   1436         }
   1437 
   1438         /**
   1439          * Creates a builder for a TtsSpan of type {@link #TYPE_DIGITS}
   1440          * and sets the {@link #ARG_DIGITS} argument.
   1441          */
   1442         public DigitsBuilder(String digits) {
   1443             this();
   1444             setDigits(digits);
   1445         }
   1446 
   1447         /**
   1448          * Sets the {@link #ARG_DIGITS} argument.
   1449          * @param digits A string of digits.
   1450          * @return This instance.
   1451          */
   1452         public DigitsBuilder setDigits(String digits) {
   1453             return setStringArgument(TtsSpan.ARG_DIGITS, digits);
   1454         }
   1455     }
   1456 
   1457     /**
   1458      * A builder for TtsSpans of type {@link #TYPE_VERBATIM}.
   1459      */
   1460     public static class VerbatimBuilder
   1461             extends SemioticClassBuilder<VerbatimBuilder> {
   1462 
   1463         /**
   1464          * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}.
   1465          */
   1466         public VerbatimBuilder() {
   1467             super(TtsSpan.TYPE_VERBATIM);
   1468         }
   1469 
   1470         /**
   1471          * Creates a builder for a TtsSpan of type {@link #TYPE_VERBATIM}
   1472          * and sets the {@link #ARG_VERBATIM} argument.
   1473          */
   1474         public VerbatimBuilder(String verbatim) {
   1475             this();
   1476             setVerbatim(verbatim);
   1477         }
   1478 
   1479         /**
   1480          * Sets the {@link #ARG_VERBATIM} argument.
   1481          * @param verbatim A string of characters that will be read verbatim,
   1482          *     except whitespace.
   1483          * @return This instance.
   1484          */
   1485         public VerbatimBuilder setVerbatim(String verbatim) {
   1486             return setStringArgument(TtsSpan.ARG_VERBATIM, verbatim);
   1487         }
   1488     }
   1489 }
   1490