2012-06-01 25 views
0

everyone。 我試圖訪問android.internal.telephony.CallManager中的sendDtmf方法,使用Reflection將這些音調發送到IVR語音。使用反射訪問Android中的Dtmf功能

的代碼如下:

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)sendDtmf()方法確實存在於ClassManager類中,如果可以,我可以訪問它嗎?

任何建議將非常感激。

回答

0

嘗試一組不同的參數類型,我不記得曾經sendDtmf採取Context - IC和2.3版本都以一個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; 
    } 
} 

說不上來,他們已經放置什麼保護呼叫管理器裏 - 或者,如果你作爲一個用戶應用程序,甚至能夠成功地調用這個方法 - 但這個例子至少可以讓你嘗試。

+0

非常感謝!我認爲我們向前邁進了一步。現在我在Method m.invoke(Object receiver,Object ... args)上得到另一個異常。 'java.lang.IllegalArgumentException:com.android.internal.telephony.CallManager類型的預期接收者,但得到java.lang.Class .'任何線索?再次感謝。 –

+0

那麼,首先你需要傳遞一個'Character'對象而不是上下文。您還需要在這裏傳遞類的實例而不是'null':'get.invoke(null,params);' – Jens

+0

對不起,我沒有粘貼引發異常的實際代碼。這裏是:'String className =「com.android.internal.telephony.CallManager」; \t \t \t \t \t \t \t \t \t \t \t \t嘗試{ \t \t \t \t \t MyClass類=的Class.forName(類名); \t \t \t \t \t \t \t \t \t \t \t \t \t \t //類[] paramTypes =新等級[1]; \t \t \t \t \t類 [] paramTypes = new Class [] {char。類};方法m = myClass.getMethod(「sendDtmf」,paramTypes);方法m = myClass.getMethod(「sendDtmf」,paramTypes);方法m = myClass.getMethod(「sendDtmf」,paramTypes); \t \t \t \t \t m.setAccessible(true); \t \t \t \t \t m.invoke(myClass,'1'); ''''。那是對的嗎?謝謝! –