| /* |
| * Copyright (C) 2008 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.telephony; |
| |
| import android.annotation.SdkConstant; |
| import android.annotation.SdkConstant.SdkConstantType; |
| import android.content.Context; |
| import android.os.Bundle; |
| import android.os.RemoteException; |
| import android.os.ServiceManager; |
| import android.os.SystemProperties; |
| import android.util.Log; |
| |
| import com.android.internal.telephony.IPhoneSubInfo; |
| import com.android.internal.telephony.ITelephony; |
| import com.android.internal.telephony.ITelephonyRegistry; |
| import com.android.internal.telephony.Phone; |
| import com.android.internal.telephony.PhoneFactory; |
| import com.android.internal.telephony.RILConstants; |
| import com.android.internal.telephony.TelephonyProperties; |
| |
| import java.util.List; |
| |
| /** |
| * Provides access to information about the telephony services on |
| * the device. Applications can use the methods in this class to |
| * determine telephony services and states, as well as to access some |
| * types of subscriber information. Applications can also register |
| * a listener to receive notification of telephony state changes. |
| * <p> |
| * You do not instantiate this class directly; instead, you retrieve |
| * a reference to an instance through |
| * {@link android.content.Context#getSystemService |
| * Context.getSystemService(Context.TELEPHONY_SERVICE)}. |
| * <p> |
| * Note that access to some telephony information is |
| * permission-protected. Your application cannot access the protected |
| * information unless it has the appropriate permissions declared in |
| * its manifest file. Where permissions apply, they are noted in the |
| * the methods through which you access the protected information. |
| */ |
| public class TelephonyManager { |
| private static final String TAG = "TelephonyManager"; |
| |
| private static Context sContext; |
| private static ITelephonyRegistry sRegistry; |
| |
| /** @hide */ |
| public TelephonyManager(Context context) { |
| if (sContext == null) { |
| sContext = context; |
| |
| sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( |
| "telephony.registry")); |
| } else { |
| Log.e(TAG, "Hidden constructor called more than once per process!"); |
| Log.e(TAG, "Original: " + sContext.getPackageName() + ", new: " + |
| context.getPackageName()); |
| } |
| } |
| |
| /** @hide */ |
| private TelephonyManager() { |
| } |
| |
| private static TelephonyManager sInstance = new TelephonyManager(); |
| |
| /** @hide |
| /* @deprecated - use getSystemService as described above */ |
| public static TelephonyManager getDefault() { |
| return sInstance; |
| } |
| |
| |
| // |
| // Broadcast Intent actions |
| // |
| |
| /** |
| * Broadcast intent action indicating that the call state (cellular) |
| * on the device has changed. |
| * |
| * <p> |
| * The {@link #EXTRA_STATE} extra indicates the new call state. |
| * If the new state is RINGING, a second extra |
| * {@link #EXTRA_INCOMING_NUMBER} provides the incoming phone number as |
| * a String. |
| * |
| * <p class="note"> |
| * Requires the READ_PHONE_STATE permission. |
| * |
| * <p class="note"> |
| * This was a {@link android.content.Context#sendStickyBroadcast sticky} |
| * broadcast in version 1.0, but it is no longer sticky. |
| * Instead, use {@link #getCallState} to synchronously query the current call state. |
| * |
| * @see #EXTRA_STATE |
| * @see #EXTRA_INCOMING_NUMBER |
| * @see #getCallState |
| */ |
| @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) |
| public static final String ACTION_PHONE_STATE_CHANGED = |
| "android.intent.action.PHONE_STATE"; |
| |
| /** |
| * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast |
| * for a String containing the new call state. |
| * |
| * @see #EXTRA_STATE_IDLE |
| * @see #EXTRA_STATE_RINGING |
| * @see #EXTRA_STATE_OFFHOOK |
| * |
| * <p class="note"> |
| * Retrieve with |
| * {@link android.content.Intent#getStringExtra(String)}. |
| */ |
| public static final String EXTRA_STATE = Phone.STATE_KEY; |
| |
| /** |
| * Value used with {@link #EXTRA_STATE} corresponding to |
| * {@link #CALL_STATE_IDLE}. |
| */ |
| public static final String EXTRA_STATE_IDLE = Phone.State.IDLE.toString(); |
| |
| /** |
| * Value used with {@link #EXTRA_STATE} corresponding to |
| * {@link #CALL_STATE_RINGING}. |
| */ |
| public static final String EXTRA_STATE_RINGING = Phone.State.RINGING.toString(); |
| |
| /** |
| * Value used with {@link #EXTRA_STATE} corresponding to |
| * {@link #CALL_STATE_OFFHOOK}. |
| */ |
| public static final String EXTRA_STATE_OFFHOOK = Phone.State.OFFHOOK.toString(); |
| |
| /** |
| * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast |
| * for a String containing the incoming phone number. |
| * Only valid when the new call state is RINGING. |
| * |
| * <p class="note"> |
| * Retrieve with |
| * {@link android.content.Intent#getStringExtra(String)}. |
| */ |
| public static final String EXTRA_INCOMING_NUMBER = "incoming_number"; |
| |
| |
| // |
| // |
| // Device Info |
| // |
| // |
| |
| /** |
| * Returns the software version number for the device, for example, |
| * the IMEI/SV for GSM phones. Return null if the software version is |
| * not available. |
| * |
| * <p>Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getDeviceSoftwareVersion() { |
| try { |
| return getSubscriberInfo().getDeviceSvn(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the unique device ID, for example, the IMEI for GSM and the MEID |
| * or ESN for CDMA phones. Return null if device ID is not available. |
| * |
| * <p>Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getDeviceId() { |
| try { |
| return getSubscriberInfo().getDeviceId(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the current location of the device. |
| * Return null if current location is not available. |
| * |
| * <p>Requires Permission: |
| * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or |
| * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION}. |
| */ |
| public CellLocation getCellLocation() { |
| try { |
| Bundle bundle = getITelephony().getCellLocation(); |
| CellLocation cl = CellLocation.newFromBundle(bundle); |
| if (cl.isEmpty()) |
| return null; |
| return cl; |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| return null; |
| } |
| } |
| |
| /** |
| * Enables location update notifications. {@link PhoneStateListener#onCellLocationChanged |
| * PhoneStateListener.onCellLocationChanged} will be called on location updates. |
| * |
| * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES |
| * CONTROL_LOCATION_UPDATES} |
| * |
| * @hide |
| */ |
| public void enableLocationUpdates() { |
| try { |
| getITelephony().enableLocationUpdates(); |
| } catch (RemoteException ex) { |
| } catch (NullPointerException ex) { |
| } |
| } |
| |
| /** |
| * Disables location update notifications. {@link PhoneStateListener#onCellLocationChanged |
| * PhoneStateListener.onCellLocationChanged} will be called on location updates. |
| * |
| * <p>Requires Permission: {@link android.Manifest.permission#CONTROL_LOCATION_UPDATES |
| * CONTROL_LOCATION_UPDATES} |
| * |
| * @hide |
| */ |
| public void disableLocationUpdates() { |
| try { |
| getITelephony().disableLocationUpdates(); |
| } catch (RemoteException ex) { |
| } catch (NullPointerException ex) { |
| } |
| } |
| |
| /** |
| * Returns the neighboring cell information of the device. |
| * |
| * @return List of NeighboringCellInfo or null if info unavailable. |
| * |
| * <p>Requires Permission: |
| * (@link android.Manifest.permission#ACCESS_COARSE_UPDATES} |
| */ |
| public List<NeighboringCellInfo> getNeighboringCellInfo() { |
| try { |
| return getITelephony().getNeighboringCellInfo(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| return null; |
| } |
| } |
| |
| /** No phone radio. */ |
| public static final int PHONE_TYPE_NONE = Phone.PHONE_TYPE_NONE; |
| /** Phone radio is GSM. */ |
| public static final int PHONE_TYPE_GSM = Phone.PHONE_TYPE_GSM; |
| /** Phone radio is CDMA. */ |
| public static final int PHONE_TYPE_CDMA = Phone.PHONE_TYPE_CDMA; |
| /** Phone is via SIP. */ |
| public static final int PHONE_TYPE_SIP = Phone.PHONE_TYPE_SIP; |
| |
| /** |
| * Returns the current phone type. |
| * TODO: This is a last minute change and hence hidden. |
| * |
| * @see #PHONE_TYPE_NONE |
| * @see #PHONE_TYPE_GSM |
| * @see #PHONE_TYPE_CDMA |
| * @see #PHONE_TYPE_SIP |
| * |
| * {@hide} |
| */ |
| public int getCurrentPhoneType() { |
| try{ |
| ITelephony telephony = getITelephony(); |
| if (telephony != null) { |
| return telephony.getActivePhoneType(); |
| } else { |
| // This can happen when the ITelephony interface is not up yet. |
| return getPhoneTypeFromProperty(); |
| } |
| } catch (RemoteException ex) { |
| // This shouldn't happen in the normal case, as a backup we |
| // read from the system property. |
| return getPhoneTypeFromProperty(); |
| } catch (NullPointerException ex) { |
| // This shouldn't happen in the normal case, as a backup we |
| // read from the system property. |
| return getPhoneTypeFromProperty(); |
| } |
| } |
| |
| /** |
| * Returns a constant indicating the device phone type. This |
| * indicates the type of radio used to transmit voice calls. |
| * |
| * @see #PHONE_TYPE_NONE |
| * @see #PHONE_TYPE_GSM |
| * @see #PHONE_TYPE_CDMA |
| * @see #PHONE_TYPE_SIP |
| */ |
| public int getPhoneType() { |
| if (!isVoiceCapable()) { |
| return PHONE_TYPE_NONE; |
| } |
| return getCurrentPhoneType(); |
| } |
| |
| private int getPhoneTypeFromProperty() { |
| int type = |
| SystemProperties.getInt(TelephonyProperties.CURRENT_ACTIVE_PHONE, |
| getPhoneTypeFromNetworkType()); |
| return type; |
| } |
| |
| private int getPhoneTypeFromNetworkType() { |
| // When the system property CURRENT_ACTIVE_PHONE, has not been set, |
| // use the system property for default network type. |
| // This is a fail safe, and can only happen at first boot. |
| int mode = SystemProperties.getInt("ro.telephony.default_network", -1); |
| if (mode == -1) |
| return PHONE_TYPE_NONE; |
| return PhoneFactory.getPhoneType(mode); |
| } |
| // |
| // |
| // Current Network |
| // |
| // |
| |
| /** |
| * Returns the alphabetic name of current registered operator. |
| * <p> |
| * Availability: Only when user is registered to a network. Result may be |
| * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if |
| * on a CDMA network). |
| */ |
| public String getNetworkOperatorName() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ALPHA); |
| } |
| |
| /** |
| * Returns the numeric name (MCC+MNC) of current registered operator. |
| * <p> |
| * Availability: Only when user is registered to a network. Result may be |
| * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if |
| * on a CDMA network). |
| */ |
| public String getNetworkOperator() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC); |
| } |
| |
| /** |
| * Returns true if the device is considered roaming on the current |
| * network, for GSM purposes. |
| * <p> |
| * Availability: Only when user registered to a network. |
| */ |
| public boolean isNetworkRoaming() { |
| return "true".equals(SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING)); |
| } |
| |
| /** |
| * Returns the ISO country code equivalent of the current registered |
| * operator's MCC (Mobile Country Code). |
| * <p> |
| * Availability: Only when user is registered to a network. Result may be |
| * unreliable on CDMA networks (use {@link #getPhoneType()} to determine if |
| * on a CDMA network). |
| */ |
| public String getNetworkCountryIso() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY); |
| } |
| |
| /** Network type is unknown */ |
| public static final int NETWORK_TYPE_UNKNOWN = 0; |
| /** Current network is GPRS */ |
| public static final int NETWORK_TYPE_GPRS = 1; |
| /** Current network is EDGE */ |
| public static final int NETWORK_TYPE_EDGE = 2; |
| /** Current network is UMTS */ |
| public static final int NETWORK_TYPE_UMTS = 3; |
| /** Current network is CDMA: Either IS95A or IS95B*/ |
| public static final int NETWORK_TYPE_CDMA = 4; |
| /** Current network is EVDO revision 0*/ |
| public static final int NETWORK_TYPE_EVDO_0 = 5; |
| /** Current network is EVDO revision A*/ |
| public static final int NETWORK_TYPE_EVDO_A = 6; |
| /** Current network is 1xRTT*/ |
| public static final int NETWORK_TYPE_1xRTT = 7; |
| /** Current network is HSDPA */ |
| public static final int NETWORK_TYPE_HSDPA = 8; |
| /** Current network is HSUPA */ |
| public static final int NETWORK_TYPE_HSUPA = 9; |
| /** Current network is HSPA */ |
| public static final int NETWORK_TYPE_HSPA = 10; |
| /** Current network is iDen */ |
| public static final int NETWORK_TYPE_IDEN = 11; |
| /** Current network is EVDO revision B*/ |
| public static final int NETWORK_TYPE_EVDO_B = 12; |
| /** Current network is LTE */ |
| public static final int NETWORK_TYPE_LTE = 13; |
| /** Current network is eHRPD */ |
| public static final int NETWORK_TYPE_EHRPD = 14; |
| /** Current network is HSPA+ |
| * @hide */ |
| public static final int NETWORK_TYPE_HSPAP = 15; |
| |
| /** |
| * Returns a constant indicating the radio technology (network type) |
| * currently in use on the device for data transmission. |
| * @return the network type |
| * |
| * @see #NETWORK_TYPE_UNKNOWN |
| * @see #NETWORK_TYPE_GPRS |
| * @see #NETWORK_TYPE_EDGE |
| * @see #NETWORK_TYPE_UMTS |
| * @see #NETWORK_TYPE_HSDPA |
| * @see #NETWORK_TYPE_HSUPA |
| * @see #NETWORK_TYPE_HSPA |
| * @see #NETWORK_TYPE_CDMA |
| * @see #NETWORK_TYPE_EVDO_0 |
| * @see #NETWORK_TYPE_EVDO_A |
| * @see #NETWORK_TYPE_EVDO_B |
| * @see #NETWORK_TYPE_1xRTT |
| * @see #NETWORK_TYPE_IDEN |
| * @see #NETWORK_TYPE_LTE |
| * @see #NETWORK_TYPE_EHRPD |
| */ |
| public int getNetworkType() { |
| try{ |
| ITelephony telephony = getITelephony(); |
| if (telephony != null) { |
| return telephony.getNetworkType(); |
| } else { |
| // This can happen when the ITelephony interface is not up yet. |
| return NETWORK_TYPE_UNKNOWN; |
| } |
| } catch(RemoteException ex) { |
| // This shouldn't happen in the normal case |
| return NETWORK_TYPE_UNKNOWN; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return NETWORK_TYPE_UNKNOWN; |
| } |
| } |
| |
| /** |
| * Returns a string representation of the radio technology (network type) |
| * currently in use on the device. |
| * @return the name of the radio technology |
| * |
| * @hide pending API council review |
| */ |
| public String getNetworkTypeName() { |
| switch (getNetworkType()) { |
| case NETWORK_TYPE_GPRS: |
| return "GPRS"; |
| case NETWORK_TYPE_EDGE: |
| return "EDGE"; |
| case NETWORK_TYPE_UMTS: |
| return "UMTS"; |
| case NETWORK_TYPE_HSDPA: |
| return "HSDPA"; |
| case NETWORK_TYPE_HSUPA: |
| return "HSUPA"; |
| case NETWORK_TYPE_HSPA: |
| return "HSPA"; |
| case NETWORK_TYPE_CDMA: |
| return "CDMA"; |
| case NETWORK_TYPE_EVDO_0: |
| return "CDMA - EvDo rev. 0"; |
| case NETWORK_TYPE_EVDO_A: |
| return "CDMA - EvDo rev. A"; |
| case NETWORK_TYPE_EVDO_B: |
| return "CDMA - EvDo rev. B"; |
| case NETWORK_TYPE_1xRTT: |
| return "CDMA - 1xRTT"; |
| case NETWORK_TYPE_LTE: |
| return "LTE"; |
| case NETWORK_TYPE_EHRPD: |
| return "CDMA - eHRPD"; |
| case NETWORK_TYPE_IDEN: |
| return "iDEN"; |
| default: |
| return "UNKNOWN"; |
| } |
| } |
| |
| // |
| // |
| // SIM Card |
| // |
| // |
| |
| /** SIM card state: Unknown. Signifies that the SIM is in transition |
| * between states. For example, when the user inputs the SIM pin |
| * under PIN_REQUIRED state, a query for sim status returns |
| * this state before turning to SIM_STATE_READY. */ |
| public static final int SIM_STATE_UNKNOWN = 0; |
| /** SIM card state: no SIM card is available in the device */ |
| public static final int SIM_STATE_ABSENT = 1; |
| /** SIM card state: Locked: requires the user's SIM PIN to unlock */ |
| public static final int SIM_STATE_PIN_REQUIRED = 2; |
| /** SIM card state: Locked: requires the user's SIM PUK to unlock */ |
| public static final int SIM_STATE_PUK_REQUIRED = 3; |
| /** SIM card state: Locked: requries a network PIN to unlock */ |
| public static final int SIM_STATE_NETWORK_LOCKED = 4; |
| /** SIM card state: Ready */ |
| public static final int SIM_STATE_READY = 5; |
| |
| /** |
| * @return true if a ICC card is present |
| */ |
| public boolean hasIccCard() { |
| try { |
| return getITelephony().hasIccCard(); |
| } catch (RemoteException ex) { |
| // Assume no ICC card if remote exception which shouldn't happen |
| return false; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return false; |
| } |
| } |
| |
| /** |
| * Returns a constant indicating the state of the |
| * device SIM card. |
| * |
| * @see #SIM_STATE_UNKNOWN |
| * @see #SIM_STATE_ABSENT |
| * @see #SIM_STATE_PIN_REQUIRED |
| * @see #SIM_STATE_PUK_REQUIRED |
| * @see #SIM_STATE_NETWORK_LOCKED |
| * @see #SIM_STATE_READY |
| */ |
| public int getSimState() { |
| String prop = SystemProperties.get(TelephonyProperties.PROPERTY_SIM_STATE); |
| if ("ABSENT".equals(prop)) { |
| return SIM_STATE_ABSENT; |
| } |
| else if ("PIN_REQUIRED".equals(prop)) { |
| return SIM_STATE_PIN_REQUIRED; |
| } |
| else if ("PUK_REQUIRED".equals(prop)) { |
| return SIM_STATE_PUK_REQUIRED; |
| } |
| else if ("NETWORK_LOCKED".equals(prop)) { |
| return SIM_STATE_NETWORK_LOCKED; |
| } |
| else if ("READY".equals(prop)) { |
| return SIM_STATE_READY; |
| } |
| else { |
| return SIM_STATE_UNKNOWN; |
| } |
| } |
| |
| /** |
| * Returns the MCC+MNC (mobile country code + mobile network code) of the |
| * provider of the SIM. 5 or 6 decimal digits. |
| * <p> |
| * Availability: SIM state must be {@link #SIM_STATE_READY} |
| * |
| * @see #getSimState |
| */ |
| public String getSimOperator() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC); |
| } |
| |
| /** |
| * Returns the Service Provider Name (SPN). |
| * <p> |
| * Availability: SIM state must be {@link #SIM_STATE_READY} |
| * |
| * @see #getSimState |
| */ |
| public String getSimOperatorName() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA); |
| } |
| |
| /** |
| * Returns the ISO country code equivalent for the SIM provider's country code. |
| */ |
| public String getSimCountryIso() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY); |
| } |
| |
| /** |
| * Returns the serial number of the SIM, if applicable. Return null if it is |
| * unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getSimSerialNumber() { |
| try { |
| return getSubscriberInfo().getIccSerialNumber(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| // |
| // |
| // Subscriber Info |
| // |
| // |
| |
| /** |
| * Returns the unique subscriber ID, for example, the IMSI for a GSM phone. |
| * Return null if it is unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getSubscriberId() { |
| try { |
| return getSubscriberInfo().getSubscriberId(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the phone number string for line 1, for example, the MSISDN |
| * for a GSM phone. Return null if it is unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getLine1Number() { |
| try { |
| return getSubscriberInfo().getLine1Number(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the alphabetic identifier associated with the line 1 number. |
| * Return null if it is unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| * @hide |
| * nobody seems to call this. |
| */ |
| public String getLine1AlphaTag() { |
| try { |
| return getSubscriberInfo().getLine1AlphaTag(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the voice mail number. Return null if it is unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getVoiceMailNumber() { |
| try { |
| return getSubscriberInfo().getVoiceMailNumber(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the complete voice mail number. Return null if it is unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#CALL_PRIVILEGED CALL_PRIVILEGED} |
| * |
| * @hide |
| */ |
| public String getCompleteVoiceMailNumber() { |
| try { |
| return getSubscriberInfo().getCompleteVoiceMailNumber(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| /** |
| * Returns the voice mail count. Return 0 if unavailable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| * @hide |
| */ |
| public int getVoiceMessageCount() { |
| try { |
| return getITelephony().getVoiceMessageCount(); |
| } catch (RemoteException ex) { |
| return 0; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return 0; |
| } |
| } |
| |
| /** |
| * Retrieves the alphabetic identifier associated with the voice |
| * mail number. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getVoiceMailAlphaTag() { |
| try { |
| return getSubscriberInfo().getVoiceMailAlphaTag(); |
| } catch (RemoteException ex) { |
| return null; |
| } catch (NullPointerException ex) { |
| // This could happen before phone restarts due to crashing |
| return null; |
| } |
| } |
| |
| private IPhoneSubInfo getSubscriberInfo() { |
| // get it each time because that process crashes a lot |
| return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo")); |
| } |
| |
| |
| /** Device call state: No activity. */ |
| public static final int CALL_STATE_IDLE = 0; |
| /** Device call state: Ringing. A new call arrived and is |
| * ringing or waiting. In the latter case, another call is |
| * already active. */ |
| public static final int CALL_STATE_RINGING = 1; |
| /** Device call state: Off-hook. At least one call exists |
| * that is dialing, active, or on hold, and no calls are ringing |
| * or waiting. */ |
| public static final int CALL_STATE_OFFHOOK = 2; |
| |
| /** |
| * Returns a constant indicating the call state (cellular) on the device. |
| */ |
| public int getCallState() { |
| try { |
| return getITelephony().getCallState(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return CALL_STATE_IDLE; |
| } catch (NullPointerException ex) { |
| // the phone process is restarting. |
| return CALL_STATE_IDLE; |
| } |
| } |
| |
| /** Data connection activity: No traffic. */ |
| public static final int DATA_ACTIVITY_NONE = 0x00000000; |
| /** Data connection activity: Currently receiving IP PPP traffic. */ |
| public static final int DATA_ACTIVITY_IN = 0x00000001; |
| /** Data connection activity: Currently sending IP PPP traffic. */ |
| public static final int DATA_ACTIVITY_OUT = 0x00000002; |
| /** Data connection activity: Currently both sending and receiving |
| * IP PPP traffic. */ |
| public static final int DATA_ACTIVITY_INOUT = DATA_ACTIVITY_IN | DATA_ACTIVITY_OUT; |
| /** |
| * Data connection is active, but physical link is down |
| */ |
| public static final int DATA_ACTIVITY_DORMANT = 0x00000004; |
| |
| /** |
| * Returns a constant indicating the type of activity on a data connection |
| * (cellular). |
| * |
| * @see #DATA_ACTIVITY_NONE |
| * @see #DATA_ACTIVITY_IN |
| * @see #DATA_ACTIVITY_OUT |
| * @see #DATA_ACTIVITY_INOUT |
| * @see #DATA_ACTIVITY_DORMANT |
| */ |
| public int getDataActivity() { |
| try { |
| return getITelephony().getDataActivity(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return DATA_ACTIVITY_NONE; |
| } catch (NullPointerException ex) { |
| // the phone process is restarting. |
| return DATA_ACTIVITY_NONE; |
| } |
| } |
| |
| /** Data connection state: Unknown. Used before we know the state. |
| * @hide |
| */ |
| public static final int DATA_UNKNOWN = -1; |
| /** Data connection state: Disconnected. IP traffic not available. */ |
| public static final int DATA_DISCONNECTED = 0; |
| /** Data connection state: Currently setting up a data connection. */ |
| public static final int DATA_CONNECTING = 1; |
| /** Data connection state: Connected. IP traffic should be available. */ |
| public static final int DATA_CONNECTED = 2; |
| /** Data connection state: Suspended. The connection is up, but IP |
| * traffic is temporarily unavailable. For example, in a 2G network, |
| * data activity may be suspended when a voice call arrives. */ |
| public static final int DATA_SUSPENDED = 3; |
| |
| /** |
| * Returns a constant indicating the current data connection state |
| * (cellular). |
| * |
| * @see #DATA_DISCONNECTED |
| * @see #DATA_CONNECTING |
| * @see #DATA_CONNECTED |
| * @see #DATA_SUSPENDED |
| */ |
| public int getDataState() { |
| try { |
| return getITelephony().getDataState(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return DATA_DISCONNECTED; |
| } catch (NullPointerException ex) { |
| return DATA_DISCONNECTED; |
| } |
| } |
| |
| private ITelephony getITelephony() { |
| return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); |
| } |
| |
| // |
| // |
| // PhoneStateListener |
| // |
| // |
| |
| /** |
| * Registers a listener object to receive notification of changes |
| * in specified telephony states. |
| * <p> |
| * To register a listener, pass a {@link PhoneStateListener} |
| * and specify at least one telephony state of interest in |
| * the events argument. |
| * |
| * At registration, and when a specified telephony state |
| * changes, the telephony manager invokes the appropriate |
| * callback method on the listener object and passes the |
| * current (udpated) values. |
| * <p> |
| * To unregister a listener, pass the listener object and set the |
| * events argument to |
| * {@link PhoneStateListener#LISTEN_NONE LISTEN_NONE} (0). |
| * |
| * @param listener The {@link PhoneStateListener} object to register |
| * (or unregister) |
| * @param events The telephony state(s) of interest to the listener, |
| * as a bitwise-OR combination of {@link PhoneStateListener} |
| * LISTEN_ flags. |
| */ |
| public void listen(PhoneStateListener listener, int events) { |
| String pkgForDebug = sContext != null ? sContext.getPackageName() : "<unknown>"; |
| try { |
| Boolean notifyNow = (getITelephony() != null); |
| sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow); |
| } catch (RemoteException ex) { |
| // system process dead |
| } catch (NullPointerException ex) { |
| // system process dead |
| } |
| } |
| |
| /** |
| * Returns the CDMA ERI icon index to display |
| * |
| * @hide |
| */ |
| public int getCdmaEriIconIndex() { |
| try { |
| return getITelephony().getCdmaEriIconIndex(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return -1; |
| } catch (NullPointerException ex) { |
| return -1; |
| } |
| } |
| |
| /** |
| * Returns the CDMA ERI icon mode, |
| * 0 - ON |
| * 1 - FLASHING |
| * |
| * @hide |
| */ |
| public int getCdmaEriIconMode() { |
| try { |
| return getITelephony().getCdmaEriIconMode(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return -1; |
| } catch (NullPointerException ex) { |
| return -1; |
| } |
| } |
| |
| /** |
| * Returns the CDMA ERI text, |
| * |
| * @hide |
| */ |
| public String getCdmaEriText() { |
| try { |
| return getITelephony().getCdmaEriText(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return null; |
| } catch (NullPointerException ex) { |
| 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() { |
| if (sContext == null) return true; |
| return sContext.getResources().getBoolean( |
| com.android.internal.R.bool.config_voice_capable); |
| } |
| |
| /** |
| * @return true if the current device supports sms service. |
| * <p> |
| * If true, this means that the device supports both sending and |
| * receiving sms via the telephony network. |
| * <p> |
| * Note: Voicemail waiting sms, cell broadcasting sms, and MMS are |
| * disabled when device doesn't support sms. |
| * |
| * @hide pending API review |
| */ |
| public boolean isSmsCapable() { |
| if (sContext == null) return true; |
| return sContext.getResources().getBoolean( |
| com.android.internal.R.bool.config_sms_capable); |
| } |
| } |