TelephonyManager是android提供给应用层的接口,这个类可以提供和设置大量与通讯模块相关的信息,比如:SIM卡状态,SIM卡信息,网络制式,网络状态,信号强度,通话状态,小区信息等等,只要是涉及到通讯模块的信息,我们都可以先查看这个接口是否提供。
此外,TelephonyManager还提供了接口让应用层可以监听某些状态,比如:数据连接状态,信号强度,网络状态的变化。
//TelephonyManager是一个系统服务
TelephonyManager tm = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
//监听者,如果系统状态变更,会回调此监听者的函数
PhoneStateListener pl = new PhoneStateListener(){
@Override
public void onServiceStateChanged(ServiceState serviceState) {
super.onServiceStateChanged(serviceState);
Log.v(TAG, serviceState.toString());
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
Log.v(TAG, "state = "+state+" incomingNumber = "+incomingNumber);
}
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
super.onDataConnectionStateChanged(state, networkType);
Log.v(TAG, "state = " + state + " networkType = " + networkType);
}
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
Log.v(TAG, signalStrength.toString());
}
@Override
public void onCellInfoChanged(List cellInfo) {
super.onCellInfoChanged(cellInfo);
for(CellInfo Info: cellInfo) {
Log.v(TAG, Info.toString());
}
}
@Override
public void onDataActivity(int direction) {
super.onDataActivity(direction);
Log.v(TAG, "direction = " + direction);
}
@Override
public void onCallForwardingIndicatorChanged(boolean cfi) {
super.onCallForwardingIndicatorChanged(cfi);
Log.v(TAG, "cfi = " + cfi);
}
@Override
public void onMessageWaitingIndicatorChanged(boolean mwi) {
super.onMessageWaitingIndicatorChanged(mwi);
Log.v(TAG, "mwi = " + mwi);
}
};
//把监听者通过TelephonyManager注册到相应的被监听者中。listen()的第二个参数表示需要监听的具体状态
tm.listen(pl,PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
tm.listen(pl,PhoneStateListener.LISTEN_CALL_STATE);
tm.listen(pl,PhoneStateListener.LISTEN_CELL_INFO);
tm.listen(pl,PhoneStateListener.LISTEN_CELL_LOCATION);
tm.listen(pl,PhoneStateListener.LISTEN_DATA_ACTIVITY);
tm.listen(pl,PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
tm.listen(pl,PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
tm.listen(pl, PhoneStateListener.LISTEN_SERVICE_STATE);
tm.listen(pl,PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
TelephonyManager是一个系统服务,先来看看它注册为系统服务的过程:
frameworks\base\core\java\android\app\SystemServiceRegistry.java
//构建TelephonyManager对象,并把TelephonyManager注册为系统服务
registerService(Context.TELEPHONY_SERVICE, TelephonyManager.class,
new CachedServiceFetcher() {
@Override
public TelephonyManager createService(ContextImpl ctx) {
return new TelephonyManager(ctx.getOuterContext());
}});
//获取系统服务的接口
public static Object getSystemService(ContextImpl ctx, String name) {
ServiceFetcher> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
return fetcher != null ? fetcher.getService(ctx) : null;
}
/**
* Gets the name of the system-level service that is represented by the specified class.
*/
public static String getSystemServiceName(Class> serviceClass) {
return SYSTEM_SERVICE_NAMES.get(serviceClass);
}
/*注册为系统服务的接口,并把注册监听的对象保存到SYSTEM_SERVICE_NAMES和
*SYSTEM_SERVICE_FETCHERS中,它们都是HashMap集合。
*/
private static void registerService(String serviceName, Class serviceClass,
ServiceFetcher serviceFetcher) {
SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}
TelephonyManager 注册为系统服务后,我们可以通过context.getSystemService()来获取其对象。
TelephonyManager 源码:
public class TelephonyManager {
//其构造函数全部是@hide状态,不对应用层开放
/** @hide */
public TelephonyManager(Context context) {
this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
}
/** @hide */
public TelephonyManager(Context context, int subId) {
mSubId = subId;
Context appContext = context.getApplicationContext();
if (appContext != null) {
mContext = appContext;
} else {
mContext = context;
}
mSubscriptionManager = SubscriptionManager.from(mContext);
}
/** @hide */
private TelephonyManager() {
mContext = null;
mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
//@hide隐藏状态。应用层可以通过context.getSystemService()方式获取TelephonyManager 对象
/** {@hide} */
public static TelephonyManager from(Context context) {
return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
}
//注册监听者PhoneStateListener
public void listen(PhoneStateListener listener, int events) {
if (mContext == null) return;
try {
boolean notifyNow = (getITelephony() != null);
// If the listener has not explicitly set the subId (for example, created with the
// default constructor), replace the subId so it will listen to the account the
// telephony manager is created with.
if (listener.mSubId == null) {
listener.mSubId = mSubId;
}
ITelephonyRegistry registry = getTelephonyRegistry();
if (registry != null) {
registry.listenForSubscriber(listener.mSubId, getOpPackageName(),
listener.callback, events, notifyNow);
} else {
Rlog.w(TAG, "telephony registry not ready.");
}
} catch (RemoteException ex) {
// system process dead
}
}
TelephonyManager 是通过ITelephonyRegistry 来实现对通讯模块状态的监听,其监听的时序图如下:
总结以上时序图:
TelephonyRegistry的源码:
TelephonyRegistry中监听有很多状态的变化,以下源码只摘抄了其中的一个notifyServiceStateForPhoneId()函数和listen()函数:
class TelephonyRegistry extends ITelephonyRegistry.Stub {
......
//RIL层的网络状态变更后,会通知Phone层,Phone层再通知TelephonyRegistry
public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) {
//检查当前监听者是否拥有权限
if (!checkNotifyPermission("notifyServiceState()")){
return;
}
synchronized (mRecords) {
String str = "notifyServiceStateForSubscriber: subId=" + subId + " phoneId=" + phoneId
+ " state=" + state;
if (VDBG) {
log(str);
}
mLocalLog.log(str);
if (validatePhoneId(phoneId)) {
//保存网络状态
mServiceState[phoneId] = state;
//循环当前所有的监听者,通知网络状态的变化
for (Record r : mRecords) {
if (VDBG) {
log("notifyServiceStateForSubscriber: r=" + r + " subId=" + subId
+ " phoneId=" + phoneId + " state=" + state);
}
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SERVICE_STATE) &&
idMatch(r.subId, subId, phoneId)) {
try {
if (DBG) {
log("notifyServiceStateForSubscriber: callback.onSSC r=" + r
+ " subId=" + subId + " phoneId=" + phoneId
+ " state=" + state);
}
//回调监听者PhoneStateListener中的onServiceStateChanged()函数
r.callback.onServiceStateChanged(new ServiceState(state));
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
}
}
} else {
log("notifyServiceStateForSubscriber: INVALID phoneId=" + phoneId);
}
handleRemoveListLocked();
}
//部分状态的变更会发出广播
broadcastServiceStateChanged(state, phoneId, subId);
}
//把监听者PhoneStateListener注册到TelephonyRegistry中
private void listen(String callingPackage, IPhoneStateListener callback, int events,
boolean notifyNow, int subId) {
int callerUserId = UserHandle.getCallingUserId();
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
if (VDBG) {
log("listen: E pkg=" + callingPackage + " events=0x" + Integer.toHexString(events)
+ " notifyNow=" + notifyNow + " subId=" + subId + " myUserId="
+ UserHandle.myUserId() + " callerUserId=" + callerUserId);
}
if (events != PhoneStateListener.LISTEN_NONE) {
// Checks permission and throws SecurityException for disallowed operations. For pre-M
// apps whose runtime permission has been revoked, we return immediately to skip sending
// events to the app without crashing it.
//检查权限
if (!checkListenerPermission(events, subId, callingPackage, "listen")) {
return;
}
int phoneId = SubscriptionManager.getPhoneId(subId);
synchronized (mRecords) {
//把监听者PhoneStateListener的binder本地对象保存到Record集合中
// register
IBinder b = callback.asBinder();
Record r = add(b);
if (r == null) {
return;
}
r.context = mContext;
r.callback = callback;
r.callingPackage = callingPackage;
r.callerUid = Binder.getCallingUid();
r.callerPid = Binder.getCallingPid();
// Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
// force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
} else {//APP specify subID
r.subId = subId;
}
r.phoneId = phoneId;
r.events = events;
if (DBG) {
log("listen: Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
/*注册监听者的时候,是否立马更新。如果是,则回调PhoneStateListener中
*on...Changed(),报告状态的变更。如果不是,则等到phone层发出notify的时候再更新。
*/
if (notifyNow && validatePhoneId(phoneId)) {
if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
try {
if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]);
r.callback.onServiceStateChanged(
new ServiceState(mServiceState[phoneId]));
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) {
try {
int gsmSignalStrength = mSignalStrength[phoneId]
.getGsmSignalStrength();
r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
: gsmSignalStrength));
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) {
try {
r.callback.onMessageWaitingIndicatorChanged(
mMessageWaiting[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) {
try {
r.callback.onCallForwardingIndicatorChanged(
mCallForwarding[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
if (DBG_LOC) log("listen: mCellLocation = "
+ mCellLocation[phoneId]);
if (checkLocationAccess(r)) {
r.callback.onCellLocationChanged(
new Bundle(mCellLocation[phoneId]));
}
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_CALL_STATE) != 0) {
try {
r.callback.onCallStateChanged(mCallState[phoneId],
getCallIncomingNumber(r, phoneId));
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) {
try {
r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
mDataConnectionNetworkType[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) {
try {
r.callback.onDataActivity(mDataActivity[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
try {
r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_OTASP_CHANGED) != 0) {
try {
r.callback.onOtaspChanged(mOtaspMode);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
try {
if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
+ mCellInfo.get(phoneId));
if (checkLocationAccess(r)) {
r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
}
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) {
try {
r.callback.onPreciseCallStateChanged(mPreciseCallState);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
try {
r.callback.onPreciseDataConnectionStateChanged(
mPreciseDataConnectionState);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) {
try {
r.callback.onCarrierNetworkChange(mCarrierNetworkChangeState);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) {
try {
r.callback.onVoiceActivationStateChanged(mVoiceActivationState[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) !=0) {
try {
r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) {
try {
r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]);
} catch (RemoteException ex) {
remove(r.binder);
}
}
if ((events & PhoneStateListener.LISTEN_PHYSICAL_CHANNEL_CONFIGURATION) != 0) {
try {
r.callback.onPhysicalChannelConfigurationChanged(
mPhysicalChannelConfigs.get(phoneId));
} catch (RemoteException ex) {
remove(r.binder);
}
}
}
}
} else {
if(DBG) log("listen: Unregister");
remove(callback.asBinder());
}
}
}