下面来看看class ContextImplextends Context类
@Override
public Object getSystemService(String name) {
if (WINDOW_SERVICE.equals(name)) {
returnWindowManagerImpl.getDefault();
} else if (ACTIVITY_SERVICE.equals(name)) {
returngetActivityManager();
}else if (TELEPHONY_SERVICE.equals(name)) {
return getTelephonyManager();
…..以下略
private TelephonyManager getTelephonyManager() {
synchronized (mSync) {
if (mTelephonyManager == null) {
mTelephonyManager = new TelephonyManager(getOuterContext());
}
}
return mTelephonyManager;
}
以下是TelephonyManager类的构造方法
/** @hide */
public TelephonyManager(Context context) {
mContext = context;
mRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
"telephony.registry"));
}
privateIPhoneSubInfo getSubscriberInfo() {
// get it each time because that process crashes a lot
returnIPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
}
private ITelephony getITelephony() {
return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
}
public void listen(PhoneStateListener listener, int events) {
String pkgForDebug = mContext != null ? mContext.getPackageName() : "<unknown>";
try {
Boolean notifyNow =(getITelephony() != null);
mRegistry.listen(pkgForDebug, listener.callback, events,notifyNow);
} catch(RemoteException ex) {
// system process dead
} catch(NullPointerException ex) {
// system process dead
}
}
在TelephonyManager类中只是通过服务管理器来得到不同的具体服务者进而提供电话的一些基本信息和注册对电话状态监听的回调, 并没有提供给可以挂断电话的功能
那系统是怎样挂断电话呢…?
最后没有找到有挂断电话的功能方法,但是在ITelephony.aidl文件中找到了
/**
* End call or go to the Home screen
*
* @return whether it hung up
*/
booleanendCall();
我们知道AIDL文件是Android接口描述语言。Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信. 为使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现.这种以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务.
这也就是说明我们可以通过此AIDL来访问到Itelephony这个接口提供的endCall功能.
加载完成后通过ITelephony telephony2 = ITelephony.Stub.asInterface(binder);把Binder对象转换成对应的服务端的代理对象,然后就通过这个Itelephony服务类在调用端的代理来完成挂断电话的功能.