Midnight Guest
Midnight Guest

Reputation: 1860

End call in android programmatically

I see a lot of questions that it's impossible to end call programmatically in Android. At the same time, I see a lot of dialer apps in googleplay market where you can activate the call and drop it also. How do they work?

Edit: I've read somewhere that my app has to be system app. Then how to make it system, and what is the difference between system and user apps?

Upvotes: 37

Views: 53217

Answers (9)

firsttimer
firsttimer

Reputation: 1

You can end calls using Telecom manager. I tested it and it worked. You need permission ANSWER_PHONE_CALLS to do so. Even though it hints to answered calls I had it ending a call made from this phone. And this works for modern Androids.

   TelecomManager telecomManager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);

telecomManager.endCall();

Upvotes: -1

Beatle Refractor
Beatle Refractor

Reputation: 659

Cut Call for the Api 28+

private void cutCall(){
    ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_PHONE_STATE }, PHONE_STATE);
}

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
        if (requestCode == PHONE_STATE) {
            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ANSWER_PHONE_CALLS }, ANSWER_CALLS);
        } else if (requestCode == ANSWER_CALLS) {
            cutTheCall;
        }
    }
}

//This code will work on Android N (Api 28 and Above)

private boolean cutTheCall() {
    TelecomManager telecomManager = (TelecomManager) getApplicationContext().getSystemService(TELECOM_SERVICE);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED || telecomManager == null) {
        return false;
    }

    if (telecomManager.isInCall()) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            callDisconnected = telecomManager.endCall();
        }
    }
    return true;
}

Upvotes: 2

Christian Paul Gastardo
Christian Paul Gastardo

Reputation: 1261

Just to add to @headuck's answer. For API 28, you also need to add:

<uses-permission android:name="android.permission.READ_CALL_LOG"/>

then request the permission in your activity. In total I requested these permissions to make it work (READ_PHONE_STATE, CALL_PHONE, ANSWER_PHONE_CALLS, READ_CONTACTS, READ_CALL_LOG)

Upvotes: 0

SLock
SLock

Reputation: 31

For Information.

May be of use in some situations. There is a potential workaround using the InCallService class. Most of the required information is here.https://developer.android.com/reference/android/telecom/InCallService.html#onCallRemoved(android.telecom.Call)

It does require setting your app as the default phone app and ensuring the following is granted.

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

If you implement your own class extending InCallService then when a call starts the call binds to your app and you get the call information through the onCallAdded() function. You can then simply call.disconnect() and the call will end.

Upvotes: 3

headuck
headuck

Reputation: 2793

For Android P (since Beta 2) and above, there is finally a formal API for endCall:

https://developer.android.com/reference/android/telecom/TelecomManager#endCall()

The ANSWER_PHONE_CALLS permission is required in manifest:

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />

With the permission, for API level 28 or above:

TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);

if (tm != null) {
    boolean success = tm.endCall();
    // success == true if call was terminated.
}

At the same time the original endCall() method under TelephonyManager is now protected by MODIFY_PHONE_STATE permission, and can no longer be invoked by non-system Apps by reflection without the permission (otherwise a Security Exception will be triggered).

Upvotes: 23

bgse
bgse

Reputation: 8597

You do not need to be a system app. First, create package com.android.internal.telephony in your project, and put this in a file called "ITelephony.aidl":

package com.android.internal.telephony; 

interface ITelephony {      

boolean endCall();     

void answerRingingCall();      

void silenceRinger(); 

}

Once you have that, you can use this code to end a call:

TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
Class clazz = Class.forName(telephonyManager.getClass().getName());
Method method = clazz.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager);
telephonyService.endCall();

You could use this inside a PhoneStateListener, for example. For this to work, you require permissions in manifest:

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

Edit: Apologies for horrible formatting, I still can't figure out how to properly do code blocks here :/

Upvotes: 51

Mauricio Manoel
Mauricio Manoel

Reputation: 1

public static boolean isCallActive(Context context){
    AudioManager manager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    if(manager.getMode()==AudioManager.MODE_IN_CALL || manager.getMode()==AudioManager.MODE_IN_COMMUNICATION){
        return true;
    }

    return false;
}

Upvotes: 0

Vinayak Bhat
Vinayak Bhat

Reputation: 33

Along with Adding android telephony interface and a broadcast receiver, you will also need to add android manifest receiver entry with the action android.intent.action.PHONE_STATE for the reciever you want to handle intent.

You will get compile time error if you add

uses-permission android:name="android.permission.MODIFY_PHONE_STATE`

in your manifest file. But even if we remove this, it automatically rejects the incoming calls.

Upvotes: 1

Sameer Kulkarni
Sameer Kulkarni

Reputation: 51

SilenceRinger() does not work for android 2.3+ versions. Just comment it, other code will work fine. Hope this works for you!

Upvotes: 1

Related Questions