由于系統api并沒有給我們提供itelephony這個電話管理服務類的接口使用,是以我們就得通過非正常手段來得到這個服務接口.(通過源碼中的itelephony.aidl來幫助我們生成電話管理服務接口,進而使我們能夠使用到系統操作電話的功能).
例如>>結束通話:
1> 拷貝連同包結構将用到的itelephony.aidl檔案到你的項目中
(由于其中引入了android.telephony.neighboringcellinfo.aidl, 是以将其也引入到你的項目中去)
要想挂斷電話必須具有<uses-permission android:name="android.permission.call_phone"/>權限
try{
//反射獲得系統服務的getservice方法對象
method method = class.forname("android.os.servicemanager")
.getmethod("getservice", string.class);
//執行這個方法得到一個ibinder對象
ibinder binder = (ibinder) method.invoke(null, new object[]{telephony_service});
//轉換為具體的服務類(itelephony)接口對象
itelephony telephony = itelephony.stub.asinterface(binder);
//結束通話
telephony.endcall();
//從上是通過 反射來做的, 下面正常的做法>> 按下面來做
// ibinder bindr = servicemanager.getservice(telephony_service);
// itelephony telephony2 = itelephony.stub.asinterface(binder);
// telephony2.endcall();
}catch(exception e){
e.printstacktrace();
}
下面來看看它是怎樣的一個機制來操作電話管理功能的.
首先我們要知道所有的服務類都是在與服務管理器互動.服務管理器把所有的服務都納入到它的管理範疇.而那些系統架構中的各個服務工具類底層都是與這個服務管理器大管家互動.
我是通過 servicemanager這個系統架構提供服務管理器來得到itelephony這個服務的binder對象的
servicemanager è系統架構上的所有服務都在後來運作着.要想得這些服務 就得通過 這個方法getservice來獲得
public static ibinder getservice(string name) {//取得服務的ibinder對象
try {
ibinder service = scache.get(name);//先從緩存上找到這個服務的ibinder
if (service != null) {
return service;
} else { //如果為空就通過服務管理器接口實作類的getservice方法來得到你想要的服務
return getiservicemanager().getservice(name);
} catch(remoteexception e) {
log.e(tag, "error in getservice", e);
return null;
public static void addservice(stringname, ibinder service){//往服務管理器中追加一個服務
public static ibinder checkservice(string name)…..//檢索已經存在的service
public static string[] listservices() throwsremoteexception//列出目前以有的服務
下面來看看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>";
boolean notifynow =(getitelephony() != null);
mregistry.listen(pkgfordebug, listener.callback, events,notifynow);
} catch(remoteexception ex) {
// system process dead
} catch(nullpointerexception ex) {
在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服務類在調用端的代理來完成挂斷電話的功能.