Getting java.lang.ClassCastException while sending DTMF tones over an active call in android
Asked Answered
S

2

3

I am developing an app that sends DTMF tones over an active call in android. I searched a lot to implement this feature in my app and i found this : com.android.internal.telecom.IInCallAdapter interface that extends android.os.IInterface. There is a method playDtmfTone(String s,Char c) inside IInCallAdapter that we can use to send DTMF tones over an active call. I have an activity HelloPage.java that do so, but getting java.lang.ClassCastException error while initializing an object of IInCallAdapter. Well i know what this error means but don't know how to deal with this. Here is my code :

public class HelloPage extends Activity implements View.OnClickListener{

Button DTMF_b1,DTMF_b2,DTMF_b3,DTMF_b4,DTMF_b5,DTMF_b6,DTMF_b7,DTMF_b8,DTMF_b9,DTMF_b0,DTMF_bS,DTMF_bP;
private TextView DTMFToneDialedView;
private String DTMFToneDialedNumber = "";
private String callId;
private IInCallAdapter mIInCallAdapter;

@Override
protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_hello_page);

    mIInCallAdapter = (IInCallAdapter) this;   /*I am getting error here in this line*/

    DTMF_b1 = (Button) findViewById(R.id.id_playDTMF1);
    DTMF_b2 = (Button) findViewById(R.id.id_playDTMF2);
    DTMF_b3 = (Button) findViewById(R.id.id_playDTMF3);
    DTMF_b4 = (Button) findViewById(R.id.id_playDTMF4);
    DTMF_b5 = (Button) findViewById(R.id.id_playDTMF5);
    DTMF_b6 = (Button) findViewById(R.id.id_playDTMF6);
    DTMF_b7 = (Button) findViewById(R.id.id_playDTMF7);
    DTMF_b8 = (Button) findViewById(R.id.id_playDTMF8);
    DTMF_b9 = (Button) findViewById(R.id.id_playDTMF9);
    DTMF_bS = (Button) findViewById(R.id.id_playDTMFStar);
    DTMF_b0 = (Button) findViewById(R.id.id_playDTMF0);
    DTMF_bP = (Button) findViewById(R.id.id_playDTMFPound);

    callId = MainActivity.telecomCallId;  //Getting telecom Call ID from a static variable in a MainActivity

    DTMFToneDialedView = (TextView) findViewById(R.id.id_DTMFToneDialedKey);

    DTMF_b1.setOnClickListener(this);
    DTMF_b2.setOnClickListener(this);
    DTMF_b3.setOnClickListener(this);
    DTMF_b4.setOnClickListener(this);
    DTMF_b5.setOnClickListener(this);
    DTMF_b6.setOnClickListener(this);
    DTMF_b7.setOnClickListener(this);
    DTMF_b8.setOnClickListener(this);
    DTMF_b9.setOnClickListener(this);
    DTMF_bS.setOnClickListener(this);
    DTMF_b0.setOnClickListener(this);
    DTMF_bP.setOnClickListener(this);

}

//This method updated the screen what we dial
public void dialedNumberUpdater(String key){

    DTMFToneDialedNumber = DTMFToneDialedNumber + key;
    DTMFToneDialedView.setText(DTMFToneDialedNumber);
}


@Override
public void onClick(View v) {

    switch (v.getId()){

        case R.id.id_playDTMF1:
            try {
                mIInCallAdapter.playDtmfTone(callId, '1');
                dialedNumberUpdater("1");
            }catch (Exception e){
                dialedNumberUpdater("w");  //updating 'w' into the screen so that user can see it is not working.
            }
            break;

        case R.id.id_playDTMF2:
            try {
                mIInCallAdapter.playDtmfTone(callId, '2');
                dialedNumberUpdater("2");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF3:
            try {
                mIInCallAdapter.playDtmfTone(callId, '3');
                dialedNumberUpdater("3");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF4:
            try {
                mIInCallAdapter.playDtmfTone(callId, '4');
                dialedNumberUpdater("4");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF5:
            try {
                mIInCallAdapter.playDtmfTone(callId, '5');
                dialedNumberUpdater("5");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF6:
            try {
                mIInCallAdapter.playDtmfTone(callId, '6');
                dialedNumberUpdater("6");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF7:
            try {
                mIInCallAdapter.playDtmfTone(callId, '7');
                dialedNumberUpdater("7");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF8:
            try {
                mIInCallAdapter.playDtmfTone(callId, '8');
                dialedNumberUpdater("8");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF9:
            try {
                mIInCallAdapter.playDtmfTone(callId, '9');
                dialedNumberUpdater("9");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMFStar:
            try {
                mIInCallAdapter.playDtmfTone(callId, '*');
                dialedNumberUpdater("*");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMF0:
            try {
                mIInCallAdapter.playDtmfTone(callId, '0');
                dialedNumberUpdater("0");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

        case R.id.id_playDTMFPound:
            try {
                mIInCallAdapter.playDtmfTone(callId, '#');
                dialedNumberUpdater("#");
            }catch (Exception e){
                dialedNumberUpdater("w");
            }
            break;

    }

}

}

Here is the Logcat :

01-29 01:43:07.649     565-1247/? I/ActivityManager﹕ START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=algor7.code.backgroundcallingapp/.HelloPage} from uid 10099 on display 0
01-29 01:43:07.794  13439-13439/algor7.code.backgroundcallingapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: algor7.code.backgroundcallingapp, PID: 13439
    java.lang.RuntimeException: Unable to start activity ComponentInfo{algor7.code.backgroundcallingapp/algor7.code.backgroundcallingapp.HelloPage}: java.lang.ClassCastException: algor7.code.backgroundcallingapp.HelloPage cannot be cast to android.os.IInterface
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.ClassCastException: algor7.code.backgroundcallingapp.HelloPage cannot be cast to android.os.IInterface
            at algor7.code.backgroundcallingapp.HelloPage.onCreate(HelloPage.java:39)
            at android.app.Activity.performCreate(Activity.java:6251)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
            at android.app.ActivityThread.-wrap11(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
01-29 01:43:07.813      565-876/? W/ActivityManager﹕ Force finishing activity algor7.code.backgroundcallingapp/.HelloPage
01-29 01:43:08.345      565-578/? W/ActivityManager﹕ Activity pause timeout for ActivityRecord{454bc33 u0 algor7.code.backgroundcallingapp/.HelloPage t191 f}

Please help me to solve this issue. Thank you in advance.

Swetiana answered 28/1, 2016 at 22:17 Comment(1)
You can see my Project on Github.Swetiana
G
0

Because your this is a HelloPage object. It is not an IInCallAdapter, does not inherit from it, and does not extend it. It can't be cast as one. Why would you think it could be?

Geny answered 29/1, 2016 at 0:22 Comment(7)
Because IInCallAdapter is an interface that extends IInterface and i think this is the way we initialize a normal interface object in an activity but this is different kind of interface(bcz it extends IInterface)...and this initializing technique is not working with this kind of interface....really, i don't know how to initialize this 'mIInCallAdapter'.Swetiana
No. The way you initialize an interface is by creating a class that implements it and instantiating an insurance of that class. You can't cat an activity as one unless the activity implements itGeny
I usually do like this.. I.java => public interface I { public void fun(int a); }Swetiana
class ABC extends Activity implements I { ............. @Override void fun(int a) { \\doing something } .......... }Swetiana
class DEF extends Activity { .......... private ABC abc; abc = (ABC) getActivity(); abc.fun(456);.............}Swetiana
So do you talking about class ABC in this example that implements interface ISwetiana
My HelloPage.java is very similar to DEF.java as shown in the example aboveSwetiana
M
0

Create a class that implements IInCallAdapter and then implement all its methods

public class ClassName implements IInCallAdapter {
    ... 
} 

Then you can create an instance of this class in your Activity class

Mystagogue answered 29/1, 2016 at 15:26 Comment(6)
That is the main problem the implementation class is already there and i don't know anything about it (almost blind). I just have this IInCallAdapter interface and want to use it. I just know that some internal implementation class is there that implements this IInCallAdapter interface and send DTMF tones over an active call by overriding playDtmfTone(String s, char c) method, i just need to use this interface in my activity but don't know how..Swetiana
I can see that InCallAdapter is not exposed in the API. Look at this: android.googlesource.com/platform/frameworks/base/+/master/…Mystagogue
What about the Call class? developer.android.com/reference/android/telecom/…Mystagogue
Yes i have gone through all these APIs before. If i use any of these you mentioned then the question remains the same that is how to initialize the IInCallAdapter object because Call class needs to pass an InCallAdapter object as a parameter while creating an object of Call class and IInCallAdapter Interface needs to pass as a parameter while creating an InCallAdapter object. Hence question remains same..Swetiana
Did you look at InCallService?Mystagogue
Yes but it use Messenger as an interface and has very limited functionalities, doesn't meet my requirements... Actually it also use InCallAdapter at line 87 in InCallService.java.Swetiana

© 2022 - 2024 — McMap. All rights reserved.