I am trying to use reflection to access some unpublished features of the telephony API. Currently I am having trouble instantiating a serviceManager
object that is needed to get the "phone" service as a binder which I can then use to instantiate a telephony object which is needed to make a call, end call, etc...
currently when I make the call
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { new Binder() });
it returns a nullPointerException. I believe this has to do with creating a new Binder instead of sending the appropriate binder (which I am unsure of which one is appropriate)
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);
}
By doing the following
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { tmpBinder });
you will get a ServiceManagerProxy instance, then the next issue happens on the line
telephonyCall.invoke(telephonyObject, number);
I have a solution. Change:
String serviceManagerName = "android.os.IServiceManager";
to:
String serviceManagerName = "android.os.ServiceManager";
Yes, it's possible! I spent 24 hours of investigating and discovering, and I've found "fresh" solution!
// "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);
Anyone who wants to develop their call-control software visit this start point:
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
There is a project. and there are important comments (and credits).
In short: copy aidl file, add permissions to manifest, copy-paste source for telephony management.
Some more info for you: You can only send AT commands if you are rooted. Then you can kill system process and send commands but you will need a reboot to allow your phone to receive and send calls.
I'm very happy! Now my Shake2MuteCall will get an update!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With