How to block call in Android 4.2

903 Views Asked by At

My Note :as I have already clarified in my initial post, I don't think it's a duplicate, I already tried these method and it doesn't work for me, The code below seems only work for 2.2, it requires MODIFY_PHONE_STATE which is not permitted after Android 2.2****

This is not duplicated questions since i have already looked many other post here and it doesn't work for me I follow the solution from the link below: block phone call

TelephonyManager tm = (TelephonyManager)   
context.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");

But the code give me exception when run on real device(which is Android 4.2) java.lang.NoSuchMethodException: getITelephony

So, does it still possible use this solution on Android 4.2, if not,does there exist other solutions i can try?

Thanks a lot in advance

1

There are 1 best solutions below

5
On

Create a file named ITelephony.aidl it should contain these data:

package com.android.internal.telephony; 
interface ITelephony
{ 

  boolean endCall();     

  void answerRingingCall();      

  void silenceRinger(); 

}

Create these folders under src

android > internal > telephony

Then Place the ITelephony.adl under telephony folder.

Copy this DeviceStateListener class and place it under any package on your project.

import android.content.Context;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import java.lang.reflect.Method;

public class DeviceStateListener extends PhoneStateListener {
    private ITelephony telephonyService;
    private Context context;
    public DeviceStateListener(Context context) {
        this.context = context;
        initializeTelephonyService();
    }
    private void initializeTelephonyService() {
        try {
            TelephonyManager telephonyManager = (TelephonyManager) context
                    .getSystemService(Context.TELEPHONY_SERVICE);
            Class clase = Class.forName(telephonyManager.getClass().getName());
            try{
                Method method = clase.getDeclaredMethod("getITelephony");
            }catch (NoSuchMethodException e){
                e.printStackTrace();
            }
            method.setAccessible(true);
            telephonyService = (ITelephony) method.invoke(telephonyManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCallStateChanged(int state, final String incomingNumber) {
        switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                boolean isNumberIsBlocked=false;
                // You can check here if incomingNumber string is under your blacklisted numbers
                if (isNumberIsBlocked) {
                    try {
                // This is the main code that block the incoming call.
                        telephonyService.endCall();
                        Thread t = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                // You can run anything here lets say a notice to the user if a call is blocked
                            }
                        });
                        t.start();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
                break;
        }
    }
}

Here is another important class "ServiceReceiver" place it also under any package of your project and resolve all possible imports.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;

public class ServiceReciever extends BroadcastReceiver
{

    private static TelephonyManager telephony;
    private static DeviceStateListener phoneListener;
    private static boolean firstTime=true;

    public ServiceReciever(Context context)
    {
        telephony=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        phoneListener=new DeviceStateListener(context);
    }

    @Override
    public void onReceive(Context context, Intent intent)
    {
        if(firstTime)
        {
            telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
            firstTime = false;
        }
    }

    // You can use this in the future to stop the call blocker feature.
    public void stopListening() {
        telephony.listen(phoneListener, PhoneStateListener.LISTEN_NONE);
        firstTime=true;
    }

}

Copy this CallBlockerService class also and place it under any package of your project. It is an unkillable service that invokes the ServiceReceiver class.

import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import com.katadigital.phone.callsmsblocker.callListener.ServiceReciever;

public class CallBlockerService extends Service {

    public static final int notification_id = 111;

    // ---------------------------------------
    // Listening Services
    // ---------------------------------------
    private static ServiceReciever service;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        service = new ServiceReciever(getApplicationContext());
        registerReceiver(service, new IntentFilter(
                "android.intent.action.PHONE_STATE"));
        System.out.println("Call blocker is running now");
    }

    @Override
    public void onDestroy() {
        service.stopListening();
        unregisterReceiver(service);
        service = null;
        cancelStatusBarNotification();
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    public void cancelStatusBarNotification() {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(notification_id);
    }
}

Place this AfterBootReceiver class beside our CallBlockerService. Its job is to restart the blocker service when the phone starts from shutdown.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class AfterBootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) 
    {
             Intent serviceLauncher = new Intent(context, CallBlockerService.class);
             context.startService(serviceLauncher);
    }
}

Lastly place this on your AndroidManifest under tag.

<receiver android:name="com.callblocker.services.AfterBootReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </receiver>

        <service android:name="com.callblocker.services.CallBlockerService" >
        </service>

Replace "com.callblocker.services" with the folder location of the CallBlockerService and your AfterBootReceiver

I have tested this code until Android 4.4 KitKat. I hope you can follow the steps and it helps you with your problem.