在android里,第三方程序可以通过telephony对外的接口监听信号变化,电话状态变化等信息。最近在做项目的时候,把这个小串了下。
首先,先来看下telephony framework对外接口的组织架构。
其次,用个例子来解释下,第三方程序究竟是如何调用telephony api和监听telephony状态的。
packages/apps/Bluetooth/src/com/android/bluetooth/hfp/HeadsetPhoneState.java
class HeadsetPhoneState { // ... HeadsetPhoneState(Context context, HeadsetStateMachine stateMachine) { // Cannot instantiate TelephonyManager directly; Retrieve a reference to an instance through // Context.getSystemService(Context.TELEPHONY_SERVICE). Just like below. mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); } void listenForPhoneState(boolean start) { if (start) { if (!mListening) { // PhoneStateListener monitors changes in specific telephony states on the device. // For example, Service state, signal strength, message waiting indicator (voicemail), // and others. mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); mListening = true; } } else { if (mListening) { mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE); mListening = false; } } } //... // mPhoneStateListener overrides PhoneStateListener private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { @Override public void onServiceStateChanged(ServiceState serviceState) { mServiceState = serviceState; mService = (serviceState.getState() == ServiceState.STATE_IN_SERVICE) ? HeadsetHalConstants.NETWORK_STATE_AVAILABLE : HeadsetHalConstants.NETWORK_STATE_NOT_AVAILABLE; setRoam(serviceState.getRoaming() ? HeadsetHalConstants.SERVICE_TYPE_ROAMING : HeadsetHalConstants.SERVICE_TYPE_HOME); sendDeviceStateChanged(); } @Override public void onSignalStrengthsChanged(SignalStrength signalStrength) { int prevSignal = mSignal; if (signalStrength.isGsm()) { mSignal = gsmAsuToSignal(signalStrength); } else { mSignal = cdmaDbmEcioToSignal(signalStrength); } // network signal strength is scaled to BT 1-5 levels. // This results in a lot of duplicate messages, hence this check if (prevSignal != mSignal) sendDeviceStateChanged(); } //... }; //... }