10

I want to hang up incoming call I detect it and then I want to hang it up.

The problem is that this: com.android.internal.telephony.ITelephony is not resolved.

I tried to adding package com.android.internal.telephony to my application and create interface:

package com.android.internal.telephony;

public interface ITelephony {      

    boolean endCall();     

    void answerRingingCall();      

    void silenceRinger(); 

}

but the call is not ended.

Here I detect call, display toast(it is displayed) then try to hang up but as I said first there was no com.android.internal.telephony.ITelephony before I created that package:

private class CallStateListener extends PhoneStateListener {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                // called when someone is ringing to this phone
                Toast.makeText(ctx, "Incoming: " + incomingNumber, Toast.LENGTH_LONG).show();
                 try{
                        TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
                        Class c = Class.forName(tm.getClass().getName());
                        Method m = c.getDeclaredMethod("getITelephony");
                        com.android.internal.telephony.ITelephony telephonyService = (com.android.internal.telephony.ITelephony) m.invoke(tm);  

                        telephonyService = (com.android.internal.telephony.ITelephony) m.invoke(tm);
                        telephonyService.silenceRinger();
                        telephonyService.endCall();
                    }catch (Exception e) {
                        e.printStackTrace();

                    }
                break;
            }
        }
    }

My Manifest and permissions:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.a"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         <service
            android:name=".CallDetectService"
            android:enabled="true"
            android:exported="false" >
        </service>
    </application>



</manifest>
Kara
  • 6,115
  • 16
  • 50
  • 57
Yoda
  • 17,363
  • 67
  • 204
  • 344

3 Answers3

21

The ITelephony interface is internal, so you cannot get a standard reference to it. You could use reflection all the way, i.e.

TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

Method m1 = tm.getClass().getDeclaredMethod("getITelephony");
m1.setAccessible(true);
Object iTelephony = m1.invoke(tm);

Method m2 = iTelephony.getClass().getDeclaredMethod("silenceRinger"); 
Method m3 = iTelephony.getClass().getDeclaredMethod("endCall"); 

m2.invoke(iTelephony);
m3.invoke(iTelephony);

But either way those methods need the MODIFY_PHONE_STATE permission, which can only be granted to system apps. So I'm afraid it won't work anyway.

matiash
  • 54,791
  • 16
  • 125
  • 154
  • There are alternative to standard Dialer(phone application) in Android Play Store, maybe there is a way to go around it. – Yoda Jul 04 '14 at 21:39
  • Oh please see this EDIT 3 here: http://stackoverflow.com/questions/24580223/how-to-reject-any-incoming-call-when-i-have-already-detected-it/24580252?noredirect=1#comment38077652_24580252 It is my question where I just copied `ITelephony` interface from grep code(http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/com/android/internal/telephony/ITelephony.java/?v=source) to `com.android.internal.telephone` package. – Yoda Jul 04 '14 at 21:40
  • Just on the side. Why is it internal? Does internal means just private or protected? If to disable access to it, then it is not really working if reflelction does the job, so why it is done? – Yoda Dec 25 '14 at 23:17
  • 2
    Your code is working with 2 permission : READ_PHONE_STATE and CALL_PHONE.. thank you very much !! – Kushal Apr 04 '15 at 06:29
  • What is the value of `TELEPHONY_SERVICE`? – hasnain_ahmad Jul 22 '16 at 06:42
  • @matiash : I have added the required permisions, App get crashed. – Vineesh TP May 08 '17 at 14:40
  • I am getting PhoneStateReceiver **java.lang.reflect.InvocationTargetException on Android 8.0 any solution to that ? – Ali Akram May 09 '18 at 06:06
  • One general tip: `Class.getMethod` will also find the method (as opposed to `getDeclaredMethod`) if the class is a child class not self implementing the method. – Joop Eggen Aug 24 '18 at 15:06
2

For kotlin:

 val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
 val m1 = tm::class.java.getDeclaredMethod("getITelephony")
 m1.setAccessible(true)
 val telephonyService = m1.invoke(tm)
 val m2 = telephonyService::class.java.getDeclaredMethod("silenceRinger")
 val m3 = telephonyService::class.java.getDeclaredMethod("endCall")

 m2.invoke(telephonyService)
 m3.invoke(telephonyService)
1

For Android API 28 and above you can use the following code

 TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                telecomManager.endCall();
            }
          
        }else{
       //Ask for permission here
       }

Also add this permission in your app manifest file

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
Ali Imran
  • 8,927
  • 3
  • 39
  • 50