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.

Algor7
  • 149
  • 1
  • 14

2 Answers2

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?

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • 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'. – Algor7 Jan 29 '16 at 10:58
  • 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 it – Gabe Sechan Jan 29 '16 at 11:00
  • I usually do like this.. I.java => public interface I { public void fun(int a); } – Algor7 Jan 29 '16 at 13:05
  • class ABC extends Activity implements I { ............. @Override void fun(int a) { \\doing something } .......... } – Algor7 Jan 29 '16 at 13:10
  • class DEF extends Activity { .......... private ABC abc; abc = (ABC) getActivity(); abc.fun(456);.............} – Algor7 Jan 29 '16 at 13:13
  • So do you talking about class ABC in this example that implements interface I – Algor7 Jan 29 '16 at 13:19
  • My HelloPage.java is very similar to DEF.java as shown in the example above – Algor7 Jan 29 '16 at 14:31
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

  • 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.. – Algor7 Jan 29 '16 at 15:52
  • I can see that InCallAdapter is not exposed in the API. Look at this: https://android.googlesource.com/platform/frameworks/base/+/master/telecomm/java/android/telecom/InCallAdapter.java – Gianmarco Reverberi Jan 29 '16 at 16:24
  • What about the Call class? http://developer.android.com/reference/android/telecom/Call.html#playDtmfTone(char) – Gianmarco Reverberi Jan 29 '16 at 16:36
  • 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.. – Algor7 Jan 29 '16 at 18:07
  • Did you look at InCallService? – Gianmarco Reverberi Jan 29 '16 at 22:38
  • 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](https://github.com/android/platform_frameworks_base/blob/master/telecomm/java/android/telecom/InCallService.java). – Algor7 Jan 30 '16 at 09:32