我正在尝试使用反射来访问电话API的一些未发布的功能。目前我无法实例化一个serviceManager
对象,这个对象需要将“电话”服务作为绑定器,然后我可以使用它来实例化拨打电话,结束通话等所需的电话对象。
目前我打电话时
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { new Binder() });
它返回nullPointerException。我认为这与创建一个新的Binder而不是发送适当的粘合剂(我不确定哪个是合适的)有关。
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 :(得分:5)
通过以下方式
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { tmpBinder });
您将获得一个ServiceManagerProxy实例,然后下一个问题就行了
telephonyCall.invoke(telephonyObject, number);
答案 1 :(得分:3)
我有一个解决方案。变化:
String serviceManagerName = "android.os.IServiceManager";
为:
String serviceManagerName = "android.os.ServiceManager";
答案 2 :(得分: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文件,为清单添加权限,复制粘贴源以进行电话管理。
您可以获得更多信息:如果您是root用户,则只能发送AT命令。然后你可以杀死系统进程并发送命令,但你需要重新启动才能让你的手机接收和发送电话。
我很开心!现在我的Shake2MuteCall将获得更新!