0

Recently working on an Android project which required call blocking feature, I came to know that to block calls you need MODIFY_PHONE_STATE permission.

While the permission is only given to system apps, I am wondering how Truecaller does that. As far as I know, Truecaller isn't a system app.

Truecaller background: It is an app widely used and known for identifying caller information. It has features such as blocking spammers and specific known and unknown contacts. Find more here.

If Truecaller has special permissions, please mention the process of getting those if possible.

Suyog
  • 212
  • 1
  • 14
  • 1
    It might help if you start by explaining what the heck Truecaller is and what it does. Its not a famous enough thing that you can just reference and expect us to know. – Gabe Sechan Mar 28 '18 at 18:24
  • Did you get any solution? – Astha Garg May 08 '20 at 12:15
  • Hey @Astha, I didn't actually find any solution or you can say I stopped looking for one. Here is one answer that seems helpful https://stackoverflow.com/questions/51085831/is-there-a-new-official-api-for-rejecting-calls-on-android. – Suyog May 18 '20 at 17:36

2 Answers2

3

BroadcastReceiver

    <receiver  android:name=".CallBarring">
        <intent-filter  android:priority="100" >
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver

Which listen to incoming calls and calls TelephonyManager.getITelephony().endCall()

import java.lang.reflect.Method;

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

import com.android.internal.telephony.ITelephony;

// Extend the class from BroadcastReceiver to listen when there is a incoming call
public class CallBarring extends BroadcastReceiver
{
    // This String will hold the incoming phone number
    private String number;

    @Override
    public void onReceive(Context context, Intent intent)
    {
        // If, the received action is not a type of "Phone_State", ignore it
        if (!intent.getAction().equals("android.intent.action.PHONE_STATE"))
            return;

            // Else, try to do some action
        else
        {
            // Fetch the number of incoming call
            number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

            // Check, whether this is a member of "Black listed" phone numbers stored in the database
            if(MainActivity.blockList.contains(new Blacklist(number)))
            {
                // If yes, invoke the method
                disconnectPhoneItelephony(context);
                return;
            }
        }
    }

    // Method to disconnect phone automatically and programmatically
    // Keep this method as it is
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void disconnectPhoneItelephony(Context context)
    {
        ITelephony telephonyService;
        TelephonyManager telephony = (TelephonyManager)
                context.getSystemService(Context.TELEPHONY_SERVICE);
        try
        {
            Class c = Class.forName(telephony.getClass().getName());
            Method m = c.getDeclaredMethod("getITelephony");
            m.setAccessible(true);
            telephonyService = (ITelephony) m.invoke(telephony);
            telephonyService.endCall();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Complete example github

BTW, ITelephony.aidl in your project isn't necessary, it is just a convenience, take a look at this answer.

whoopdedoo
  • 2,815
  • 23
  • 46
0

Since API 24 you can use the CallScreeningService: https://developer.android.com/reference/android/telecom/CallScreeningService Not sure how TrueCaller did that before Nougat.

o_weisman
  • 804
  • 7
  • 19