1

Application detects incoming calls and displays a toast when they come. The inner class CallStateListener is responsible for detecting the call:

    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();           
                break;
            }
        }
    }

but now just after a Toast is shown I would like to cancel/reject this incoming call(any). How to perform cancelling this incoming call?

The full class looks like that:

package com.example.a;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;


public class CallHelper {

    /**
     * Listener to detect incoming calls.
     */
    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();           
                break;
            }
        }
    }

    /**
     * Broadcast receiver to detect the outgoing calls.
     */
    public class OutgoingReceiver extends BroadcastReceiver {
        public OutgoingReceiver() {
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

            Toast.makeText(ctx, "Outgoing: " + number, Toast.LENGTH_LONG).show();
        }

    }

    private Context ctx;
    private TelephonyManager tm;
    private CallStateListener callStateListener;

    private OutgoingReceiver outgoingReceiver;

    public CallHelper(Context ctx) {
        this.ctx = ctx;

        callStateListener = new CallStateListener();
        outgoingReceiver = new OutgoingReceiver();
    }

    /**
     * Start calls detection.
     */
    public void start() {
        tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);

        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
        ctx.registerReceiver(outgoingReceiver, intentFilter);
    }

    /**
     * Stop calls detection.
     */
/*  public void stop() {
        tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
        ctx.unregisterReceiver(outgoingReceiver);
    }*/

}

EDIT:

enter image description here

EDIT2 Maybe I lack 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>

UPDATED CLASS

package com.example.a;

import java.lang.reflect.Method;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.widget.Toast;


public class CallHelper {

    /**
     * Listener to detect incoming calls.
     */
    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;
            }
        }
    }

    /**
     * Broadcast receiver to detect the outgoing calls.
     */
    public class OutgoingReceiver extends BroadcastReceiver {
        public OutgoingReceiver() {
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);

            Toast.makeText(ctx, "Outgoing: " + number, Toast.LENGTH_LONG).show();
        }

    }

    private Context ctx;
    private TelephonyManager tm;
    private CallStateListener callStateListener;

    private OutgoingReceiver outgoingReceiver;

    public CallHelper(Context ctx) {
        this.ctx = ctx;

        callStateListener = new CallStateListener();
        outgoingReceiver = new OutgoingReceiver();
    }

    /**
     * Start calls detection.
     */
    public void start() {
        tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
        tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);

        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
        ctx.registerReceiver(outgoingReceiver, intentFilter);
    }

    /**
     * Stop calls detection.
     */
    /*
     * public void stop() { tm.listen(callStateListener,
     * PhoneStateListener.LISTEN_NONE);
     * ctx.unregisterReceiver(outgoingReceiver); }
     */

}

EDIT 3 Link to project: http://www.speedyshare.com/ccY6T/A1.zip

Kara
  • 6,115
  • 16
  • 50
  • 57
Yoda
  • 17,363
  • 67
  • 204
  • 344

1 Answers1

6

Import these...

  import java.lang.reflect.Method;
  import android.app.Activity;  
  import android.telephony.TelephonyManager;
  import com.android.internal.telephony.*;

Use this code to reject the phone call.

 try{
    TelephonyManager tm = (TelephonyManager)        context.getSystemService(Context.TELEPHONY_SERVICE);
    Class c = Class.forName(tm.getClass().getName());
    Method m = c.getDeclaredMethod("getITelephony");
    com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);  
    telephonyService = (ITelephony) m.invoke(tm);
    telephonyService.silenceRinger();
    telephonyService.endCall();
}catch (Exception e) {
    e.printStackTrace();
      // Some problem occurred while accessing private API
    // TODO: do whatever error handling you want here  

}

Add these permissions into Manifest file.

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

The com.android.internal.telephony is not part of the Android SDK. You can get this Java file from here.

Note:

Here we uses Java reflection.These methods are there, but they are marked as "private". Using reflection, we can get lots of information about classes, even the information that is considered "private". Since this is an "unsupported API" it may not work on all devices and it may be changed in a future release of Android

Community
  • 1
  • 1
Darish
  • 11,032
  • 5
  • 50
  • 70
  • Thank you. The only problem is that I do not know what type should be `telephonyService`. By looking on your code it should be `ITelephony` because you cast it, but this class/interface can't be found. – Yoda Jul 04 '14 at 20:11
  • I copied updated code(please look at edit in OP, I edited it too). The problem is there is no: `com.android.internal.telephony.ITelephony`. There is only `com.android.internal.util`. – Yoda Jul 04 '14 at 20:25
  • "The import com.android.internal.telephony.*; cannot be resolved". I get this. – Yoda Jul 04 '14 at 20:29
  • Thanks now there is no errors. I pasted updated code into EDIT2. The problem is that the phone does not rejects the call. The Android version is 4.2 – Yoda Jul 04 '14 at 20:51
  • Oh I added Manifest to show permissions I used also I will post my project in EDIT 3. – Yoda Jul 04 '14 at 20:51
  • 2
    not allowed permission – Menna-Allah Sami Sep 08 '14 at 11:43