@@ -1513,14 +1513,65 @@ public static String normalizeNumber(String phoneNumber) {
15131513 static final int MIN_MATCH = 7 ;
15141514
15151515 /**
1516- * isEmergencyNumber: checks a given number against the list of
1517- * emergency numbers provided by the RIL and SIM card.
1516+ * Checks a given number against the list of
1517+ * emergency numbers provided by the RIL and SIM card.
15181518 *
15191519 * @param number the number to look up.
1520- * @return if the number is in the list of emergency numbers
1521- * listed in the ril / sim, then return true, otherwise false.
1520+ * @return true if the number is in the list of emergency numbers
1521+ * listed in the RIL / SIM, otherwise return false.
15221522 */
15231523 public static boolean isEmergencyNumber (String number ) {
1524+ // Return true only if the specified number *exactly* matches
1525+ // one of the emergency numbers listed by the RIL / SIM.
1526+ return isEmergencyNumberInternal (number , true /* useExactMatch */ );
1527+ }
1528+
1529+ /**
1530+ * Checks if given number might *potentially* result in
1531+ * a call to an emergency service on the current network.
1532+ *
1533+ * Specifically, this method will return true if the specified number
1534+ * is an emergency number according to the list managed by the RIL or
1535+ * SIM, *or* if the specified number simply starts with the same
1536+ * digits as any of the emergency numbers listed in the RIL / SIM.
1537+ *
1538+ * This method is intended for internal use by the phone app when
1539+ * deciding whether to allow ACTION_CALL intents from 3rd party apps
1540+ * (where we're required to *not* allow emergency calls to be placed.)
1541+ *
1542+ * @param number the number to look up.
1543+ * @return true if the number is in the list of emergency numbers
1544+ * listed in the RIL / SIM, *or* if the number starts with the
1545+ * same digits as any of those emergency numbers.
1546+ *
1547+ * @hide
1548+ */
1549+ public static boolean isPotentialEmergencyNumber (String number ) {
1550+ // Check against the emergency numbers listed by the RIL / SIM,
1551+ // and *don't* require an exact match.
1552+ return isEmergencyNumberInternal (number , false /* useExactMatch */ );
1553+ }
1554+
1555+ /**
1556+ * Helper function for isEmergencyNumber(String) and
1557+ * isPotentialEmergencyNumber(String).
1558+ *
1559+ * @param number the number to look up.
1560+ *
1561+ * @param useExactMatch if true, consider a number to be an emergency
1562+ * number only if it *exactly* matches a number listed in
1563+ * the RIL / SIM. If false, a number is considered to be an
1564+ * emergency number if it simply starts with the same digits
1565+ * as any of the emergency numbers listed in the RIL / SIM.
1566+ * (Setting useExactMatch to false allows you to identify
1567+ * number that could *potentially* result in emergency calls
1568+ * since many networks will actually ignore trailing digits
1569+ * after a valid emergency number.)
1570+ *
1571+ * @return true if the number is in the list of emergency numbers
1572+ * listed in the RIL / sim, otherwise return false.
1573+ */
1574+ private static boolean isEmergencyNumberInternal (String number , boolean useExactMatch ) {
15241575 // If the number passed in is null, just return false:
15251576 if (number == null ) return false ;
15261577
@@ -1540,16 +1591,26 @@ public static boolean isEmergencyNumber(String number) {
15401591 // searches through the comma-separated list for a match,
15411592 // return true if one is found.
15421593 for (String emergencyNum : numbers .split ("," )) {
1543- if (number .startsWith (emergencyNum )) {
1544- return true ;
1594+ if (useExactMatch ) {
1595+ if (number .equals (emergencyNum )) {
1596+ return true ;
1597+ }
1598+ } else {
1599+ if (number .startsWith (emergencyNum )) {
1600+ return true ;
1601+ }
15451602 }
15461603 }
15471604 // no matches found against the list!
15481605 return false ;
15491606 }
15501607
1551- //no ecclist system property, so use our own list.
1552- return (number .startsWith ("112" ) || number .startsWith ("911" ));
1608+ // No ecclist system property, so use our own list.
1609+ if (useExactMatch ) {
1610+ return (number .equals ("112" ) || number .equals ("911" ));
1611+ } else {
1612+ return (number .startsWith ("112" ) || number .startsWith ("911" ));
1613+ }
15531614 }
15541615
15551616 /**
@@ -1559,31 +1620,81 @@ public static boolean isEmergencyNumber(String number) {
15591620 * @param defaultCountryIso the specific country which the number should be checked against
15601621 * @return if the number is an emergency number for the specific country, then return true,
15611622 * otherwise false
1623+ *
15621624 * @hide
15631625 */
15641626 public static boolean isEmergencyNumber (String number , String defaultCountryIso ) {
1565- PhoneNumberUtil util = PhoneNumberUtil .getInstance ();
1566- try {
1567- PhoneNumber pn = util .parse (number , defaultCountryIso );
1568- // libphonenumber guarantees short numbers such as emergency numbers are classified as
1569- // invalid. Therefore, if the number passes the validation test, we believe it is not an
1570- // emergency number.
1571- // TODO: Compare against a list of country-specific known emergency numbers instead, once
1572- // that has been collected.
1573- if (util .isValidNumber (pn )) {
1574- return false ;
1575- } else if ("BR" .equalsIgnoreCase (defaultCountryIso ) && number .length () >= 8 ) {
1576- // This is to prevent Brazilian local numbers which start with 911 being incorrectly
1577- // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
1578- // not possible to append additional digits to an emergency number to dial the number in
1579- // Brazil - it won't connect.
1580- // TODO: Clean this up once a list of country-specific known emergency numbers is
1581- // collected.
1582- return false ;
1583- }
1584- } catch (NumberParseException e ) {
1585- }
1586- return isEmergencyNumber (number );
1627+ return isEmergencyNumberInternal (number ,
1628+ defaultCountryIso ,
1629+ true /* useExactMatch */ );
1630+ }
1631+
1632+ /**
1633+ * Checks if a given number might *potentially* result in a call to an
1634+ * emergency service, for a specific country.
1635+ *
1636+ * Specifically, this method will return true if the specified number
1637+ * is an emergency number in the specified country, *or* if the number
1638+ * simply starts with the same digits as any emergency number for that
1639+ * country.
1640+ *
1641+ * This method is intended for internal use by the phone app when
1642+ * deciding whether to allow ACTION_CALL intents from 3rd party apps
1643+ * (where we're required to *not* allow emergency calls to be placed.)
1644+ *
1645+ * @param number the number to look up.
1646+ * @param defaultCountryIso the specific country which the number should be checked against
1647+ * @return true if the number is an emergency number for the specific
1648+ * country, *or* if the number starts with the same digits as
1649+ * any of those emergency numbers.
1650+ *
1651+ * @hide
1652+ */
1653+ public static boolean isPotentialEmergencyNumber (String number , String defaultCountryIso ) {
1654+ return isEmergencyNumberInternal (number ,
1655+ defaultCountryIso ,
1656+ false /* useExactMatch */ );
1657+ }
1658+
1659+ /**
1660+ * Helper function for isEmergencyNumber(String, String) and
1661+ * isPotentialEmergencyNumber(String, String).
1662+ *
1663+ * @param number the number to look up.
1664+ * @param defaultCountryIso the specific country which the number should be checked against
1665+ * @param useExactMatch if true, consider a number to be an emergency
1666+ * number only if it *exactly* matches a number listed in
1667+ * the RIL / SIM. If false, a number is considered to be an
1668+ * emergency number if it simply starts with the same digits
1669+ * as any of the emergency numbers listed in the RIL / SIM.
1670+ *
1671+ * @return true if the number is an emergency number for the specified country.
1672+ */
1673+ private static boolean isEmergencyNumberInternal (String number ,
1674+ String defaultCountryIso ,
1675+ boolean useExactMatch ) {
1676+ PhoneNumberUtil util = PhoneNumberUtil .getInstance ();
1677+ try {
1678+ PhoneNumber pn = util .parse (number , defaultCountryIso );
1679+ // libphonenumber guarantees short numbers such as emergency numbers are classified as
1680+ // invalid. Therefore, if the number passes the validation test, we believe it is not an
1681+ // emergency number.
1682+ // TODO: Compare against a list of country-specific known emergency numbers instead, once
1683+ // that has been collected.
1684+ if (util .isValidNumber (pn )) {
1685+ return false ;
1686+ } else if ("BR" .equalsIgnoreCase (defaultCountryIso ) && number .length () >= 8 ) {
1687+ // This is to prevent Brazilian local numbers which start with 911 being incorrectly
1688+ // classified as emergency numbers. 911 is not an emergency number in Brazil; it is also
1689+ // not possible to append additional digits to an emergency number to dial the number in
1690+ // Brazil - it won't connect.
1691+ // TODO: Clean this up once a list of country-specific known emergency numbers is
1692+ // collected.
1693+ return false ;
1694+ }
1695+ } catch (NumberParseException e ) {
1696+ }
1697+ return isEmergencyNumberInternal (number , useExactMatch );
15871698 }
15881699
15891700 /**
@@ -1592,12 +1703,66 @@ public static boolean isEmergencyNumber(String number, String defaultCountryIso)
15921703 *
15931704 * @param number the number to look up.
15941705 * @param context the specific context which the number should be checked against
1595- * @return if a phone number is an emergency number for a local country, based on the
1596- * CountryDetector.
1706+ * @return true if the specified number is an emergency number for a local country, based on the
1707+ * CountryDetector.
1708+ *
15971709 * @see android.location.CountryDetector
15981710 * @hide
15991711 */
16001712 public static boolean isLocalEmergencyNumber (String number , Context context ) {
1713+ return isLocalEmergencyNumberInternal (number ,
1714+ context ,
1715+ true /* useExactMatch */ );
1716+ }
1717+
1718+ /**
1719+ * Checks if a given number might *potentially* result in a call to an
1720+ * emergency service, for the country that the user is in. The current
1721+ * country is determined using the CountryDetector.
1722+ *
1723+ * Specifically, this method will return true if the specified number
1724+ * is an emergency number in the current country, *or* if the number
1725+ * simply starts with the same digits as any emergency number for the
1726+ * current country.
1727+ *
1728+ * This method is intended for internal use by the phone app when
1729+ * deciding whether to allow ACTION_CALL intents from 3rd party apps
1730+ * (where we're required to *not* allow emergency calls to be placed.)
1731+ *
1732+ * @param number the number to look up.
1733+ * @param context the specific context which the number should be checked against
1734+ * @return true if the specified number is an emergency number for a local country, based on the
1735+ * CountryDetector.
1736+ *
1737+ * @see android.location.CountryDetector
1738+ * @hide
1739+ */
1740+ public static boolean isPotentialLocalEmergencyNumber (String number , Context context ) {
1741+ return isLocalEmergencyNumberInternal (number ,
1742+ context ,
1743+ false /* useExactMatch */ );
1744+ }
1745+
1746+ /**
1747+ * Helper function for isLocalEmergencyNumber() and
1748+ * isPotentialLocalEmergencyNumber().
1749+ *
1750+ * @param number the number to look up.
1751+ * @param context the specific context which the number should be checked against
1752+ * @param useExactMatch if true, consider a number to be an emergency
1753+ * number only if it *exactly* matches a number listed in
1754+ * the RIL / SIM. If false, a number is considered to be an
1755+ * emergency number if it simply starts with the same digits
1756+ * as any of the emergency numbers listed in the RIL / SIM.
1757+ *
1758+ * @return true if the specified number is an emergency number for a
1759+ * local country, based on the CountryDetector.
1760+ *
1761+ * @see android.location.CountryDetector
1762+ */
1763+ private static boolean isLocalEmergencyNumberInternal (String number ,
1764+ Context context ,
1765+ boolean useExactMatch ) {
16011766 String countryIso ;
16021767 CountryDetector detector = (CountryDetector ) context .getSystemService (
16031768 Context .COUNTRY_DETECTOR );
@@ -1609,7 +1774,7 @@ public static boolean isLocalEmergencyNumber(String number, Context context) {
16091774 Log .w (LOG_TAG , "No CountryDetector; falling back to countryIso based on locale: "
16101775 + countryIso );
16111776 }
1612- return isEmergencyNumber (number , countryIso );
1777+ return isEmergencyNumberInternal (number , countryIso , useExactMatch );
16131778 }
16141779
16151780 /**
0 commit comments