tags:

views:

829

answers:

6

I am trying to use reflection to access some advanced features of the telephony api not published. 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 due 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);

}

Thanks in advance for any answers.

+2  A: 

Hi,

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);

Hope that helps David

david
A: 

I'm also interested on how to get it work. Now i'm getting a NullPointerException when i call telephonyEndCall.invoke(telephonyObject); because telephonyObject is null.

Ricky
A: 

OMG!!! YES, WE CAN DO THAT!!! I was going to kill myself after severe 24 hours of investigating and discovering... But 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);

all all all of hundreds of people 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)

briefly: copy aidl file, add permissions to manifest, copy-paste source for telephony management )))

Some more info for you. AT commands you can send only if you are rooted. Than 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 hapy =) Now my Shake2MuteCall will get an update !

foryou
A: 

hi can you please tell me how to do this, i've also try to do this, but couldn't achieve this.

i just want to start my activity when call is receiving

as you asked earlier i've done like this

telManager = (TelephonyManager) context .getSystemService(Context.TELEPHONY_SERVICE);

     try {
      Class c = Class.forName(telManager.getClass().getName());
      Method m = c.getDeclaredMethod("getITelephony");
      m.setAccessible(true);
telephonyService = (ITelephony)m.invoke(telManager);

} catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); }

telManager.listen(new StateListener(), PhoneStateListener.LISTEN_CALL_STATE);

and have these permissions in manifest

is this correct?? regards, Mil

MIke
A: 

this is not working in EVO 4G. i have tried it. not the same app but its almost similar to this. hae you tried this in EVO. it always runs in the background. and what is this aidl file. in the project can't find such a file.

MIke
A: 

Hi I have a solution. i Change from String serviceManagerName = "android.os.IServiceManager"; to String serviceManagerName = "android.os.ServiceManager";

brad