2010-01-04 54 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