summaryrefslogtreecommitdiffstats
path: root/telephony/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'telephony/java/android')
-rw-r--r--telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java223
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java125
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java3
-rw-r--r--telephony/java/android/telephony/SmsManager.java23
-rw-r--r--telephony/java/android/telephony/SmsMessage.java1
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java21
6 files changed, 309 insertions, 87 deletions
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 8a47339..ffabb7b 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -16,83 +16,200 @@
package android.telephony;
+import com.google.i18n.phonenumbers.AsYouTypeFormatter;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+
+import android.telephony.PhoneNumberUtils;
import android.text.Editable;
import android.text.Selection;
import android.text.TextWatcher;
-import android.widget.TextView;
import java.util.Locale;
/**
- * Watches a {@link TextView} and if a phone number is entered will format it using
- * {@link PhoneNumberUtils#formatNumber(Editable, int)}. The formatting is based on
- * the current system locale when this object is created and future locale changes
- * may not take effect on this instance.
+ * Watches a {@link android.widget.TextView} and if a phone number is entered
+ * will format it.
+ * <p>
+ * Stop formatting when the user
+ * <ul>
+ * <li>Inputs non-dialable characters</li>
+ * <li>Removes the separator in the middle of string.</li>
+ * </ul>
+ * <p>
+ * The formatting will be restarted once the text is cleared.
*/
public class PhoneNumberFormattingTextWatcher implements TextWatcher {
+ /**
+ * One or more characters were removed from the end.
+ */
+ private final static int STATE_REMOVE_LAST = 0;
+
+ /**
+ * One or more characters were appended.
+ */
+ private final static int STATE_APPEND = 1;
+
+ /**
+ * One or more digits were changed in the beginning or the middle of text.
+ */
+ private final static int STATE_MODIFY_DIGITS = 2;
+
+ /**
+ * The changes other than the above.
+ */
+ private final static int STATE_OTHER = 3;
- static private int sFormatType;
- static private Locale sCachedLocale;
- private boolean mFormatting;
- private boolean mDeletingHyphen;
- private int mHyphenStart;
- private boolean mDeletingBackward;
+ /**
+ * The state of this change could be one value of the above
+ */
+ private int mState;
+ /**
+ * Indicates the change was caused by ourselves.
+ */
+ private boolean mSelfChange = false;
+
+ /**
+ * Indicates the formatting has been stopped.
+ */
+ private boolean mStopFormatting;
+
+ private AsYouTypeFormatter mFormatter;
+
+ /**
+ * The formatting is based on the current system locale and future locale changes
+ * may not take effect on this instance.
+ */
public PhoneNumberFormattingTextWatcher() {
- if (sCachedLocale == null || sCachedLocale != Locale.getDefault()) {
- sCachedLocale = Locale.getDefault();
- sFormatType = PhoneNumberUtils.getFormatTypeForLocale(sCachedLocale);
+ this(Locale.getDefault().getCountry());
+ }
+
+ /**
+ * The formatting is based on the given <code>countryCode</code>.
+ *
+ * @param countryCode the ISO 3166-1 two-letter country code that indicates the country/region
+ * where the phone number is being entered.
+ *
+ * @hide
+ */
+ public PhoneNumberFormattingTextWatcher(String countryCode) {
+ if (countryCode == null) throw new IllegalArgumentException();
+ mFormatter = PhoneNumberUtil.getInstance().getAsYouTypeFormatter(countryCode);
+ }
+
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+ if (mSelfChange || mStopFormatting) {
+ return;
+ }
+ if (count == 0 && s.length() == start) {
+ // Append one or more new chars
+ mState = STATE_APPEND;
+ } else if (after == 0 && start + count == s.length() && count > 0) {
+ // Remove one or more chars from the end of string.
+ mState = STATE_REMOVE_LAST;
+ } else if (count > 0 && !hasSeparator(s, start, count)) {
+ // Remove the dialable chars in the begin or middle of text.
+ mState = STATE_MODIFY_DIGITS;
+ } else {
+ mState = STATE_OTHER;
}
}
- public synchronized void afterTextChanged(Editable text) {
- // Make sure to ignore calls to afterTextChanged caused by the work done below
- if (!mFormatting) {
- mFormatting = true;
-
- // If deleting the hyphen, also delete the char before or after that
- if (mDeletingHyphen && mHyphenStart > 0) {
- if (mDeletingBackward) {
- if (mHyphenStart - 1 < text.length()) {
- text.delete(mHyphenStart - 1, mHyphenStart);
- }
- } else if (mHyphenStart < text.length()) {
- text.delete(mHyphenStart, mHyphenStart + 1);
- }
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (mSelfChange || mStopFormatting) {
+ return;
+ }
+ if (mState == STATE_OTHER) {
+ if (count > 0 && !hasSeparator(s, start, count)) {
+ // User inserted the dialable characters in the middle of text.
+ mState = STATE_MODIFY_DIGITS;
}
+ }
+ // Check whether we should stop formatting.
+ if (mState == STATE_APPEND && count > 0 && hasSeparator(s, start, count)) {
+ // User appended the non-dialable character, stop formatting.
+ stopFormatting();
+ } else if (mState == STATE_OTHER) {
+ // User must insert or remove the non-dialable characters in the begin or middle of
+ // number, stop formatting.
+ stopFormatting();
+ }
+ }
- PhoneNumberUtils.formatNumber(text, sFormatType);
-
- mFormatting = false;
+ public synchronized void afterTextChanged(Editable s) {
+ if (mStopFormatting) {
+ // Restart the formatting when all texts were clear.
+ mStopFormatting = !(s.length() == 0);
+ return;
+ }
+ if (mSelfChange) {
+ // Ignore the change caused by s.replace().
+ return;
+ }
+ String formatted = reformat(s, Selection.getSelectionEnd(s));
+ if (formatted != null) {
+ int rememberedPos = mFormatter.getRememberedPosition();
+ mSelfChange = true;
+ s.replace(0, s.length(), formatted, 0, formatted.length());
+ // The text could be changed by other TextWatcher after we changed it. If we found the
+ // text is not the one we were expecting, just give up calling setSelection().
+ if (formatted.equals(s.toString())) {
+ Selection.setSelection(s, rememberedPos);
+ }
+ mSelfChange = false;
}
}
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- // Check if the user is deleting a hyphen
- if (!mFormatting) {
- // Make sure user is deleting one char, without a selection
- final int selStart = Selection.getSelectionStart(s);
- final int selEnd = Selection.getSelectionEnd(s);
- if (s.length() > 1 // Can delete another character
- && count == 1 // Deleting only one character
- && after == 0 // Deleting
- && s.charAt(start) == '-' // a hyphen
- && selStart == selEnd) { // no selection
- mDeletingHyphen = true;
- mHyphenStart = start;
- // Check if the user is deleting forward or backward
- if (selStart == start + 1) {
- mDeletingBackward = true;
- } else {
- mDeletingBackward = false;
+ /**
+ * Generate the formatted number by ignoring all non-dialable chars and stick the cursor to the
+ * nearest dialable char to the left. For instance, if the number is (650) 123-45678 and '4' is
+ * removed then the cursor should be behind '3' instead of '-'.
+ */
+ private String reformat(CharSequence s, int cursor) {
+ // The index of char to the leftward of the cursor.
+ int curIndex = cursor - 1;
+ String formatted = null;
+ mFormatter.clear();
+ char lastNonSeparator = 0;
+ boolean hasCursor = false;
+ int len = s.length();
+ for (int i = 0; i < len; i++) {
+ char c = s.charAt(i);
+ if (PhoneNumberUtils.isNonSeparator(c)) {
+ if (lastNonSeparator != 0) {
+ formatted = getFormattedNumber(lastNonSeparator, hasCursor);
+ hasCursor = false;
}
- } else {
- mDeletingHyphen = false;
+ lastNonSeparator = c;
}
+ if (i == curIndex) {
+ hasCursor = true;
+ }
+ }
+ if (lastNonSeparator != 0) {
+ formatted = getFormattedNumber(lastNonSeparator, hasCursor);
}
+ return formatted;
}
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- // Does nothing
+ private String getFormattedNumber(char lastNonSeparator, boolean hasCursor) {
+ return hasCursor ? mFormatter.inputDigitAndRememberPosition(lastNonSeparator)
+ : mFormatter.inputDigit(lastNonSeparator);
+ }
+
+ private void stopFormatting() {
+ mStopFormatting = true;
+ mFormatter.clear();
+ }
+
+ private boolean hasSeparator(final CharSequence s, final int start, final int count) {
+ for (int i = start; i < start + count; i++) {
+ char c = s.charAt(i);
+ if (!PhoneNumberUtils.isNonSeparator(c)) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 7829006..b0fa0f5 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,6 +16,11 @@
package android.telephony;
+import com.google.i18n.phonenumbers.NumberParseException;
+import com.google.i18n.phonenumbers.PhoneNumberUtil;
+import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
+import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
+
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
@@ -617,7 +622,7 @@ public class PhoneNumberUtils
}
} else {
// In the US, 1-650-555-1234 must be equal to 650-555-1234,
- // while 090-1234-1234 must not be equalt to 90-1234-1234 in Japan.
+ // 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"
@@ -779,10 +784,10 @@ public class PhoneNumberUtils
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
+ // 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 is a
+ // http://web.telia.com/~u47904776/gsmkode.htm
// has a nice list of some of these GSM codes.
//
// Examples are:
@@ -870,10 +875,10 @@ public class PhoneNumberUtils
// 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 commense with
+ // 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
+ // How does this jive with 24.008 10.5.4.7
b = (byte)((bytes[i] >> 4) & 0xf);
@@ -1004,7 +1009,7 @@ public class PhoneNumberUtils
* Convert a dialing number to BCD byte array
*
* @param number dialing number string
- * if the dialing number starts with '+', set to internationl TOA
+ * if the dialing number starts with '+', set to international TOA
* @return BCD byte array
*/
public static byte[]
@@ -1108,10 +1113,10 @@ public class PhoneNumberUtils
*
* @param source the phone number to format
* @param defaultFormattingType The default formatting rules to apply if the number does
- * not begin with +<country_code>
+ * not begin with +[country_code]
* @return The phone number formatted with the given formatting type.
*
- * @hide TODO:Shuold be unhidden.
+ * @hide TODO: Should be unhidden.
*/
public static String formatNumber(String source, int defaultFormattingType) {
SpannableStringBuilder text = new SpannableStringBuilder(source);
@@ -1138,7 +1143,7 @@ public class PhoneNumberUtils
*
* @param text The number to be formatted, will be modified with the formatting
* @param defaultFormattingType The default formatting rules to apply if the number does
- * not begin with +<country_code>
+ * not begin with +[country_code]
*/
public static void formatNumber(Editable text, int defaultFormattingType) {
int formatType = defaultFormattingType;
@@ -1319,6 +1324,88 @@ public class PhoneNumberUtils
}
}
+ /**
+ * Format the given phoneNumber to the E.164 representation.
+ * <p>
+ * The given phone number must have an area code and could have a country
+ * code.
+ * <p>
+ * 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.
+ *
+ * @param phoneNumber
+ * the phone number to format
+ * @param defaultCountryIso
+ * the ISO 3166-1 two letters country code
+ * @return the E.164 representation, or null if the given phone number is
+ * not valid.
+ *
+ * @hide
+ */
+ public static String formatNumberToE164(String phoneNumber, String defaultCountryIso) {
+ 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;
+ }
+
+ /**
+ * Format a phone number.
+ * <p>
+ * If the given number doesn't have the country code, the phone will be
+ * formatted to the default country's convention.
+ *
+ * @param phoneNumber
+ * the number to be formatted.
+ * @param defaultCountryIso
+ * the ISO 3166-1 two letters country code whose convention will
+ * be used if the given number doesn't have the country code.
+ * @return the formatted number, or null if the given number is not valid.
+ *
+ * @hide
+ */
+ public static String formatNumber(String phoneNumber, String defaultCountryIso) {
+ PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+ String result = null;
+ try {
+ PhoneNumber pn = util.parse(phoneNumber, defaultCountryIso);
+ result = util.formatInOriginalFormat(pn, defaultCountryIso);
+ } catch (NumberParseException e) {
+ }
+ return result;
+ }
+
+ /**
+ * 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.
+ *
+ * @param phoneNumber
+ * the number to be normalized.
+ * @return the normalized number.
+ *
+ * @hide
+ */
+ public static String normalizeNumber(String phoneNumber) {
+ StringBuilder sb = new StringBuilder();
+ int len = phoneNumber.length();
+ for (int i = 0; i < len; i++) {
+ char c = phoneNumber.charAt(i);
+ if ((i == 0 && c == '+') || PhoneNumberUtils.isISODigit(c)) {
+ sb.append(c);
+ } else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ return normalizeNumber(PhoneNumberUtils.convertKeypadLettersToDigits(phoneNumber));
+ }
+ }
+ return sb.toString();
+ }
+
// Three and four digit phone numbers for either special services,
// or 3-6 digit addresses from the network (eg carrier-originated SMS messages) should
// not match.
@@ -1546,7 +1633,7 @@ public class PhoneNumberUtils
* @hide
*/
public static String
- cdmaCheckAndProcessPlusCodeByNumberFormat(String dialStr,int currFormat,int defaultFormt) {
+ cdmaCheckAndProcessPlusCodeByNumberFormat(String dialStr,int currFormat,int defaultFormat) {
String retStr = dialStr;
// Checks if the plus sign character is in the passed-in dial string
@@ -1554,7 +1641,7 @@ public class PhoneNumberUtils
dialStr.lastIndexOf(PLUS_SIGN_STRING) != -1) {
// Format the string based on the rules for the country the number is from,
// and the current country the phone is camped on.
- if ((currFormat == defaultFormt) && (currFormat == FORMAT_NANP)) {
+ if ((currFormat == defaultFormat) && (currFormat == FORMAT_NANP)) {
// Handle case where default and current telephone numbering plans are NANP.
String postDialStr = null;
String tempDialStr = dialStr;
@@ -1741,7 +1828,7 @@ public class PhoneNumberUtils
return -1;
}
- // This function appends the non-diablable P/W character to the original
+ // This function appends the non-dialable P/W character to the original
// dial string based on the dialable index passed in
private static String
appendPwCharBackToOrigDialStr(int dialableIndex,String origStr, String dialStr) {
@@ -1761,7 +1848,7 @@ public class PhoneNumberUtils
return retStr;
}
- //===== Begining of utility methods used in compareLoosely() =====
+ //===== Beginning of utility methods used in compareLoosely() =====
/**
* Phone numbers are stored in "lookup" form in the database
@@ -1883,12 +1970,12 @@ public class PhoneNumberUtils
//===== End of utility methods used only in compareLoosely() =====
- //===== Beggining of utility methods used only in compareStrictly() ====
+ //===== Beginning of utility methods used only in compareStrictly() ====
/*
* If true, the number is country calling code.
*/
- private static final boolean COUNTLY_CALLING_CALL[] = {
+ private static final boolean COUNTRY_CALLING_CALL[] = {
true, true, false, false, false, false, false, true, false, false,
false, false, false, false, false, false, false, false, false, false,
true, false, false, false, false, false, false, true, true, false,
@@ -1900,18 +1987,18 @@ public class PhoneNumberUtils
false, true, true, true, true, false, true, false, false, true,
true, true, true, true, true, true, false, false, true, false,
};
- private static final int CCC_LENGTH = COUNTLY_CALLING_CALL.length;
+ private static final int CCC_LENGTH = COUNTRY_CALLING_CALL.length;
/**
* @return true when input is valid Country Calling Code.
*/
private static boolean isCountryCallingCode(int countryCallingCodeCandidate) {
return countryCallingCodeCandidate > 0 && countryCallingCodeCandidate < CCC_LENGTH &&
- COUNTLY_CALLING_CALL[countryCallingCodeCandidate];
+ COUNTRY_CALLING_CALL[countryCallingCodeCandidate];
}
/**
- * Returns interger corresponding to the input if input "ch" is
+ * Returns integer corresponding to the input if input "ch" is
* ISO-LATIN characters 0-9.
* Returns -1 otherwise
*/
@@ -2046,7 +2133,7 @@ public class PhoneNumberUtils
/**
* Return true if the prefix of "str" is "ignorable". Here, "ignorable" means
- * that "str" has only one digit and separater characters. The one digit is
+ * that "str" has only one digit and separator characters. The one digit is
* assumed to be trunk prefix.
*/
private static boolean checkPrefixIsIgnorable(final String str,
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 830af47..38f44d8 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -25,6 +25,7 @@ import android.telephony.CellLocation;
import android.util.Log;
import com.android.internal.telephony.IPhoneStateListener;
+import com.android.internal.telephony.Phone;
/**
* A listener class for monitoring changes in specific telephony states
@@ -284,7 +285,7 @@ public class PhoneStateListener {
}
public void onDataConnectionStateChanged(int state, int networkType) {
- Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType, null).
+ Message.obtain(mHandler, LISTEN_DATA_CONNECTION_STATE, state, networkType).
sendToTarget();
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index f5e9751..953696b 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -21,7 +21,6 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.text.TextUtils;
-import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.ISms;
import com.android.internal.telephony.IccConstants;
import com.android.internal.telephony.SmsRawData;
@@ -33,7 +32,7 @@ import java.util.List;
/*
* TODO(code review): Curious question... Why are a lot of these
* methods not declared as static, since they do not seem to require
- * any local object state? Assumedly this cannot be changed without
+ * any local object state? Presumably this cannot be changed without
* interfering with the API...
*/
@@ -42,7 +41,8 @@ import java.util.List;
* Get this object by calling the static method SmsManager.getDefault().
*/
public final class SmsManager {
- private static SmsManager sInstance;
+ /** Singleton object constructed during class initialization. */
+ private static final SmsManager sInstance = new SmsManager();
/**
* Send a text based SMS.
@@ -52,8 +52,8 @@ public final class SmsManager {
* the current default SMSC
* @param text the body of the message to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * broadcast when the message is successfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK</code> for success,
* or one of these errors:<br>
* <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
* <code>RESULT_ERROR_RADIO_OFF</code><br>
@@ -116,7 +116,7 @@ public final class SmsManager {
* @param sentIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been sent.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * The result code will be <code>Activity.RESULT_OK</code> for success,
* or one of these errors:<br>
* <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
* <code>RESULT_ERROR_RADIO_OFF</code><br>
@@ -125,7 +125,7 @@ public final class SmsManager {
* the extra "errorCode" containing a radio technology specific value,
* generally only useful for troubleshooting.<br>
* The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
+ * is NULL the caller will be checked against all unknown applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
@@ -178,8 +178,8 @@ public final class SmsManager {
* @param destinationPort the port to deliver the message to
* @param data the body of the message to send
* @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is sucessfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * broadcast when the message is successfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK</code> for success,
* or one of these errors:<br>
* <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
* <code>RESULT_ERROR_RADIO_OFF</code><br>
@@ -188,7 +188,7 @@ public final class SmsManager {
* the extra "errorCode" containing a radio technology specific value,
* generally only useful for troubleshooting.<br>
* The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applicaitons,
+ * is NULL the caller will be checked against all unknown applications,
* which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
@@ -224,9 +224,6 @@ public final class SmsManager {
* @return the default instance of the SmsManager
*/
public static SmsManager getDefault() {
- if (sInstance == null) {
- sInstance = new SmsManager();
- }
return sInstance;
}
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index a284ea5..d899430 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -20,7 +20,6 @@ import android.os.Parcel;
import android.util.Log;
import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.EncodeException;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 27e08d4..2370add 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -912,4 +912,25 @@ public class TelephonyManager {
return null;
}
}
+
+ /**
+ * @return true if the current device is "voice capable".
+ * <p>
+ * "Voice capable" means that this device supports circuit-switched
+ * (i.e. voice) phone calls over the telephony network, and is allowed
+ * to display the in-call UI while a cellular voice call is active.
+ * This will be false on "data only" devices which can't make voice
+ * calls and don't support any in-call UI.
+ * <p>
+ * Note: the meaning of this flag is subtly different from the
+ * PackageManager.FEATURE_TELEPHONY system feature, which is available
+ * on any device with a telephony radio, even if the device is
+ * data-only.
+ *
+ * @hide pending API review
+ */
+ public boolean isVoiceCapable() {
+ return mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_voice_capable);
+ }
}