在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();
}
//...
};
//...
}