为了账号安全,请及时绑定邮箱和手机立即绑定

Java ClassCastException:怎么会这样?

Java ClassCastException:怎么会这样?

浮云间 2023-05-17 15:08:27
我正在尝试使用 Android Telephony Manager 结束通话(新的 Call Screening API 不适合我)。我在网上找到了很多例子,都和我下面的代码非常相似。它编译得很好,但我在线上得到了一个运行时 ClassCastExceptiontelephonyService = (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();        }    }我也试过导入com.android.internal.telephony(包括 ITelephony),但这不符合要求。
查看完整描述

1 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

它编译是因为你使用了反射:Object Method.invoke()。

反射在编译时通常很好,但在运行时可能不太好。


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


ITelephony您定义为嵌套类的接口MyApp.IncomingCallReceiver不是该类的实例Proxy。这是肯定的,因为它没有扩展:


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


查看完整回答
反对 回复 2023-05-17
  • 1 回答
  • 0 关注
  • 135 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信