Java ClassCastException:为什么?

Java ClassCastException:为什么?,java,casting,broadcastreceiver,classcastexception,Java,Casting,Broadcastreceiver,Classcastexception,我正在尝试使用Android Telephony Manager结束通话(新的通话屏蔽API不适合我)。我在网上找到了许多例子,都与下面的代码非常相似。它编译得很好,但我得到了一个运行时ClassCastException telephonyService = (ITelephony) m.invoke(tm); 例外是 java.lang.ClassCastException: com.android.internal.telephony.ITelephony$Stub$Proxy

我正在尝试使用Android Telephony Manager结束通话(新的通话屏蔽API不适合我)。我在网上找到了许多例子,都与下面的代码非常相似。它编译得很好,但我得到了一个运行时ClassCastException

telephonyService = (ITelephony) m.invoke(tm); 
例外是

java.lang.ClassCastException:
  com.android.internal.telephony.ITelephony$Stub$Proxy
  cannot be cast to com.ramrod.MyApp.IncomingCallReceiver$ITelephony
我的代码是

public class IncomingCallReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        ITelephony telephonyService;
        try {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){
                TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                try {
                    Method m = tm.getClass().getDeclaredMethod("getITelephony");
                    m.setAccessible(true);
                    telephonyService = (ITelephony) m.invoke(tm);
                    if ((number != null)) {
                        telephonyService.endCall();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                Toast.makeText(context, "Ring " + number, Toast.LENGTH_SHORT).show();

            }
            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)){
                Toast.makeText(context, "Answered " + number, Toast.LENGTH_SHORT).show();
            }
            if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)){
                Toast.makeText(context, "Idle "+ number, Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
我发现的示例还直接包含Java接口,如下所示:

public static interface ITelephony {
    boolean endCall();
    void answerRingingCall();
    void silenceRinger();
}
是什么导致了这种类型的异常?我怎样才能修好它?
(我对添加的界面非常怀疑)


我还尝试导入com.android.internal.telephony(包括ITelephony),但这并不复杂。

它会编译,因为您使用反射:
对象方法.invoke()

在编译时反射通常很好,但在运行时反射可能更少

这里,您尝试在运行时强制转换的实例是
Proxy
,更准确地说是嵌套类:
com.android.internal.telephony.ITelephony.Stub.Proxy

定义为MyApp.IncomingCallReceiver的嵌套类的接口
ITelephony
不是该
代理类的实例。这是肯定的,因为它没有扩展任何内容:

public static interface ITelephony {
    boolean endCall();
    void answerRingingCall();
    void silenceRinger();
}
而类强制转换异常

我假设
Proxy
com.android.internal.telephony.ITelephony
的一个生成实现,所以您需要做的可能只是导入该类并强制转换到该类:

import com.android.internal.telephony.ITelephony;
//..    
telephonyService = (ITelephony) m.invoke(tm); 

当您正在强制转换的对象(一个
com.android.internal.telephony.ITelephony$Stub$Proxy
)不是您要强制转换到的类型的实例(
com.ramrod.MyApp.IncomingCallReceiver$ITelephony
)时,就会发生这种类型的异常。特别是,请注意
com.android.internal.telephony.ITelephony
com.ramrod.MyApp.IncomingCallReceiver$ITelephony
是两种同名的不同类型。