0

每个人。我正在尝试使用反射访问 android.internal.telephony.CallManager 中的 sendDtmf 方法,以将这些音调发送到 IVR 语音。

代码如下:

import java.lang.reflect.Method;

import android.content.Context;
import android.util.Log;


public class RefelectionFactory {

public boolean sendDtmf(char c, Context context) throws IllegalArgumentException {

    try{
      @SuppressWarnings("rawtypes")
      //Class Phone = cl.loadClass("com.android.internal.telephony.Phone");

        ClassLoader classLoader = context.getClassLoader();
        final Class<?> classCallManager = classLoader.loadClass("com.android.internal.telephony.CallManager");

      //Parameters Types
      @SuppressWarnings("rawtypes")
      Class[] paramTypes= new Class[1];
      paramTypes[0]= Context.class;

      //Method get = Phone.getMethod("sendDtmf",  paramTypes);
      Method get = classCallManager.getMethod("sendDtmf",  paramTypes);
      get.setAccessible(true);

      //Parameters
      Object[] params= new Object[1];
      params[0]= context;

      get.invoke(null, params);

    }catch( IllegalArgumentException iAE ){
        throw iAE;
    }catch( Exception e ){
        Log.e("ERRORE", "sendDtmf", e);
    }
    return true;
}


}

当我编译代码时,在 LogCat 中抛出这个异常:

java.lang.NoSuchMethodException: sendDtmf [class android.content.Context]
java.lang.Class.getConstructorOrMethod(Class.java:460)
java.lang.Class.getMethod(Class.java:915)
it.digitalnatives.*****.ricarica.RefelectionFactory.sendDtmf(RefelectionFactory.java:39)
it.digitalnatives.*****.ricarica.MainRicarica$2.onClick(MainRicarica.java:541)
android.view.View.performClick(View.java:3511)
android.view.View$PerformClick.run(View.java:14105)
android.os.Handler.handleCallback(Handler.java:605)
android.os.Handler.dispatchMessage(Handler.java:92)
android.os.Looper.loop(Looper.java:137)
android.app.ActivityThread.main(ActivityThread.java:4424)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
dalvik.system.NativeStart.main(Native Method)

我被这些东西困住了,我有一些要求。1)这段代码正确吗?2) classManager 类中确实存在 sendDtmf() 方法,如果是,我可以访问它吗?

任何建议将不胜感激。

4

1 回答 1

0

尝试一组不同的参数类型,我不记得sendDtmf曾经采用 a Context- ICS 和 2.3 版本都采用 a char,即CallManager#sendDtmf(char c)

我建议:

Class<?>[] paramTypes = new Class<?>[]{char.class};
Method get = classCallManager.getMethod("sendDtmf",  paramTypes);

编辑:现在举个例子。

class Dtmf {
    private static final String CALL_MANAGER = "com.android.internal.telephony.CallManager";
    private static final String SEND_DTMF = "sendDtmf";
    private static final String GET_INSTANCE = "getInstance";
    private Method mSendDtmfMethod;
    private Object mCallManager;
    public Dtmf() {
        try {
            Class<?> callManagerClass = Class.forName(CALL_MANAGER);
            // Obtain an instance of CallManager
            Method getInstanceMethod = callManagerClass.getMethod(GET_INSTANCE);
            mCallManager = getInstanceMethod.invoke(null);
            // Get sendDtmf(char)
            Class<?>[] sendDtmfParamTypes = new Class<?>[]{char.class};
            mSendDtmfMethod = callManagerClass.getMethod(SEND_DTMF, sendDtmfParamTypes);
        } catch (ClassNotFoundException e) {
        } catch (NoSuchMethodException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        }
    }

    public boolean sendDtmf(char ch) {
        boolean result = false;
        if (mCallManager != null && mSendDtmfMethod != null) {
            try {
                Object res = mSendDtmfMethod.invoke(mCallManager, 
                        new Object[]{Character.valueOf(ch)});

                if (res instanceof Boolean) {
                    result = ((Boolean) res).booleanValue(); 
                }
            } catch (IllegalArgumentException e) {
            } catch (IllegalAccessException e) {
            } catch (InvocationTargetException e) {
            }
        }
        return result;
    }
}

不知道他们在呼叫管理器中设置了哪些保护措施——或者你作为用户应用程序是否能够成功调用此方法——但这个示例至少可以让你尝试。

于 2012-06-01T08:46:49.257 回答