2010-01-04 72 views
20

我想用反射來訪問電話API的一些未發佈的功能。目前,我在實例化serviceManager對象時遇到問題,需要將「電話」服務作爲活頁夾來使用,然後我可以使用它來實例化撥打電話,結束呼叫等所需的電話對象...反思訪問高級電話功能

當前撥打電話時

serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { new Binder() }); 

它返回一個nullPointerException。我相信這必須做與創建一個新的活頁夾,而不是發送相應的粘合劑(這我不清楚其中的一個爲宜)

public void placeReflectedCall() throws ClassNotFoundException, 
     SecurityException, NoSuchMethodException, IllegalArgumentException, 
     IllegalAccessException, InvocationTargetException, 
     InstantiationException { 
    String serviceManagerName = "android.os.IServiceManager"; 
    String serviceManagerNativeName = "android.os.ServiceManagerNative"; 
    String telephonyName = "com.android.internal.telephony.ITelephony"; 

    Class telephonyClass; 
    Class telephonyStubClass; 
    Class serviceManagerClass; 
    Class serviceManagerStubClass; 
    Class serviceManagerNativeClass; 
    Class serviceManagerNativeStubClass; 

    Method telephonyCall; 
    Method telephonyEndCall; 
    Method telephonyAnswerCall; 
    Method getDefault; 

    Method[] temps; 
    Constructor[] serviceManagerConstructor; 

    // Method getService; 
    Object telephonyObject; 
    Object serviceManagerObject; 
    String number = "1111111111"; 

    telephonyClass = Class.forName(telephonyName); 
    telephonyStubClass = telephonyClass.getClasses()[0]; 
    serviceManagerClass = Class.forName(serviceManagerName); 
    serviceManagerNativeClass = Class.forName(serviceManagerNativeName); 

    Method getService = // getDefaults[29]; 
    serviceManagerClass.getMethod("getService", String.class); 

    Method tempInterfaceMethod = serviceManagerNativeClass.getMethod(
      "asInterface", IBinder.class); 
    // this does not work 
    serviceManagerObject = tempInterfaceMethod.invoke(null, 
      new Object[] { new Binder() }); 

    IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, 
      "phone"); 
    Method serviceMethod = telephonyStubClass.getMethod("asInterface", 
      IBinder.class); 
    telephonyObject = serviceMethod 
      .invoke(null, new Object[] { retbinder }); 

    telephonyCall = telephonyClass.getMethod("call", String.class); 
    telephonyEndCall = telephonyClass.getMethod("endCall"); 
    telephonyAnswerCall = telephonyClass.getMethod("answerRingingCall"); 

    telephonyCall.invoke(telephonyObject, number); 

} 
+0

「目前我有麻煩實例化一個對象的ServiceManager」是你給有關錯誤或問題的唯一信息。你給我們的代碼。現在告訴我們它在做什麼或不做什麼是意外的,以及如何知道它不能正常工作。 – 2010-01-04 18:14:54

回答

5

通過執行以下操作

Binder tmpBinder = new Binder(); 
tmpBinder.attachInterface(null, "fake"); 
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { tmpBinder }); 

你會得到一個ServiceManagerProxy實例,那麼下一個問題發生在線

telephonyCall.invoke(telephonyObject, number); 
1

是的,這是可能的!我花了24小時進行調查和發現,並找到了「新鮮」的解決方案!

// "cheat" with Java reflection to gain access to 
// TelephonyManager's ITelephony getter 
Class c = Class.forName(tm.getClass().getName()); 
Method m = c.getDeclaredMethod("getITelephony"); 
m.setAccessible(true); 
telephonyService = (ITelephony) m.invoke(tm); 

誰想要發展自己的呼叫控制軟件訪問這個起點:
http://www.google.com/codesearch/p?hl=en#zvQ8rp58BUs/trunk/phone/src/i4nc4mp/myLock/phone/CallPrompt.java&q=itelephony%20package:http://mylockforandroid%5C.googlecode%5C.com&d=0

有一個項目。並有重要的評論(和學分)。

簡而言之:複製aidl文件,爲清單添加權限,複製粘貼電話管理源。

一些更多的信息給你:你只能發送AT命令,如果你是植根。然後,您可以終止系統進程併發送命令,但您需要重新啓動才能讓手機接收和發送呼叫。

我很開心!現在我的Shake2MuteCall會得到更新!

+2

嗨。我是mylock的開發者。我只是想告訴你,這不再適用於2.3,我們正在研究如何在超級用戶root權限下完成相同的結果。我沒有提出這種方法,我的一個朋友Tedd遇到了它,並找出了將反射應用於迭代的方法。 – mylock 2011-02-12 06:25:12

+0

這適用於我4.2 – AlBeebe 2013-07-03 17:28:23

+0

嘿@AlBeebe上面的鏈接現在不工作,你可以請分享aidl文件和電話管理的來源嗎?它會幫助我很多。 – 2015-06-25 04:58:57

3

我有一個解決方案。變化:

String serviceManagerName = "android.os.IServiceManager"; 

到:

String serviceManagerName = "android.os.ServiceManager"; 
+0

這適用於我! :) – 2011-12-05 02:31:45