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