| /* |
| * 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.content.BroadcastReceiver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.os.Bundle; |
| import android.os.RemoteException; |
| import android.os.SystemProperties; |
| import android.os.ServiceManager; |
| |
| import com.android.internal.telephony.*; |
| import android.telephony.CellLocation; |
| import android.telephony.ServiceState; |
| |
| import java.util.ArrayList; |
| |
| /** |
| * 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 acess 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 Context mContext; |
| private ITelephonyRegistry mRegistry; |
| |
| /** @hide */ |
| public TelephonyManager(Context context) { |
| mContext = context; |
| mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( |
| "telephony.registry")); |
| } |
| |
| /** @hide */ |
| private TelephonyManager() { |
| } |
| |
| private static TelephonyManager sInstance = new TelephonyManager(); |
| |
| /** @hide */ |
| public static TelephonyManager getDefault() { |
| return sInstance; |
| } |
| |
| // |
| // |
| // Device Info |
| // |
| // |
| |
| /** |
| * Returns the software version number for the device, for example, |
| * the IMEI/SV for GSM phones. |
| * |
| * <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; |
| } |
| |
| /** |
| * Returns the unique device ID, for example,the IMEI for GSM |
| * phones. |
| * |
| * <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; |
| } |
| |
| /** |
| * Returns the current location of the device. |
| * |
| * <p>Requires Permission: {@link android.Manifest.permission#ACCESS_COARSE_LOCATION |
| * ACCESS_COARSE_LOCATION}. |
| */ |
| public CellLocation getCellLocation() { |
| try { |
| Bundle bundle = getITelephony().getCellLocation(); |
| return CellLocation.newFromBundle(bundle); |
| } catch (RemoteException 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) { |
| } |
| } |
| |
| /** |
| * 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) { |
| } |
| } |
| |
| /** |
| * No phone module |
| */ |
| public static final int PHONE_TYPE_NONE = 0; |
| |
| /** |
| * GSM phone |
| */ |
| public static final int PHONE_TYPE_GSM = 1; |
| |
| /** |
| * Returns a constant indicating the device phone type. |
| * |
| * @see #PHONE_TYPE_NONE |
| * @see #PHONE_TYPE_GSM |
| */ |
| public int getPhoneType() { |
| // in the future, we should really check this |
| return PHONE_TYPE_GSM; |
| } |
| |
| // |
| // |
| // Current Network |
| // |
| // |
| |
| /** |
| * Returns the alphabetic name of current registered operator. |
| * <p> |
| * Availability: Only when user is registered to a 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 |
| */ |
| 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 equivilent of the current registered |
| * operator's MCC (Mobile Country Code). |
| * <p> |
| * Availability: Only when user is registered to a 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; |
| |
| /** |
| * Returns a constant indicating the radio technology (network type) |
| * currently in use on the device. |
| * |
| * @see #NETWORK_TYPE_UNKNOWN |
| * @see #NETWORK_TYPE_GPRS |
| * @see #NETWORK_TYPE_EDGE |
| * @see #NETWORK_TYPE_UMTS |
| */ |
| public int getNetworkType() { |
| String prop = SystemProperties.get(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE); |
| if ("GPRS".equals(prop)) { |
| return NETWORK_TYPE_GPRS; |
| } |
| else if ("EDGE".equals(prop)) { |
| return NETWORK_TYPE_EDGE; |
| } |
| else if ("UMTS".equals(prop)) { |
| return NETWORK_TYPE_UMTS; |
| } |
| else { |
| return NETWORK_TYPE_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; |
| |
| /** |
| * 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_SIM_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_SIM_OPERATOR_ALPHA); |
| } |
| |
| /** |
| * Returns the ISO country code equivalent for the SIM provider's country code. |
| */ |
| public String getSimCountryIso() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_SIM_OPERATOR_ISO_COUNTRY); |
| } |
| |
| /** |
| * Returns the serial number of the SIM, if applicable. |
| * <p> |
| * Requires Permission: |
| * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} |
| */ |
| public String getSimSerialNumber() { |
| try { |
| return getSubscriberInfo().getSimSerialNumber(); |
| } catch (RemoteException ex) { |
| } |
| return null; |
| } |
| |
| // |
| // |
| // Subscriber Info |
| // |
| // |
| |
| /** |
| * Returns the unique subscriber ID, for example, the IMSI for a GSM phone. |
| * <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; |
| } |
| |
| /** |
| * Returns the phone number string for line 1, for example, the MSISDN |
| * for a GSM phone. |
| * <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; |
| } |
| |
| /** |
| * Returns the alphabetic identifier associated with the line 1 number. |
| * <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; |
| } |
| |
| /** |
| * Returns the voice mail number. |
| * <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; |
| } |
| |
| /** |
| * 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; |
| } |
| |
| 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; |
| } |
| } |
| |
| /** 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; |
| |
| /** |
| * 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 |
| */ |
| public int getDataActivity() { |
| try { |
| return getITelephony().getDataActivity(); |
| } catch (RemoteException ex) { |
| // the phone process is restarting. |
| return DATA_ACTIVITY_NONE; |
| } |
| } |
| |
| /** 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; |
| } |
| } |
| |
| 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 = mContext != null ? mContext.getPackageName() : "<unknown>"; |
| try { |
| mRegistry.listen(pkgForDebug, listener.callback, events, true); |
| } catch (RemoteException ex) { |
| // system process dead |
| } |
| } |
| } |
| |
| /* |
| * These have not been implemented since they're not used anywhere in the system |
| * and it's impossible to tell if they're working or not. The comments in SystemProperties |
| * were wrong in at least one case, so I don't trust them. They claimed that |
| * PROPERTY_OPERATOR_ISROAMING was "1" if it was true, but it's actually set to "true." |
| */ |
| |
| |
| /* Set to '1' if voice mail is waiting, otherwise false */ |
| /* |
| public boolean isVoiceMailWaiting() { |
| return "1".equals( |
| SystemProperties.get(TelephonyProperties.PROPERTY_LINE1_VOICE_MAIL_WAITING)); |
| } |
| */ |
| |
| /* Set to 'true' if unconditional voice call forwarding is enabled |
| * Availablity: only if configured in SIM; SIM state must be "READY" |
| */ |
| /* |
| public boolean isCallForwarding() { |
| SystemProperties.get(TelephonyProperties.PROPERTY_LINE1_VOICE_CALL_FORWARDING); |
| } |
| */ |
| |
| /* '1' if the current network is the result of a manual network selection. |
| * Availability: when registered to a network |
| */ |
| /* |
| public boolean isNetworkManual() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISMANUAL); |
| } |
| */ |
| |
| |
| /* |
| * These have not been implemented because they're not public IMHO. -joeo |
| */ |
| |
| /* |
| * Baseband version |
| * Availability: property is available any time radio is on |
| */ |
| /* |
| public String getBasebandVersion() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION); |
| } |
| */ |
| |
| /* |
| * Radio Interface Layer (RIL) library implementation. |
| */ |
| /* |
| public String getRilLibrary() { |
| return SystemProperties.get(TelephonyProperties.PROPERTY_RIL_IMPL); |
| } |
| */ |
| |