Here's the most updated code, which will work for Android P too, because it has an official API for it (here) :
in manifest, add this:
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>
In code, use this:
Java:
@SuppressLint("PrivateApi")
public static boolean endCall(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        final TelecomManager telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
        if (telecomManager != null && ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.endCall();
            return true;
        }
        return false;
    }
    //use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
    try {
        final Class<?> telephonyClass = Class.forName("com.android.internal.telephony.ITelephony");
        final Class<?> telephonyStubClass = telephonyClass.getClasses()[0];
        final Class<?> serviceManagerClass = Class.forName("android.os.ServiceManager");
        final Class<?> serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative");
        final Method getService = serviceManagerClass.getMethod("getService", String.class);
        final Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
        final Binder tmpBinder = new Binder();
        tmpBinder.attachInterface(null, "fake");
        final Object serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
        final IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
        final Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
        final Object telephonyObject = serviceMethod.invoke(null, retbinder);
        final Method telephonyEndCall = telephonyClass.getMethod("endCall");
        telephonyEndCall.invoke(telephonyObject);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        LogManager.e(e);
    }
    return false;
}
or in Kotlin:
@SuppressLint("PrivateApi")
fun endCall(context: Context): Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.endCall()
            return true
        }
        return false
    }
    //use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
    try {
        val telephonyClass = Class.forName("com.android.internal.telephony.ITelephony")
        val telephonyStubClass = telephonyClass.classes[0]
        val serviceManagerClass = Class.forName("android.os.ServiceManager")
        val serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative")
        val getService = serviceManagerClass.getMethod("getService", String::class.java)
        val tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder::class.java)
        val tmpBinder = Binder()
        tmpBinder.attachInterface(null, "fake")
        val serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder)
        val retbinder = getService.invoke(serviceManagerObject, "phone") as IBinder
        val serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder::class.java)
        val telephonyObject = serviceMethod.invoke(null, retbinder)
        val telephonyEndCall = telephonyClass.getMethod("endCall")
        telephonyEndCall.invoke(telephonyObject)
        return true
    } catch (e: Exception) {
        e.printStackTrace()
        return false
    }
}