Methods Summary |
---|
private static java.lang.String | appendPwCharBackToOrigDialStr(int dialableIndex, java.lang.String origStr, java.lang.String dialStr)
String retStr;
// There is only 1 P/W character before the dialable characters
if (dialableIndex == 1) {
StringBuilder ret = new StringBuilder(origStr);
ret = ret.append(dialStr.charAt(0));
retStr = ret.toString();
} else {
// It means more than 1 P/W characters in the post dial string,
// appends to retStr
String nonDigitStr = dialStr.substring(0,dialableIndex);
retStr = origStr.concat(nonDigitStr);
}
return retStr;
|
private static char | bcdToChar(byte b)returns 0 on invalid value
if (b < 0xa) {
return (char)('0" + b);
} else switch (b) {
case 0xa: return '*";
case 0xb: return '#";
case 0xc: return PAUSE;
case 0xd: return WILD;
default: return 0;
}
|
public static java.lang.String | calledPartyBCDFragmentToString(byte[] bytes, int offset, int length)Like calledPartyBCDToString, but field does not start with a
TOA byte. For example: SIM ADN extension fields
StringBuilder ret = new StringBuilder(length * 2);
internalCalledPartyBCDFragmentToString(ret, bytes, offset, length);
return ret.toString();
|
public static java.lang.String | calledPartyBCDToString(byte[] bytes, int offset, int length)3GPP TS 24.008 10.5.4.7
Called Party BCD Number
See Also TS 51.011 10.5.1 "dialing number/ssc string"
and TS 11.11 "10.3.1 EF adn (Abbreviated dialing numbers)"
boolean prependPlus = false;
StringBuilder ret = new StringBuilder(1 + length * 2);
if (length < 2) {
return "";
}
//Only TON field should be taken in consideration
if ((bytes[offset] & 0xf0) == (TOA_International & 0xf0)) {
prependPlus = true;
}
internalCalledPartyBCDFragmentToString(
ret, bytes, offset + 1, length - 1);
if (prependPlus && ret.length() == 0) {
// If the only thing there is a prepended plus, return ""
return "";
}
if (prependPlus) {
// This is an "international number" and should have
// a plus prepended to the dialing number. But there
// can also be GSM MMI codes as defined in TS 22.030 6.5.2
// so we need to handle those also.
//
// http://web.telia.com/~u47904776/gsmkode.htm
// has a nice list of some of these GSM codes.
//
// Examples are:
// **21*+886988171479#
// **21*8311234567#
// *21#
// #21#
// *#21#
// *31#+11234567890
// #31#+18311234567
// #31#8311234567
// 18311234567
// +18311234567#
// +18311234567
// Odd ball cases that some phones handled
// where there is no dialing number so they
// append the "+"
// *21#+
// **21#+
String retString = ret.toString();
Pattern p = Pattern.compile("(^[#*])(.*)([#*])(.*)(#)$");
Matcher m = p.matcher(retString);
if (m.matches()) {
if ("".equals(m.group(2))) {
// Started with two [#*] ends with #
// So no dialing number and we'll just
// append a +, this handles **21#+
ret = new StringBuilder();
ret.append(m.group(1));
ret.append(m.group(3));
ret.append(m.group(4));
ret.append(m.group(5));
ret.append("+");
} else {
// Starts with [#*] and ends with #
// Assume group 4 is a dialing number
// such as *21*+1234554#
ret = new StringBuilder();
ret.append(m.group(1));
ret.append(m.group(2));
ret.append(m.group(3));
ret.append("+");
ret.append(m.group(4));
ret.append(m.group(5));
}
} else {
p = Pattern.compile("(^[#*])(.*)([#*])(.*)");
m = p.matcher(retString);
if (m.matches()) {
// Starts with [#*] and only one other [#*]
// Assume the data after last [#*] is dialing
// number (i.e. group 4) such as *31#+11234567890.
// This also includes the odd ball *21#+
ret = new StringBuilder();
ret.append(m.group(1));
ret.append(m.group(2));
ret.append(m.group(3));
ret.append("+");
ret.append(m.group(4));
} else {
// Does NOT start with [#*] just prepend '+'
ret = new StringBuilder();
ret.append('+");
ret.append(retString);
}
}
}
return ret.toString();
|
public static java.lang.String | cdmaCheckAndProcessPlusCode(java.lang.String dialStr)This function checks if there is a plus sign (+) in the passed-in dialing number.
If there is, it processes the plus sign based on the default telephone
numbering plan of the system when the phone is activated and the current
telephone numbering plan of the system that the phone is camped on.
Currently, we only support the case that the default and current telephone
numbering plans are North American Numbering Plan(NANP).
The passed-in dialStr should only contain the valid format as described below,
1) the 1st character in the dialStr should be one of the really dialable
characters listed below
ISO-LATIN characters 0-9, *, # , +
2) the dialStr should already strip out the separator characters,
every character in the dialStr should be one of the non separator characters
listed below
ISO-LATIN characters 0-9, *, # , +, WILD, WAIT, PAUSE
Otherwise, this function returns the dial string passed in
if (!TextUtils.isEmpty(dialStr)) {
if (isReallyDialable(dialStr.charAt(0)) &&
isNonSeparator(dialStr)) {
String currIso = TelephonyManager.getDefault().getNetworkCountryIso();
String defaultIso = TelephonyManager.getDefault().getSimCountryIso();
if (!TextUtils.isEmpty(currIso) && !TextUtils.isEmpty(defaultIso)) {
return cdmaCheckAndProcessPlusCodeByNumberFormat(dialStr,
getFormatTypeFromCountryCode(currIso),
getFormatTypeFromCountryCode(defaultIso));
}
}
}
return dialStr;
|
public static java.lang.String | cdmaCheckAndProcessPlusCodeByNumberFormat(java.lang.String dialStr, int currFormat, int defaultFormat)This function should be called from checkAndProcessPlusCode only
And it is used for test purpose also.
It checks the dial string by looping through the network portion,
post dial portion 1, post dial porting 2, etc. If there is any
plus sign, then process the plus sign.
Currently, this function supports the plus sign conversion within NANP only.
Specifically, it handles the plus sign in the following ways:
1)+1NANP,remove +, e.g.
+18475797000 is converted to 18475797000,
2)+NANP or +non-NANP Numbers,replace + with the current NANP IDP, e.g,
+8475797000 is converted to 0118475797000,
+11875767800 is converted to 01111875767800
3)+1NANP in post dial string(s), e.g.
8475797000;+18475231753 is converted to 8475797000;18475231753
String retStr = dialStr;
boolean useNanp = (currFormat == defaultFormat) && (currFormat == FORMAT_NANP);
// Checks if the plus sign character is in the passed-in dial string
if (dialStr != null &&
dialStr.lastIndexOf(PLUS_SIGN_STRING) != -1) {
// Handle case where default and current telephone numbering plans are NANP.
String postDialStr = null;
String tempDialStr = dialStr;
// Sets the retStr to null since the conversion will be performed below.
retStr = null;
if (DBG) log("checkAndProcessPlusCode,dialStr=" + dialStr);
// This routine is to process the plus sign in the dial string by loop through
// the network portion, post dial portion 1, post dial portion 2... etc. if
// applied
do {
String networkDialStr;
// Format the string based on the rules for the country the number is from,
// and the current country the phone is camped
if (useNanp) {
networkDialStr = extractNetworkPortion(tempDialStr);
} else {
networkDialStr = extractNetworkPortionAlt(tempDialStr);
}
networkDialStr = processPlusCode(networkDialStr, useNanp);
// Concatenates the string that is converted from network portion
if (!TextUtils.isEmpty(networkDialStr)) {
if (retStr == null) {
retStr = networkDialStr;
} else {
retStr = retStr.concat(networkDialStr);
}
} else {
// This should never happen since we checked the if dialStr is null
// and if it contains the plus sign in the beginning of this function.
// The plus sign is part of the network portion.
Rlog.e("checkAndProcessPlusCode: null newDialStr", networkDialStr);
return dialStr;
}
postDialStr = extractPostDialPortion(tempDialStr);
if (!TextUtils.isEmpty(postDialStr)) {
int dialableIndex = findDialableIndexFromPostDialStr(postDialStr);
// dialableIndex should always be greater than 0
if (dialableIndex >= 1) {
retStr = appendPwCharBackToOrigDialStr(dialableIndex,
retStr,postDialStr);
// Skips the P/W character, extracts the dialable portion
tempDialStr = postDialStr.substring(dialableIndex);
} else {
// Non-dialable character such as P/W should not be at the end of
// the dial string after P/W processing in CdmaConnection.java
// Set the postDialStr to "" to break out of the loop
if (dialableIndex < 0) {
postDialStr = "";
}
Rlog.e("wrong postDialStr=", postDialStr);
}
}
if (DBG) log("checkAndProcessPlusCode,postDialStr=" + postDialStr);
} while (!TextUtils.isEmpty(postDialStr) && !TextUtils.isEmpty(tempDialStr));
}
return retStr;
|
public static java.lang.String | cdmaCheckAndProcessPlusCodeForSms(java.lang.String dialStr)Process phone number for CDMA, converting plus code using the home network number format.
This is used for outgoing SMS messages.
if (!TextUtils.isEmpty(dialStr)) {
if (isReallyDialable(dialStr.charAt(0)) && isNonSeparator(dialStr)) {
String defaultIso = TelephonyManager.getDefault().getSimCountryIso();
if (!TextUtils.isEmpty(defaultIso)) {
int format = getFormatTypeFromCountryCode(defaultIso);
return cdmaCheckAndProcessPlusCodeByNumberFormat(dialStr, format, format);
}
}
}
return dialStr;
|
private static int | charToBCD(char c)
if (c >= '0" && c <= '9") {
return c - '0";
} else if (c == '*") {
return 0xa;
} else if (c == '#") {
return 0xb;
} else if (c == PAUSE) {
return 0xc;
} else if (c == WILD) {
return 0xd;
} else if (c == WAIT) {
return 0xe;
} else {
throw new RuntimeException ("invalid char for BCD " + c);
}
|
private static boolean | checkPrefixIsIgnorable(java.lang.String str, int forwardIndex, int backwardIndex)Return true if the prefix of "str" is "ignorable". Here, "ignorable" means
that "str" has only one digit and separator characters. The one digit is
assumed to be trunk prefix.
boolean trunk_prefix_was_read = false;
while (backwardIndex >= forwardIndex) {
if (tryGetISODigit(str.charAt(backwardIndex)) >= 0) {
if (trunk_prefix_was_read) {
// More than one digit appeared, meaning that "a" and "b"
// is different.
return false;
} else {
// Ignore just one digit, assuming it is trunk prefix.
trunk_prefix_was_read = true;
}
} else if (isDialable(str.charAt(backwardIndex))) {
// Trunk prefix is a digit, not "*", "#"...
return false;
}
backwardIndex--;
}
return true;
|
public static boolean | compare(java.lang.String a, java.lang.String b)Compare phone numbers a and b, return true if they're identical enough for caller ID purposes.
// We've used loose comparation at least Eclair, which may change in the future.
return compare(a, b, false);
|
public static boolean | compare(android.content.Context context, java.lang.String a, java.lang.String b)Compare phone numbers a and b, and return true if they're identical
enough for caller ID purposes. Checks a resource to determine whether
to use a strict or loose comparison algorithm.
boolean useStrict = context.getResources().getBoolean(
com.android.internal.R.bool.config_use_strict_phone_number_comparation);
return compare(a, b, useStrict);
|
public static boolean | compare(java.lang.String a, java.lang.String b, boolean useStrictComparation)
return (useStrictComparation ? compareStrictly(a, b) : compareLoosely(a, b));
|
public static boolean | compareLoosely(java.lang.String a, java.lang.String b)Compare phone numbers a and b, return true if they're identical
enough for caller ID purposes.
- Compares from right to left
- requires MIN_MATCH (7) characters to match
- handles common trunk prefixes and international prefixes
(basically, everything except the Russian trunk prefix)
Note that this method does not return false even when the two phone numbers
are not exactly same; rather; we can call this method "similar()", not "equals()".
int ia, ib;
int matched;
int numNonDialableCharsInA = 0;
int numNonDialableCharsInB = 0;
if (a == null || b == null) return a == b;
if (a.length() == 0 || b.length() == 0) {
return false;
}
ia = indexOfLastNetworkChar (a);
ib = indexOfLastNetworkChar (b);
matched = 0;
while (ia >= 0 && ib >=0) {
char ca, cb;
boolean skipCmp = false;
ca = a.charAt(ia);
if (!isDialable(ca)) {
ia--;
skipCmp = true;
numNonDialableCharsInA++;
}
cb = b.charAt(ib);
if (!isDialable(cb)) {
ib--;
skipCmp = true;
numNonDialableCharsInB++;
}
if (!skipCmp) {
if (cb != ca && ca != WILD && cb != WILD) {
break;
}
ia--; ib--; matched++;
}
}
if (matched < MIN_MATCH) {
int effectiveALen = a.length() - numNonDialableCharsInA;
int effectiveBLen = b.length() - numNonDialableCharsInB;
// if the number of dialable chars in a and b match, but the matched chars < MIN_MATCH,
// treat them as equal (i.e. 404-04 and 40404)
if (effectiveALen == effectiveBLen && effectiveALen == matched) {
return true;
}
return false;
}
// At least one string has matched completely;
if (matched >= MIN_MATCH && (ia < 0 || ib < 0)) {
return true;
}
/*
* Now, what remains must be one of the following for a
* match:
*
* - a '+' on one and a '00' or a '011' on the other
* - a '0' on one and a (+,00)<country code> on the other
* (for this, a '0' and a '00' prefix would have succeeded above)
*/
if (matchIntlPrefix(a, ia + 1)
&& matchIntlPrefix (b, ib +1)
) {
return true;
}
if (matchTrunkPrefix(a, ia + 1)
&& matchIntlPrefixAndCC(b, ib +1)
) {
return true;
}
if (matchTrunkPrefix(b, ib + 1)
&& matchIntlPrefixAndCC(a, ia +1)
) {
return true;
}
return false;
|
public static boolean | compareStrictly(java.lang.String a, java.lang.String b)
return compareStrictly(a, b, true);
|
public static boolean | compareStrictly(java.lang.String a, java.lang.String b, boolean acceptInvalidCCCPrefix)
if (a == null || b == null) {
return a == b;
} else if (a.length() == 0 && b.length() == 0) {
return false;
}
int forwardIndexA = 0;
int forwardIndexB = 0;
CountryCallingCodeAndNewIndex cccA =
tryGetCountryCallingCodeAndNewIndex(a, acceptInvalidCCCPrefix);
CountryCallingCodeAndNewIndex cccB =
tryGetCountryCallingCodeAndNewIndex(b, acceptInvalidCCCPrefix);
boolean bothHasCountryCallingCode = false;
boolean okToIgnorePrefix = true;
boolean trunkPrefixIsOmittedA = false;
boolean trunkPrefixIsOmittedB = false;
if (cccA != null && cccB != null) {
if (cccA.countryCallingCode != cccB.countryCallingCode) {
// Different Country Calling Code. Must be different phone number.
return false;
}
// When both have ccc, do not ignore trunk prefix. Without this,
// "+81123123" becomes same as "+810123123" (+81 == Japan)
okToIgnorePrefix = false;
bothHasCountryCallingCode = true;
forwardIndexA = cccA.newIndex;
forwardIndexB = cccB.newIndex;
} else if (cccA == null && cccB == null) {
// When both do not have ccc, do not ignore trunk prefix. Without this,
// "123123" becomes same as "0123123"
okToIgnorePrefix = false;
} else {
if (cccA != null) {
forwardIndexA = cccA.newIndex;
} else {
int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
if (tmp >= 0) {
forwardIndexA = tmp;
trunkPrefixIsOmittedA = true;
}
}
if (cccB != null) {
forwardIndexB = cccB.newIndex;
} else {
int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
if (tmp >= 0) {
forwardIndexB = tmp;
trunkPrefixIsOmittedB = true;
}
}
}
int backwardIndexA = a.length() - 1;
int backwardIndexB = b.length() - 1;
while (backwardIndexA >= forwardIndexA && backwardIndexB >= forwardIndexB) {
boolean skip_compare = false;
final char chA = a.charAt(backwardIndexA);
final char chB = b.charAt(backwardIndexB);
if (isSeparator(chA)) {
backwardIndexA--;
skip_compare = true;
}
if (isSeparator(chB)) {
backwardIndexB--;
skip_compare = true;
}
if (!skip_compare) {
if (chA != chB) {
return false;
}
backwardIndexA--;
backwardIndexB--;
}
}
if (okToIgnorePrefix) {
if ((trunkPrefixIsOmittedA && forwardIndexA <= backwardIndexA) ||
!checkPrefixIsIgnorable(a, forwardIndexA, backwardIndexA)) {
if (acceptInvalidCCCPrefix) {
// Maybe the code handling the special case for Thailand makes the
// result garbled, so disable the code and try again.
// e.g. "16610001234" must equal to "6610001234", but with
// Thailand-case handling code, they become equal to each other.
//
// Note: we select simplicity rather than adding some complicated
// logic here for performance(like "checking whether remaining
// numbers are just 66 or not"), assuming inputs are small
// enough.
return compare(a, b, false);
} else {
return false;
}
}
if ((trunkPrefixIsOmittedB && forwardIndexB <= backwardIndexB) ||
!checkPrefixIsIgnorable(b, forwardIndexA, backwardIndexB)) {
if (acceptInvalidCCCPrefix) {
return compare(a, b, false);
} else {
return false;
}
}
} else {
// In the US, 1-650-555-1234 must be equal to 650-555-1234,
// while 090-1234-1234 must not be equal to 90-1234-1234 in Japan.
// This request exists just in US (with 1 trunk (NDD) prefix).
// In addition, "011 11 7005554141" must not equal to "+17005554141",
// while "011 1 7005554141" must equal to "+17005554141"
//
// In this comparison, we ignore the prefix '1' just once, when
// - at least either does not have CCC, or
// - the remaining non-separator number is 1
boolean maybeNamp = !bothHasCountryCallingCode;
while (backwardIndexA >= forwardIndexA) {
final char chA = a.charAt(backwardIndexA);
if (isDialable(chA)) {
if (maybeNamp && tryGetISODigit(chA) == 1) {
maybeNamp = false;
} else {
return false;
}
}
backwardIndexA--;
}
while (backwardIndexB >= forwardIndexB) {
final char chB = b.charAt(backwardIndexB);
if (isDialable(chB)) {
if (maybeNamp && tryGetISODigit(chB) == 1) {
maybeNamp = false;
} else {
return false;
}
}
backwardIndexB--;
}
}
return true;
|
public static java.lang.String | convertAndStrip(java.lang.String phoneNumber)Translates keypad letters to actual digits (e.g. 1-800-GOOG-411 will
become 1-800-4664-411), and then strips all separators (e.g. 1-800-4664-411 will become
18004664411).
return stripSeparators(convertKeypadLettersToDigits(phoneNumber));
|
public static java.lang.String | convertKeypadLettersToDigits(java.lang.String input)Translates any alphabetic letters (i.e. [A-Za-z]) in the
specified phone number into the equivalent numeric digits,
according to the phone keypad letter mapping described in
ITU E.161 and ISO/IEC 9995-8.
if (input == null) {
return input;
}
int len = input.length();
if (len == 0) {
return input;
}
char[] out = input.toCharArray();
for (int i = 0; i < len; i++) {
char c = out[i];
// If this char isn't in KEYPAD_MAP at all, just leave it alone.
out[i] = (char) KEYPAD_MAP.get(c, c);
}
return new String(out);
|
public static java.lang.String | convertPreDial(java.lang.String phoneNumber)Converts pause and tonewait pause characters
to Android representation.
RFC 3601 says pause is 'p' and tonewait is 'w'.
if (phoneNumber == null) {
return null;
}
int len = phoneNumber.length();
StringBuilder ret = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = phoneNumber.charAt(i);
if (isPause(c)) {
c = PAUSE;
} else if (isToneWait(c)) {
c = WAIT;
}
ret.append(c);
}
return ret.toString();
|
public static java.lang.String | extractNetworkPortion(java.lang.String phoneNumber)Extracts the network address portion and canonicalizes
(filters out separators.)
Network address portion is everything up to DTMF control digit
separators (pause or wait), but without non-dialable characters.
Please note that the GSM wild character is allowed in the result.
This must be resolved before dialing.
Returns null if phoneNumber == null
if (phoneNumber == null) {
return null;
}
int len = phoneNumber.length();
StringBuilder ret = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = phoneNumber.charAt(i);
// Character.digit() supports ASCII and Unicode digits (fullwidth, Arabic-Indic, etc.)
int digit = Character.digit(c, 10);
if (digit != -1) {
ret.append(digit);
} else if (c == '+") {
// Allow '+' as first character or after CLIR MMI prefix
String prefix = ret.toString();
if (prefix.length() == 0 || prefix.equals(CLIR_ON) || prefix.equals(CLIR_OFF)) {
ret.append(c);
}
} else if (isDialable(c)) {
ret.append(c);
} else if (isStartsPostDial (c)) {
break;
}
}
return ret.toString();
|
public static java.lang.String | extractNetworkPortionAlt(java.lang.String phoneNumber)Extracts the network address portion and canonicalize.
This function is equivalent to extractNetworkPortion(), except
for allowing the PLUS character to occur at arbitrary positions
in the address portion, not just the first position.
if (phoneNumber == null) {
return null;
}
int len = phoneNumber.length();
StringBuilder ret = new StringBuilder(len);
boolean haveSeenPlus = false;
for (int i = 0; i < len; i++) {
char c = phoneNumber.charAt(i);
if (c == '+") {
if (haveSeenPlus) {
continue;
}
haveSeenPlus = true;
}
if (isDialable(c)) {
ret.append(c);
} else if (isStartsPostDial (c)) {
break;
}
}
return ret.toString();
|
public static java.lang.String | extractPostDialPortion(java.lang.String phoneNumber)Extracts the post-dial sequence of DTMF control digits, pauses, and
waits. Strips separators. This string may be empty, but will not be null
unless phoneNumber == null.
Returns null if phoneNumber == null
if (phoneNumber == null) return null;
int trimIndex;
StringBuilder ret = new StringBuilder();
trimIndex = indexOfLastNetworkChar (phoneNumber);
for (int i = trimIndex + 1, s = phoneNumber.length()
; i < s; i++
) {
char c = phoneNumber.charAt(i);
if (isNonSeparator(c)) {
ret.append(c);
}
}
return ret.toString();
|
private static int | findDialableIndexFromPostDialStr(java.lang.String postDialStr)
for (int index = 0;index < postDialStr.length();index++) {
char c = postDialStr.charAt(index);
if (isReallyDialable(c)) {
return index;
}
}
return -1;
|
public static void | formatJapaneseNumber(android.text.Editable text)Formats a phone number in-place using the Japanese formatting rules.
Numbers will be formatted as:
03-xxxx-xxxx
090-xxxx-xxxx
0120-xxx-xxx
+81-3-xxxx-xxxx
+81-90-xxxx-xxxx
JapanesePhoneNumberFormatter.format(text);
|
public static void | formatNanpNumber(android.text.Editable text)Formats a phone number in-place using the NANP formatting rules. Numbers will be formatted
as:
xxxxx
xxx-xxxx
xxx-xxx-xxxx
1-xxx-xxx-xxxx
+1-xxx-xxx-xxxx
int length = text.length();
if (length > "+1-nnn-nnn-nnnn".length()) {
// The string is too long to be formatted
return;
} else if (length <= 5) {
// The string is either a shortcode or too short to be formatted
return;
}
CharSequence saved = text.subSequence(0, length);
// Strip the dashes first, as we're going to add them back
removeDashes(text);
length = text.length();
// When scanning the number we record where dashes need to be added,
// if they're non-0 at the end of the scan the dashes will be added in
// the proper places.
int dashPositions[] = new int[3];
int numDashes = 0;
int state = NANP_STATE_DIGIT;
int numDigits = 0;
for (int i = 0; i < length; i++) {
char c = text.charAt(i);
switch (c) {
case '1":
if (numDigits == 0 || state == NANP_STATE_PLUS) {
state = NANP_STATE_ONE;
break;
}
// fall through
case '2":
case '3":
case '4":
case '5":
case '6":
case '7":
case '8":
case '9":
case '0":
if (state == NANP_STATE_PLUS) {
// Only NANP number supported for now
text.replace(0, length, saved);
return;
} else if (state == NANP_STATE_ONE) {
// Found either +1 or 1, follow it up with a dash
dashPositions[numDashes++] = i;
} else if (state != NANP_STATE_DASH && (numDigits == 3 || numDigits == 6)) {
// Found a digit that should be after a dash that isn't
dashPositions[numDashes++] = i;
}
state = NANP_STATE_DIGIT;
numDigits++;
break;
case '-":
state = NANP_STATE_DASH;
break;
case '+":
if (i == 0) {
// Plus is only allowed as the first character
state = NANP_STATE_PLUS;
break;
}
// Fall through
default:
// Unknown character, bail on formatting
text.replace(0, length, saved);
return;
}
}
if (numDigits == 7) {
// With 7 digits we want xxx-xxxx, not xxx-xxx-x
numDashes--;
}
// Actually put the dashes in place
for (int i = 0; i < numDashes; i++) {
int pos = dashPositions[i];
text.replace(pos + i, pos + i, "-");
}
// Remove trailing dashes
int len = text.length();
while (len > 0) {
if (text.charAt(len - 1) == '-") {
text.delete(len - 1, len);
len--;
} else {
break;
}
}
|
public static java.lang.String | formatNumber(java.lang.String source)Breaks the given number down and formats it according to the rules
for the country the number is from.
SpannableStringBuilder text = new SpannableStringBuilder(source);
formatNumber(text, getFormatTypeForLocale(Locale.getDefault()));
return text.toString();
|
public static java.lang.String | formatNumber(java.lang.String source, int defaultFormattingType)Formats the given number with the given formatting type. Currently
{@link #FORMAT_NANP} and {@link #FORMAT_JAPAN} are supported as a formating type.
SpannableStringBuilder text = new SpannableStringBuilder(source);
formatNumber(text, defaultFormattingType);
return text.toString();
|
public static void | formatNumber(android.text.Editable text, int defaultFormattingType)Formats a phone number in-place. Currently {@link #FORMAT_JAPAN} and {@link #FORMAT_NANP}
is supported as a second argument.
int formatType = defaultFormattingType;
if (text.length() > 2 && text.charAt(0) == '+") {
if (text.charAt(1) == '1") {
formatType = FORMAT_NANP;
} else if (text.length() >= 3 && text.charAt(1) == '8"
&& text.charAt(2) == '1") {
formatType = FORMAT_JAPAN;
} else {
formatType = FORMAT_UNKNOWN;
}
}
switch (formatType) {
case FORMAT_NANP:
formatNanpNumber(text);
return;
case FORMAT_JAPAN:
formatJapaneseNumber(text);
return;
case FORMAT_UNKNOWN:
removeDashes(text);
return;
}
|
public static java.lang.String | formatNumber(java.lang.String phoneNumber, java.lang.String defaultCountryIso)Format a phone number.
If the given number doesn't have the country code, the phone will be
formatted to the default country's convention.
// Do not attempt to format numbers that start with a hash or star symbol.
if (phoneNumber.startsWith("#") || phoneNumber.startsWith("*")) {
return phoneNumber;
}
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
String result = null;
try {
PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
result = util.formatInOriginalFormat(pn, defaultCountryIso);
} catch (NumberParseException e) {
}
return result;
|
public static java.lang.String | formatNumber(java.lang.String phoneNumber, java.lang.String phoneNumberE164, java.lang.String defaultCountryIso)Format the phone number only if the given number hasn't been formatted.
The number which has only dailable character is treated as not being
formatted.
int len = phoneNumber.length();
for (int i = 0; i < len; i++) {
if (!isDialable(phoneNumber.charAt(i))) {
return phoneNumber;
}
}
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
// Get the country code from phoneNumberE164
if (phoneNumberE164 != null && phoneNumberE164.length() >= 2
&& phoneNumberE164.charAt(0) == '+") {
try {
// The number to be parsed is in E164 format, so the default region used doesn't
// matter.
PhoneNumber pn = util.parse(phoneNumberE164, "ZZ");
String regionCode = util.getRegionCodeForNumber(pn);
if (!TextUtils.isEmpty(regionCode) &&
// This makes sure phoneNumber doesn't contain an IDD
normalizeNumber(phoneNumber).indexOf(phoneNumberE164.substring(1)) <= 0) {
defaultCountryIso = regionCode;
}
} catch (NumberParseException e) {
}
}
String result = formatNumber(phoneNumber, defaultCountryIso);
return result != null ? result : phoneNumber;
|
public static java.lang.String | formatNumberToE164(java.lang.String phoneNumber, java.lang.String defaultCountryIso)Format the given phoneNumber to the E.164 representation.
The given phone number must have an area code and could have a country
code.
The defaultCountryIso is used to validate the given number and generate
the E.164 phone number if the given number doesn't have a country code.
PhoneNumberUtil util = PhoneNumberUtil.getInstance();
String result = null;
try {
PhoneNumber pn = util.parse(phoneNumber, defaultCountryIso);
if (util.isValidNumber(pn)) {
result = util.format(pn, PhoneNumberFormat.E164);
}
} catch (NumberParseException e) {
}
return result;
|
private static java.lang.String | getCurrentIdp(boolean useNanp)
// in case, there is no IDD is found, we shouldn't convert it.
String ps = SystemProperties.get(
PROPERTY_OPERATOR_IDP_STRING, useNanp ? NANP_IDP_STRING : PLUS_SIGN_STRING);
return ps;
|
private static int | getDefaultVoiceSubId()Returns Default voice subscription Id.
return SubscriptionManager.getDefaultVoiceSubId();
|
public static int | getFormatTypeForLocale(java.util.Locale locale)Returns the phone number formatting type for the given locale.
String country = locale.getCountry();
return getFormatTypeFromCountryCode(country);
|
private static int | getFormatTypeFromCountryCode(java.lang.String country)
// Check for the NANP countries
int length = NANP_COUNTRIES.length;
for (int i = 0; i < length; i++) {
if (NANP_COUNTRIES[i].compareToIgnoreCase(country) == 0) {
return FORMAT_NANP;
}
}
if ("jp".compareToIgnoreCase(country) == 0) {
return FORMAT_JAPAN;
}
return FORMAT_UNKNOWN;
|
public static java.lang.String | getNumberFromIntent(android.content.Intent intent, android.content.Context context)Extracts the phone number from an Intent.
String number = null;
Uri uri = intent.getData();
if (uri == null) {
return null;
}
String scheme = uri.getScheme();
if (scheme.equals("tel") || scheme.equals("sip")) {
return uri.getSchemeSpecificPart();
}
if (context == null) {
return null;
}
String type = intent.resolveType(context);
String phoneColumn = null;
// Correctly read out the phone entry based on requested provider
final String authority = uri.getAuthority();
if (Contacts.AUTHORITY.equals(authority)) {
phoneColumn = Contacts.People.Phones.NUMBER;
} else if (ContactsContract.AUTHORITY.equals(authority)) {
phoneColumn = ContactsContract.CommonDataKinds.Phone.NUMBER;
}
final Cursor c = context.getContentResolver().query(uri, new String[] {
phoneColumn
}, null, null, null);
if (c != null) {
try {
if (c.moveToFirst()) {
number = c.getString(c.getColumnIndex(phoneColumn));
}
} finally {
c.close();
}
}
return number;
|
public static java.lang.String | getStrippedReversed(java.lang.String phoneNumber)Returns the network portion reversed.
This string is intended to go into an index column for a
database lookup.
Returns null if phoneNumber == null
String np = extractNetworkPortionAlt(phoneNumber);
if (np == null) return null;
return internalGetStrippedReversed(np, np.length());
|
public static java.lang.String | getUsernameFromUriNumber(java.lang.String number)
// The delimiter between username and domain name can be
// either "@" or "%40" (the URI-escaped equivalent.)
int delimiterIndex = number.indexOf('@");
if (delimiterIndex < 0) {
delimiterIndex = number.indexOf("%40");
}
if (delimiterIndex < 0) {
Rlog.w(LOG_TAG,
"getUsernameFromUriNumber: no delimiter found in SIP addr '" + number + "'");
delimiterIndex = number.length();
}
return number.substring(0, delimiterIndex);
|
private static int | indexOfLastNetworkChar(java.lang.String a)index of the last character of the network portion
(eg anything after is a post-dial string)
int pIndex, wIndex;
int origLength;
int trimIndex;
origLength = a.length();
pIndex = a.indexOf(PAUSE);
wIndex = a.indexOf(WAIT);
trimIndex = minPositive(pIndex, wIndex);
if (trimIndex < 0) {
return origLength - 1;
} else {
return trimIndex - 1;
}
|
private static void | internalCalledPartyBCDFragmentToString(java.lang.StringBuilder sb, byte[] bytes, int offset, int length)
for (int i = offset ; i < length + offset ; i++) {
byte b;
char c;
c = bcdToChar((byte)(bytes[i] & 0xf));
if (c == 0) {
return;
}
sb.append(c);
// FIXME(mkf) TS 23.040 9.1.2.3 says
// "if a mobile receives 1111 in a position prior to
// the last semi-octet then processing shall commence with
// the next semi-octet and the intervening
// semi-octet shall be ignored"
// How does this jive with 24.008 10.5.4.7
b = (byte)((bytes[i] >> 4) & 0xf);
if (b == 0xf && i + 1 == length + offset) {
//ignore final 0xf
break;
}
c = bcdToChar(b);
if (c == 0) {
return;
}
sb.append(c);
}
|
private static java.lang.String | internalGetStrippedReversed(java.lang.String np, int numDigits)Returns the last numDigits of the reversed phone number
Returns null if np == null
if (np == null) return null;
StringBuilder ret = new StringBuilder(numDigits);
int length = np.length();
for (int i = length - 1, s = length
; i >= 0 && (s - i) <= numDigits ; i--
) {
char c = np.charAt(i);
ret.append(c);
}
return ret.toString();
|
public static final boolean | is12Key(char c)True if c is ISO-LATIN characters 0-9, *, #
return (c >= '0" && c <= '9") || c == '*" || c == '#";
|
private static boolean | isCountryCallingCode(int countryCallingCodeCandidate)
return countryCallingCodeCandidate > 0 && countryCallingCodeCandidate < CCC_LENGTH &&
COUNTRY_CALLING_CALL[countryCallingCodeCandidate];
|
public static final boolean | isDialable(char c)True if c is ISO-LATIN characters 0-9, *, # , +, WILD
return (c >= '0" && c <= '9") || c == '*" || c == '#" || c == '+" || c == WILD;
|
private static boolean | isDialable(java.lang.String address)
for (int i = 0, count = address.length(); i < count; i++) {
if (!isDialable(address.charAt(i))) {
return false;
}
}
return true;
|
public static boolean | isEmergencyNumber(java.lang.String number)Checks a given number against the list of
emergency numbers provided by the RIL and SIM card.
return isEmergencyNumber(getDefaultVoiceSubId(), number);
|
public static boolean | isEmergencyNumber(int subId, java.lang.String number)Checks a given number against the list of
emergency numbers provided by the RIL and SIM card.
// Return true only if the specified number *exactly* matches
// one of the emergency numbers listed by the RIL / SIM.
return isEmergencyNumberInternal(subId, number, true /* useExactMatch */);
|
public static boolean | isEmergencyNumber(java.lang.String number, java.lang.String defaultCountryIso)Checks if a given number is an emergency number for a specific country.
return isEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso);
|
public static boolean | isEmergencyNumber(int subId, java.lang.String number, java.lang.String defaultCountryIso)Checks if a given number is an emergency number for a specific country.
return isEmergencyNumberInternal(subId, number,
defaultCountryIso,
true /* useExactMatch */);
|
private static boolean | isEmergencyNumberInternal(java.lang.String number, boolean useExactMatch)Helper function for isEmergencyNumber(String) and
isPotentialEmergencyNumber(String).
return isEmergencyNumberInternal(getDefaultVoiceSubId(), number, useExactMatch);
|
private static boolean | isEmergencyNumberInternal(int subId, java.lang.String number, boolean useExactMatch)Helper function for isEmergencyNumber(String) and
isPotentialEmergencyNumber(String).
return isEmergencyNumberInternal(subId, number, null, useExactMatch);
|
private static boolean | isEmergencyNumberInternal(java.lang.String number, java.lang.String defaultCountryIso, boolean useExactMatch)Helper function for isEmergencyNumber(String, String) and
isPotentialEmergencyNumber(String, String).
return isEmergencyNumberInternal(getDefaultVoiceSubId(), number, defaultCountryIso,
useExactMatch);
|
private static boolean | isEmergencyNumberInternal(int subId, java.lang.String number, java.lang.String defaultCountryIso, boolean useExactMatch)Helper function for isEmergencyNumber(String, String) and
isPotentialEmergencyNumber(String, String).
// If the number passed in is null, just return false:
if (number == null) return false;
// If the number passed in is a SIP address, return false, since the
// concept of "emergency numbers" is only meaningful for calls placed
// over the cell network.
// (Be sure to do this check *before* calling extractNetworkPortionAlt(),
// since the whole point of extractNetworkPortionAlt() is to filter out
// any non-dialable characters (which would turn 'abc911def@example.com'
// into '911', for example.))
if (isUriNumber(number)) {
return false;
}
// Strip the separators from the number before comparing it
// to the list.
number = extractNetworkPortionAlt(number);
Rlog.d(LOG_TAG, "subId:" + subId + ", defaultCountryIso:" +
((defaultCountryIso == null) ? "NULL" : defaultCountryIso));
String emergencyNumbers = "";
int slotId = SubscriptionManager.getSlotId(subId);
// retrieve the list of emergency numbers
// check read-write ecclist property first
String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
emergencyNumbers = SystemProperties.get(ecclist, "");
Rlog.d(LOG_TAG, "slotId:" + slotId + ", emergencyNumbers: " + emergencyNumbers);
if (TextUtils.isEmpty(emergencyNumbers)) {
// then read-only ecclist property since old RIL only uses this
emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
}
if (!TextUtils.isEmpty(emergencyNumbers)) {
// searches through the comma-separated list for a match,
// return true if one is found.
for (String emergencyNum : emergencyNumbers.split(",")) {
// It is not possible to append additional digits to an emergency number to dial
// the number in Brazil - it won't connect.
if (useExactMatch || "BR".equalsIgnoreCase(defaultCountryIso)) {
if (number.equals(emergencyNum)) {
return true;
}
} else {
if (number.startsWith(emergencyNum)) {
return true;
}
}
}
// no matches found against the list!
return false;
}
Rlog.d(LOG_TAG, "System property doesn't provide any emergency numbers."
+ " Use embedded logic for determining ones.");
// If slot id is invalid, means that there is no sim card.
// According spec 3GPP TS22.101, the following numbers should be
// ECC numbers when SIM/USIM is not present.
emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
for (String emergencyNum : emergencyNumbers.split(",")) {
if (useExactMatch) {
if (number.equals(emergencyNum)) {
return true;
}
} else {
if (number.startsWith(emergencyNum)) {
return true;
}
}
}
// No ecclist system property, so use our own list.
if (defaultCountryIso != null) {
ShortNumberUtil util = new ShortNumberUtil();
if (useExactMatch) {
return util.isEmergencyNumber(number, defaultCountryIso);
} else {
return util.connectsToEmergencyNumber(number, defaultCountryIso);
}
}
return false;
|
public static boolean | isGlobalPhoneNumber(java.lang.String phoneNumber)
if (TextUtils.isEmpty(phoneNumber)) {
return false;
}
Matcher match = GLOBAL_PHONE_NUMBER_PATTERN.matcher(phoneNumber);
return match.matches();
|
public static boolean | isISODigit(char c)True if c is ISO-LATIN characters 0-9
return c >= '0" && c <= '9";
|
public static boolean | isLocalEmergencyNumber(android.content.Context context, java.lang.String number)Checks if a given number is an emergency number for the country that the user is in.
return isLocalEmergencyNumber(context, getDefaultVoiceSubId(), number);
|
public static boolean | isLocalEmergencyNumber(android.content.Context context, int subId, java.lang.String number)Checks if a given number is an emergency number for the country that the user is in.
return isLocalEmergencyNumberInternal(subId, number,
context,
true /* useExactMatch */);
|
private static boolean | isLocalEmergencyNumberInternal(java.lang.String number, android.content.Context context, boolean useExactMatch)Helper function for isLocalEmergencyNumber() and
isPotentialLocalEmergencyNumber().
return isLocalEmergencyNumberInternal(getDefaultVoiceSubId(), number, context,
useExactMatch);
|
private static boolean | isLocalEmergencyNumberInternal(int subId, java.lang.String number, android.content.Context context, boolean useExactMatch)Helper function for isLocalEmergencyNumber() and
isPotentialLocalEmergencyNumber().
String countryIso;
CountryDetector detector = (CountryDetector) context.getSystemService(
Context.COUNTRY_DETECTOR);
if (detector != null && detector.detectCountry() != null) {
countryIso = detector.detectCountry().getCountryIso();
} else {
Locale locale = context.getResources().getConfiguration().locale;
countryIso = locale.getCountry();
Rlog.w(LOG_TAG, "No CountryDetector; falling back to countryIso based on locale: "
+ countryIso);
}
return isEmergencyNumberInternal(subId, number, countryIso, useExactMatch);
|
public static boolean | isNanp(java.lang.String dialStr)This function checks if the passed in string conforms to the NANP format
i.e. NXX-NXX-XXXX, N is any digit 2-9 and X is any digit 0-9
boolean retVal = false;
if (dialStr != null) {
if (dialStr.length() == NANP_LENGTH) {
if (isTwoToNine(dialStr.charAt(0)) &&
isTwoToNine(dialStr.charAt(3))) {
retVal = true;
for (int i=1; i<NANP_LENGTH; i++ ) {
char c=dialStr.charAt(i);
if (!PhoneNumberUtils.isISODigit(c)) {
retVal = false;
break;
}
}
}
}
} else {
Rlog.e("isNanp: null dialStr passed in", dialStr);
}
return retVal;
|
private static boolean | isNonSeparator(java.lang.String address)
for (int i = 0, count = address.length(); i < count; i++) {
if (!isNonSeparator(address.charAt(i))) {
return false;
}
}
return true;
|
public static final boolean | isNonSeparator(char c)True if c is ISO-LATIN characters 0-9, *, # , +, WILD, WAIT, PAUSE
return (c >= '0" && c <= '9") || c == '*" || c == '#" || c == '+"
|| c == WILD || c == WAIT || c == PAUSE;
|
private static boolean | isOneNanp(java.lang.String dialStr)This function checks if the passed in string conforms to 1-NANP format
boolean retVal = false;
if (dialStr != null) {
String newDialStr = dialStr.substring(1);
if ((dialStr.charAt(0) == '1") && isNanp(newDialStr)) {
retVal = true;
}
} else {
Rlog.e("isOneNanp: null dialStr passed in", dialStr);
}
return retVal;
|
private static boolean | isPause(char c)
return c == 'p"||c == 'P";
|
public static boolean | isPotentialEmergencyNumber(java.lang.String number)Checks if given number might *potentially* result in
a call to an emergency service on the current network.
Specifically, this method will return true if the specified number
is an emergency number according to the list managed by the RIL or
SIM, *or* if the specified number simply starts with the same
digits as any of the emergency numbers listed in the RIL / SIM.
This method is intended for internal use by the phone app when
deciding whether to allow ACTION_CALL intents from 3rd party apps
(where we're required to *not* allow emergency calls to be placed.)
return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number);
|
public static boolean | isPotentialEmergencyNumber(int subId, java.lang.String number)Checks if given number might *potentially* result in
a call to an emergency service on the current network.
Specifically, this method will return true if the specified number
is an emergency number according to the list managed by the RIL or
SIM, *or* if the specified number simply starts with the same
digits as any of the emergency numbers listed in the RIL / SIM.
This method is intended for internal use by the phone app when
deciding whether to allow ACTION_CALL intents from 3rd party apps
(where we're required to *not* allow emergency calls to be placed.)
// Check against the emergency numbers listed by the RIL / SIM,
// and *don't* require an exact match.
return isEmergencyNumberInternal(subId, number, false /* useExactMatch */);
|
public static boolean | isPotentialEmergencyNumber(java.lang.String number, java.lang.String defaultCountryIso)Checks if a given number might *potentially* result in a call to an
emergency service, for a specific country.
Specifically, this method will return true if the specified number
is an emergency number in the specified country, *or* if the number
simply starts with the same digits as any emergency number for that
country.
This method is intended for internal use by the phone app when
deciding whether to allow ACTION_CALL intents from 3rd party apps
(where we're required to *not* allow emergency calls to be placed.)
return isPotentialEmergencyNumber(getDefaultVoiceSubId(), number, defaultCountryIso);
|
public static boolean | isPotentialEmergencyNumber(int subId, java.lang.String number, java.lang.String defaultCountryIso)Checks if a given number might *potentially* result in a call to an
emergency service, for a specific country.
Specifically, this method will return true if the specified number
is an emergency number in the specified country, *or* if the number
simply starts with the same digits as any emergency number for that
country.
This method is intended for internal use by the phone app when
deciding whether to allow ACTION_CALL intents from 3rd party apps
(where we're required to *not* allow emergency calls to be placed.)
return isEmergencyNumberInternal(subId, number,
defaultCountryIso,
false /* useExactMatch */);
|
public static boolean | isPotentialLocalEmergencyNumber(android.content.Context context, java.lang.String number)Checks if a given number might *potentially* result in a call to an
emergency service, for the country that the user is in. The current
country is determined using the CountryDetector.
Specifically, this method will return true if the specified number
is an emergency number in the current country, *or* if the number
simply starts with the same digits as any emergency number for the
current country.
This method is intended for internal use by the phone app when
deciding whether to allow ACTION_CALL intents from 3rd party apps
(where we're required to *not* allow emergency calls to be placed.)
return isPotentialLocalEmergencyNumber(context, getDefaultVoiceSubId(), number);
|
public static boolean | isPotentialLocalEmergencyNumber(android.content.Context context, int subId, java.lang.String number)Checks if a given number might *potentially* result in a call to an
emergency service, for the country that the user is in. The current
country is determined using the CountryDetector.
Specifically, this method will return true if the specified number
is an emergency number in the current country, *or* if the number
simply starts with the same digits as any emergency number for the
current country.
This method is intended for internal use by the phone app when
deciding whether to allow ACTION_CALL intents from 3rd party apps
(where we're required to *not* allow emergency calls to be placed.)
return isLocalEmergencyNumberInternal(subId, number,
context,
false /* useExactMatch */);
|
public static final boolean | isReallyDialable(char c)True if c is ISO-LATIN characters 0-9, *, # , + (no WILD)
return (c >= '0" && c <= '9") || c == '*" || c == '#" || c == '+";
|
private static boolean | isSeparator(char ch)Returns true if ch is not dialable or alpha char
return !isDialable(ch) && !(('a" <= ch && ch <= 'z") || ('A" <= ch && ch <= 'Z"));
|
public static final boolean | isStartsPostDial(char c)This any anything to the right of this char is part of the
post-dial string (eg this is PAUSE or WAIT)
return c == PAUSE || c == WAIT;
|
private static boolean | isToneWait(char c)
return c == 'w"||c == 'W";
|
private static boolean | isTwoToNine(char c)
if (c >= '2" && c <= '9") {
return true;
} else {
return false;
}
|
public static boolean | isUriNumber(java.lang.String number)Determines if the specified number is actually a URI
(i.e. a SIP address) rather than a regular PSTN phone number,
based on whether or not the number contains an "@" character.
// Note we allow either "@" or "%40" to indicate a URI, in case
// the passed-in string is URI-escaped. (Neither "@" nor "%40"
// will ever be found in a legal PSTN number.)
return number != null && (number.contains("@") || number.contains("%40"));
|
public static boolean | isVoiceMailNumber(java.lang.String number)isVoiceMailNumber: checks a given number against the voicemail
number provided by the RIL and SIM card. The caller must have
the READ_PHONE_STATE credential.
return isVoiceMailNumber(SubscriptionManager.getDefaultSubId(), number);
|
public static boolean | isVoiceMailNumber(int subId, java.lang.String number)isVoiceMailNumber: checks a given number against the voicemail
number provided by the RIL and SIM card. The caller must have
the READ_PHONE_STATE credential.
String vmNumber;
try {
vmNumber = TelephonyManager.getDefault().getVoiceMailNumber(subId);
} catch (SecurityException ex) {
return false;
}
// Strip the separators from the number before comparing it
// to the list.
number = extractNetworkPortionAlt(number);
// compare tolerates null so we need to make sure that we
// don't return true when both are null.
return !TextUtils.isEmpty(number) && compare(number, vmNumber);
|
public static boolean | isWellFormedSmsAddress(java.lang.String address)Return true iff the network portion of address is,
as far as we can tell on the device, suitable for use as an SMS
destination address.
String networkPortion =
PhoneNumberUtils.extractNetworkPortion(address);
return (!(networkPortion.equals("+")
|| TextUtils.isEmpty(networkPortion)))
&& isDialable(networkPortion);
|
private static void | log(java.lang.String msg)
Rlog.d(LOG_TAG, msg);
|
private static boolean | matchIntlPrefix(java.lang.String a, int len)all of a up to len must be an international prefix or
separators/non-dialing digits
/* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
/* 0 1 2 3 45 */
int state = 0;
for (int i = 0 ; i < len ; i++) {
char c = a.charAt(i);
switch (state) {
case 0:
if (c == '+") state = 1;
else if (c == '0") state = 2;
else if (isNonSeparator(c)) return false;
break;
case 2:
if (c == '0") state = 3;
else if (c == '1") state = 4;
else if (isNonSeparator(c)) return false;
break;
case 4:
if (c == '1") state = 5;
else if (isNonSeparator(c)) return false;
break;
default:
if (isNonSeparator(c)) return false;
break;
}
}
return state == 1 || state == 3 || state == 5;
|
private static boolean | matchIntlPrefixAndCC(java.lang.String a, int len)all of 'a' up to len must be a (+|00|011)country code)
We're fast and loose with the country code. Any \d{1,3} matches
/* [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
/* 0 1 2 3 45 6 7 8 */
int state = 0;
for (int i = 0 ; i < len ; i++ ) {
char c = a.charAt(i);
switch (state) {
case 0:
if (c == '+") state = 1;
else if (c == '0") state = 2;
else if (isNonSeparator(c)) return false;
break;
case 2:
if (c == '0") state = 3;
else if (c == '1") state = 4;
else if (isNonSeparator(c)) return false;
break;
case 4:
if (c == '1") state = 5;
else if (isNonSeparator(c)) return false;
break;
case 1:
case 3:
case 5:
if (isISODigit(c)) state = 6;
else if (isNonSeparator(c)) return false;
break;
case 6:
case 7:
if (isISODigit(c)) state++;
else if (isNonSeparator(c)) return false;
break;
default:
if (isNonSeparator(c)) return false;
}
}
return state == 6 || state == 7 || state == 8;
|
private static boolean | matchTrunkPrefix(java.lang.String a, int len)all of 'a' up to len must match non-US trunk prefix ('0')
boolean found;
found = false;
for (int i = 0 ; i < len ; i++) {
char c = a.charAt(i);
if (c == '0" && !found) {
found = true;
} else if (isNonSeparator(c)) {
return false;
}
}
return found;
|
private static int | minPositive(int a, int b)or -1 if both are negative
if (a >= 0 && b >= 0) {
return (a < b) ? a : b;
} else if (a >= 0) { /* && b < 0 */
return a;
} else if (b >= 0) { /* && a < 0 */
return b;
} else { /* a < 0 && b < 0 */
return -1;
}
|
public static byte[] | networkPortionToCalledPartyBCD(java.lang.String s)Note: calls extractNetworkPortion(), so do not use for
SIM EF[ADN] style records
Returns null if network portion is empty.
String networkPortion = extractNetworkPortion(s);
return numberToCalledPartyBCDHelper(networkPortion, false);
|
public static byte[] | networkPortionToCalledPartyBCDWithLength(java.lang.String s)Same as {@link #networkPortionToCalledPartyBCD}, but includes a
one-byte length prefix.
String networkPortion = extractNetworkPortion(s);
return numberToCalledPartyBCDHelper(networkPortion, true);
|
public static java.lang.String | normalizeNumber(java.lang.String phoneNumber)Normalize a phone number by removing the characters other than digits. If
the given number has keypad letters, the letters will be converted to
digits first.
if (TextUtils.isEmpty(phoneNumber)) {
return "";
}
StringBuilder sb = new StringBuilder();
int len = phoneNumber.length();
for (int i = 0; i < len; i++) {
char c = phoneNumber.charAt(i);
// Character.digit() supports ASCII and Unicode digits (fullwidth, Arabic-Indic, etc.)
int digit = Character.digit(c, 10);
if (digit != -1) {
sb.append(digit);
} else if (sb.length() == 0 && c == '+") {
sb.append(c);
} else if ((c >= 'a" && c <= 'z") || (c >= 'A" && c <= 'Z")) {
return normalizeNumber(PhoneNumberUtils.convertKeypadLettersToDigits(phoneNumber));
}
}
return sb.toString();
|
public static byte[] | numberToCalledPartyBCD(java.lang.String number)Convert a dialing number to BCD byte array
return numberToCalledPartyBCDHelper(number, false);
|
private static byte[] | numberToCalledPartyBCDHelper(java.lang.String number, boolean includeLength)If includeLength is true, prepend a one-byte length value to
the return array.
int numberLenReal = number.length();
int numberLenEffective = numberLenReal;
boolean hasPlus = number.indexOf('+") != -1;
if (hasPlus) numberLenEffective--;
if (numberLenEffective == 0) return null;
int resultLen = (numberLenEffective + 1) / 2; // Encoded numbers require only 4 bits each.
int extraBytes = 1; // Prepended TOA byte.
if (includeLength) extraBytes++; // Optional prepended length byte.
resultLen += extraBytes;
byte[] result = new byte[resultLen];
int digitCount = 0;
for (int i = 0; i < numberLenReal; i++) {
char c = number.charAt(i);
if (c == '+") continue;
int shift = ((digitCount & 0x01) == 1) ? 4 : 0;
result[extraBytes + (digitCount >> 1)] |= (byte)((charToBCD(c) & 0x0F) << shift);
digitCount++;
}
// 1-fill any trailing odd nibble/quartet.
if ((digitCount & 0x01) == 1) result[extraBytes + (digitCount >> 1)] |= 0xF0;
int offset = 0;
if (includeLength) result[offset++] = (byte)(resultLen - 1);
result[offset] = (byte)(hasPlus ? TOA_International : TOA_Unknown);
return result;
|
private static java.lang.String | processPlusCode(java.lang.String networkDialStr, boolean useNanp)This function handles the plus code conversion
If the number format is
1)+1NANP,remove +,
2)other than +1NANP, any + numbers,replace + with the current IDP
String retStr = networkDialStr;
if (DBG) log("processPlusCode, networkDialStr = " + networkDialStr
+ "for NANP = " + useNanp);
// If there is a plus sign at the beginning of the dial string,
// Convert the plus sign to the default IDP since it's an international number
if (networkDialStr != null &&
networkDialStr.charAt(0) == PLUS_SIGN_CHAR &&
networkDialStr.length() > 1) {
String newStr = networkDialStr.substring(1);
// TODO: for nonNanp, should the '+' be removed if following number is country code
if (useNanp && isOneNanp(newStr)) {
// Remove the leading plus sign
retStr = newStr;
} else {
// Replaces the plus sign with the default IDP
retStr = networkDialStr.replaceFirst("[+]", getCurrentIdp(useNanp));
}
}
if (DBG) log("processPlusCode, retStr=" + retStr);
return retStr;
|
private static void | removeDashes(android.text.Editable text)Removes all dashes from the number.
int p = 0;
while (p < text.length()) {
if (text.charAt(p) == '-") {
text.delete(p, p + 1);
} else {
p++;
}
}
|
public static java.lang.String | replaceUnicodeDigits(java.lang.String number)Replaces all unicode(e.g. Arabic, Persian) digits with their decimal digit equivalents.
StringBuilder normalizedDigits = new StringBuilder(number.length());
for (char c : number.toCharArray()) {
int digit = Character.digit(c, 10);
if (digit != -1) {
normalizedDigits.append(digit);
} else {
normalizedDigits.append(c);
}
}
return normalizedDigits.toString();
|
private static java.lang.String | splitAtNonNumerics(java.lang.CharSequence number)
StringBuilder sb = new StringBuilder(number.length());
for (int i = 0; i < number.length(); i++) {
sb.append(PhoneNumberUtils.isISODigit(number.charAt(i))
? number.charAt(i)
: " ");
}
// It is very important to remove extra spaces. At time of writing, any leading or trailing
// spaces, or any sequence of more than one space, will confuse TalkBack and cause the TTS
// span to be non-functional!
return sb.toString().replaceAll(" +", " ").trim();
|
public static java.lang.String | stringFromStringAndTOA(java.lang.String s, int TOA)Basically: makes sure there's a + in front of a
TOA_International number
Returns null if s == null
if (s == null) return null;
if (TOA == TOA_International && s.length() > 0 && s.charAt(0) != '+") {
return "+" + s;
}
return s;
|
public static java.lang.String | stripSeparators(java.lang.String phoneNumber)Strips separators from a phone number string.
if (phoneNumber == null) {
return null;
}
int len = phoneNumber.length();
StringBuilder ret = new StringBuilder(len);
for (int i = 0; i < len; i++) {
char c = phoneNumber.charAt(i);
// Character.digit() supports ASCII and Unicode digits (fullwidth, Arabic-Indic, etc.)
int digit = Character.digit(c, 10);
if (digit != -1) {
ret.append(digit);
} else if (isNonSeparator(c)) {
ret.append(c);
}
}
return ret.toString();
|
public static java.lang.String | toCallerIDMinMatch(java.lang.String phoneNumber)Returns the rightmost MIN_MATCH (5) characters in the network portion
in *reversed* order
This can be used to do a database lookup against the column
that stores getStrippedReversed()
Returns null if phoneNumber == null
String np = extractNetworkPortionAlt(phoneNumber);
return internalGetStrippedReversed(np, MIN_MATCH);
|
public static int | toaFromString(java.lang.String s)Returns the TOA for the given dial string
Basically, returns TOA_International if there's a + prefix
if (s != null && s.length() > 0 && s.charAt(0) == '+") {
return TOA_International;
}
return TOA_Unknown;
|
private static android.telephony.PhoneNumberUtils$CountryCallingCodeAndNewIndex | tryGetCountryCallingCodeAndNewIndex(java.lang.String str, boolean acceptThailandCase)
// Rough regexp:
// ^[^0-9*#+]*((\+|0(0|11)\d\d?|166) [^0-9*#+] $
// 0 1 2 3 45 6 7 89
//
// In all the states, this function ignores separator characters.
// "166" is the special case for the call from Thailand to the US. Uguu!
int state = 0;
int ccc = 0;
final int length = str.length();
for (int i = 0 ; i < length ; i++ ) {
char ch = str.charAt(i);
switch (state) {
case 0:
if (ch == '+") state = 1;
else if (ch == '0") state = 2;
else if (ch == '1") {
if (acceptThailandCase) {
state = 8;
} else {
return null;
}
} else if (isDialable(ch)) {
return null;
}
break;
case 2:
if (ch == '0") state = 3;
else if (ch == '1") state = 4;
else if (isDialable(ch)) {
return null;
}
break;
case 4:
if (ch == '1") state = 5;
else if (isDialable(ch)) {
return null;
}
break;
case 1:
case 3:
case 5:
case 6:
case 7:
{
int ret = tryGetISODigit(ch);
if (ret > 0) {
ccc = ccc * 10 + ret;
if (ccc >= 100 || isCountryCallingCode(ccc)) {
return new CountryCallingCodeAndNewIndex(ccc, i + 1);
}
if (state == 1 || state == 3 || state == 5) {
state = 6;
} else {
state++;
}
} else if (isDialable(ch)) {
return null;
}
}
break;
case 8:
if (ch == '6") state = 9;
else if (isDialable(ch)) {
return null;
}
break;
case 9:
if (ch == '6") {
return new CountryCallingCodeAndNewIndex(66, i + 1);
} else {
return null;
}
default:
return null;
}
}
return null;
|
private static int | tryGetISODigit(char ch)Returns integer corresponding to the input if input "ch" is
ISO-LATIN characters 0-9.
Returns -1 otherwise
if ('0" <= ch && ch <= '9") {
return ch - '0";
} else {
return -1;
}
|
private static int | tryGetTrunkPrefixOmittedIndex(java.lang.String str, int currentIndex)Currently this function simply ignore the first digit assuming it is
trunk prefix. Actually trunk prefix is different in each country.
e.g.
"+79161234567" equals "89161234567" (Russian trunk digit is 8)
"+33123456789" equals "0123456789" (French trunk digit is 0)
int length = str.length();
for (int i = currentIndex ; i < length ; i++) {
final char ch = str.charAt(i);
if (tryGetISODigit(ch) >= 0) {
return i + 1;
} else if (isDialable(ch)) {
return -1;
}
}
return -1;
|
public static java.lang.CharSequence | ttsSpanAsPhoneNumber(java.lang.CharSequence phoneNumber)Wrap the supplied {@code CharSequence} with a {@code TtsSpan}, annotating it as
containing a phone number in its entirety.
if (phoneNumber == null) {
return null;
}
Spannable spannable = Spannable.Factory.getInstance().newSpannable(phoneNumber);
PhoneNumberUtils.ttsSpanAsPhoneNumber(spannable, 0, spannable.length());
return spannable;
|
public static void | ttsSpanAsPhoneNumber(android.text.Spannable s, int start, int end)Attach a {@link TtsSpan} to the supplied {@code Spannable} at the indicated location,
annotating that location as containing a phone number.
s.setSpan(
new TtsSpan.TelephoneBuilder()
.setNumberParts(splitAtNonNumerics(s.subSequence(start, end)))
.build(),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|