//得到软件版本 getDeviceSoftwareVersion() //得到设备的ID,IMEI或者MEID getDeviceId() //得到位置信息,主要是当前注册小区的位置码 getCellLocation() //得到附近小区信息 getNeighboringCellInfo() //得到当前Phone的类型,GSM/CDMA getCurrentPhoneType() //得到/proc/cmdline文件当前的内容 getProcCmdLine() //得到运营商名字 getNetworkOperatorName() //得到MCC+MNC getNetworkOperator() //得到是否漫游的状态 isNetworkRoaming() //得到网络状态,NETWORK_TYPE_GPRS、NETWORK_TYPE_EDGE、NETWORK_TYPE_CDMA等等 getNetworkType() //得到SIM卡状态 getSimState() //得到SIM卡MCC+MNC getSimOperator() //得到SIM卡SPN getSimOperatorName() //得到SIM卡串号 getSimSerialNumber() //得到MSISDN getMsisdn() //得到语音信箱号码 getVoiceMailNumber() //得到语音信箱短信条数 getVoiceMessageCount() //得到语音信箱名称 getVoiceMailAlphaTag() //得到数据连接状态:DATA_DISCONNECTED、DATA_CONNECTING、DATA_CONNECTED、DATA_SUSPENDED等 getDataState() //注册监听器监听Phone状态 listen() //得到所有Phone的信息 getAllCellInfo()从这些方法来看,TelephonyManager提供了与PhoneInterfaceManager类似的功能,但是又有本质的区别,其共同点是:都向其他模块提供了全面的操作Telephony相关事务的能力,其他模块可以在获取到这两个服务后,对Telephony进行各种操作。而区别在于:
下面我们通过代码来进一步论述上面的说明。
@ContactsProvider2.java boolean isPhone() { if (!mIsPhoneInitialized) { //创建TelephonyManager对象,并调用isVoiceCapable()方法 mIsPhone = new TelephonyManager(getContext()).isVoiceCapable(); mIsPhoneInitialized = true; } return mIsPhone; }或者通过TelephonyManager的getDefault()方法来获取TelephonyManager对象:
@TelephonyManager.java private static TelephonyManager sInstance = new TelephonyManager(); public static TelephonyManager getDefault() { return sInstance; }如果调用者不是系统应用的话,如何获取他的服务呢?
@ContextImpl.java registerService(TELEPHONY_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { return new TelephonyManager(ctx.getOuterContext()); }});经过这样的注册,其他进程就可以通过Context对象的getSystemService()方法来获取其服务,比如:
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);或者直接调用TelephonyManager的from()方法获取:
@TelephonyManager.java public static TelephonyManager from(Context context) { return (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); }
public class TelephonyManager {}看来TelephonyManager并没有继承任何的父类,那么他是如何实现各项功能的呢?
public TelephonyManager(Context context) { Context appContext = context.getApplicationContext(); if (appContext != null) { mContext = appContext; } else { mContext = context; } if (sRegistry == null) { //获取TelephonyRegistry的服务 sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry")); } }然后通过getSubscriberInfo()获取了PhoneSubInfoProxy的服务:
private IPhoneSubInfo getSubscriberInfo() { //获取的是PhoneSubInfoProxy的服务 return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo")); }以及通过getITelephony()获取了PhoneInterfaceManager的服务:
private ITelephony getITelephony() { return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); }TelephonyManager拿到这三个Service之后,就用三个Service提供的服务,以及SystemProperties提供的属性,搭建了自己的public方法集合。
@TelephonyManager.java public void listen(PhoneStateListener listener, int events) { String pkgForDebug = sContext != null ? sContext.getPackageName() : "<unknown>"; try { Boolean notifyNow = (getITelephony() != null); //通过TelephonyRegistry注册监听器 sRegistry.listen(pkgForDebug, listener.callback, events, notifyNow); } catch (RemoteException ex) { } catch (NullPointerException ex) { } }
//得到软件版本信息 public String getDeviceSoftwareVersion() { return getSubscriberInfo().getDeviceSvn(); } //得到设备ID public String getDeviceId() { return getSubscriberInfo().getDeviceId(); } //得到SIM卡串号 public String getSimSerialNumber() { return getSubscriberInfo().getIccSerialNumber(); } //得到语音信箱 public String getVoiceMailNumber() { return getSubscriberInfo().getVoiceMailNumber(); }
//得到位置信息 public CellLocation getCellLocation() { Bundle bundle = getITelephony().getCellLocation(); if (bundle.isEmpty()) return null; CellLocation cl = CellLocation.newFromBundle(bundle); return cl; } //得到附近小区信息 public List<NeighboringCellInfo> getNeighboringCellInfo() { return getITelephony().getNeighboringCellInfo(); } //得到当前Phone状态 public int getCurrentPhoneType() { ITelephony telephony = getITelephony(); if (telephony != null) { return telephony.getActivePhoneType(); } else { return getPhoneTypeFromProperty(); } } //判断是否有SIM卡插入 public boolean hasIccCard() { return getITelephony().hasIccCard(); }