How to properly use reflection to access hidden methods in Telephony Manager

安稳与你 提交于 2019-11-30 16:28:21

You need an instance of the class you wish to operate on - an object of that type that has already been created.

You pass that to setLine1Number.invoke()

For example, if we were dealing with the Integer class you'd say:

Integer i = new Integer(5);
...
Object TestReturn = someIntegerMethod.invoke(i, arglist);

You must create an instance of GSMPhone (classToInvestigate). Here is a start:

Class commandsInterface = Class.forName("com.android.internal.telephony.CommandsInterface");
Class phoneNotifier = Class.forName("com.android.internal.telephony.PhoneNotifier");
Constructor constructor = classToInvestigate.getConstructor(Context.class, commandsInterface, phoneNotifier);

// This creation of newInstance will have to be modified depending on NullPointerExceptions.
// Will probably have to pass in context, as well as instantiate CommandsInterface and PhoneNotifier in a similar fashion and then inject them as well.
Object newInstance = constructor.newInstance(context, null, null);

setLine1Number.invoke(newInstance, arglist);

You need to pass in an object of the type you want to call the method on, not the class object.

in the invoke call you need to pass an instance of GSMPhone class not classToInvestigate

I'm not familiar with any android API so i'm not sure how you can obtain an instance of it.

EDIT: looking at GSMPhone it calls a public method of SIMRecords maybe you can obtain an instance of that class and call that method instead?

In case you like to set not accessible fields or call not accesible methods, you can set them to accessible if you like See:

https://github.com/ko5tik/andject/blob/master/src/main/java/de/pribluda/android/andject/ViewInjector.java

( lines 34-37 )

1) I suggest using "com.android.internal.telephony.Phone" instead of "....gsm.GSMPhone"

2) try this one in the beginning (and use mPhone when invoking your setLine1Number method): NB: ommit try/catch if you desire, but set your calling method to throw everything up...

private static final String CLASS_PHONEFACTORY = "com.android.internal.telephony.PhoneFactory";
private static final String METHOD_GETDEFAULTPHONE = "getDefaultPhone";

private Class<?> cPhoneFactory;
private Class<?> cPhone;
private Method mGetDefaultPhone;

private Object mPhone;

...

    try {
        cPhoneFactory = Class.forName(CLASS_PHONEFACTORY);
    } catch (ClassNotFoundException e) {
        cPhoneFactory = null; 
    }
    try {
        cPhone = Class.forName(CLASS_PHONE);
    } catch (ClassNotFoundException e) {
        cPhone = null;
    }

    try {
        mGetDefaultPhone = cPhoneFactory == null ? null : cPhoneFactory.getMethod(METHOD_GETDEFAULTPHONE,(Class[])null);
    }
    catch (NoSuchMethodException e) {
        mGetDefaultPhone = null;
    }

    try {
        mPhone = mGetDefaultPhone == null ? null : mGetDefaultPhone.invoke(null,(Object[])null);
    } catch (Exception e) {
        mPhone = null;
    }
Jason Zong

please try the following code.

String className = "com.android.internal.telephony.gsm.GSMPhone";
Class classToInvestigate = Class.forName(className);
Object gsmObj = classToInvestigate.newInstance();

Object arglist[] = new Object[3];
arglist[0] = new String("Phone Number");
arglist[1] = new String ("16035552412"); // Not a real phone number
arglist[2] = null;

Class[] paramTypes = new Class[3];
paramTypes[0] = String.class;
paramTypes[1] = String.class;
paramTypes[2] = Message.class;

Method setLine1Number = classToInvestigate.getMethod("setLine1Number", paramTypes);
boolean accessible = setLine1Number.isAccessible();
setLine1Number.setAccessible(true);

Object TestReturn = setLine1Number.invoke(gsmObj, arglist);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!