Monday, May 12, 2014

Disconnect Block Drop calls Android 4 and above

The internet is littered with forum posts and articles that would tell you it is impossible to block drop disconnect an incoming or outgoing call using code starting Android version 4 Jelly Bean, because Google placed strict restrictions on MODIFY_PHONE_STATE permission. Only the manufacturer signing certificate can grant you MODIFY_PHONE_STATE permission.
block drop disconnect call android

There are a lot of call blocker type of scenarios in which we need to shield our user from a bad guy's or sour ex girl friend's telephone calls.
The good news is, you don't need to MODIFY_PHONE_STATE permission to block drop disconnect an incoming call on Google Android . The technique described here is available to drop block disconnect incoming calls without using the secretive infamous permission.

Time to disclose the secret sauce, a hint first:
Ever tried to dial a call using ADB(Android Debugger Bridge) shell?

If you've done that, it is going to be very simple to disconnect or drop a call using a similar technique.
Time to spill the secret sauce, on the internet.

Drop call on Android 4 Jelly Bean KitKat and above

The exact Java code to drop disconnect or reject an incoming call or an outgoing call on an Android 4 and above system is given below:

I'm working as a freelance programmer through, you may hire me thorough following link:

public int disconnectCallAndroid()
 Runtime runtime = Runtime.getRuntime();
 int nResp = 0;  
  Log.d(Keys.LOGTAG, "service call phone 5 \n");
  runtime.exec("service call phone 5 \n");   
 }catch(Exception exc)
  Log.e(Keys.LOGTAG, exc.getMessage());
 return nResp;

A reader has complained that the technique described here works through ADB Shell on their Nexus S Android smart phone but it does nothing when tried through code.
The app in which I'm using this code is basically taking input over UDP/Bluetooth Sockets and performing disconnect call action in an IntentService. Please note that IntentService is running separately in its own thread.
From Android version 4 Jelly Bean which is API level 14 Android blocks user apps to perform lengthy operations on the UI thread. In that case, you can use a SingleThreadExecutor and spin off a new thread to initiate run time in order to perform call disconnect/drop/block operation. Sample code is given below.

Executor eS = Executors.newSingleThreadExecutor();
eS.execute(new Runnable() {
 public void run() {
});// code formatting with

Wait a minute, what about the permissions required to do this?
Well following Android permissions are needed to mess with calls:

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

The disconnectCallAndroid method will effectively disconnect a telephone call in following states:
  1. Incoming call, which is in ringing state
  2. Outgoing call, which might be ringing on the other end or not
  3. Connected call, while you're talking be it dialled by you or the other party
Nothing will happen if an active call in any of the aforementioned states does not exist on the phone.
I have tested my code on an Android 4.1.3 smart phone QMobile A50.
Update: I tested the call disconnect/reject/drop/cut on a friend's LG G2 which has got Android KitKat 4.4 installed, and it worked like a charm.
Update: A friend tested the call disconnect/reject/drop/cut on a friend's Samsung Galaxy S 4 (SGS 4) which ahas got Android KitKat 4.4 installed, call disconnect worked on it as well ;)

Call disconnect technique is tested on following Android devices/versions

  1. Samsung Galaxy S4 Android KitKat Version 4.2.2
  2. LG G2 Android KitKat 4.4
  3. Sony Xperia Z Android 4.3 KitKat
  4. Q Mobilie A 50 Android 4.1 Jelly Bean
  5. Nexus 5 Android 4.4.2
  6. LG Optimus 4G LTE Tag Android 2.2 Froyo
  7. Samsung Galaxy S3 Android 4.3 (Contributed by user Said Dami)
  8. Samsung STARS Android 4.1 (Contributed by user Said Dami)

Older versions of Android

The commands slightly different on older versions of Android.
In order to disconnect reject drop call I had to use 8 in place of 4 on an Android 2.2 smart phone and the command became

runtime.exec("service call phone 8 \n");

Ain't that very simple? I hope the blog post is going to help a lot of troubled Android coders.

Be careful

The magic number 4 and 8 can be changed in any version of Android without a notice, you'll only wake up when your clients will come crying to you and tell that "Mommy the app is broken".

Please feel free to check my profile on Elance and ODesk, Elance widget is given on top right of the page.

I'm working as a freelance programmer through, you may hire me thorough following link:


  1. I have tried this in a Nexus 5 and is not doing anything, i tried 4, 5 and 8 with no luck.
    where can i find more info about this ?

  2. Which Android version is running on your Nexus 5? Did you specify the appropriate permissions in manifest.xml?
    The magic numbers are subject to change without prior notice, these are defined in An example can be seen here
    A quick hack is to connect to your device through adb shell and execute the service call phone command with various options. Make sure a call is in ringing, dialling, or connected state before running the command otherwise you won't know if it dropped something or not. I actually discovered that disconnecting a call was possible by hit and try :)

  3. @Jorge I hope you will figure out the correct number some time soon, please let me know if it worked for you. For developer community this will be a very useful information, I will like to add your device/Android version into the list of tested devices. Thank you.

  4. it does work if i do the adb shell command, but it doesn't work when i do it trough code :S

  5. That's nasty, maybe you could perform the operation in a separate thread because Android OS 4+ does not allow certain long running tasks on the UI thread.
    One more thing, please tell the model of your phone and the Android OS version your are running I want to put it in the list of devices where this code is tested and working.

  6. I've updated the post, please give it a try.

  7. Let me test it and ill let you know the result, by the way i am using a Nexus 5 with 4.4.2 OS

  8. Hello Akram

    I am struggling with this. Maybe you can please help me. I am trying to capture the incoming call and compare it with my database (that I have created of phone numbers) and take some action. I am implementing a broadcast receiver and phonestatelistener but when I keep the database access code in the call_state_ringing case, it is not working. But when I hard code the comparison of incoming number with some number in a IF statement it works. How to access database and compare the incoming number and take some action please?

  9. Hi Anonymous :)
    Try debugging your stuff, maybe there's a string mismatch or something. I am putting together a post which describes a phone state listener, I hope it will help you.

  10. Hey Thanks so much. I didn't mean to put it as anonymous. I am Mac here. I thought anonymous means without using email. I didn't want to use email ID because sometimes it tries to extract my email IDs in account. I got the smirk on your face :)

    I heard that the phonestatelistener doesn't let us put code directly but to use a service or an intent service. Didn't know how to do it. All I am asking is: after I find the state (for example: call_state_ringing), I need to be able to run a code (for example: a database access and then compare the incoming number) either directly or as a service or as an intent service. I hope your post which you mentioned address that. Thanks once again.

  11. Hey Mac! I've published the post, it does not handle the intent service stuff but that is fairly simple. First, please try the phone state listener which is given in a blog post along with full code and explanation.

  12. You may use executor service like this:
    Executor eS = Executors.newSingleThreadExecutor();
    eS.execute(new Runnable() {
    public void run() {
    });// code formatting with

  13. Here is what I have:Please ignore syntax. I can take care of that.

    public class PhoneCallReceiver extends BroadcastReceiver {
    SQLiteDatabase db1 = null;
    blah blah blah ...

    public void onCallStateChanged(int state, String incomingNumber) {
    super.onCallStateChanged(state, incomingNumber);

    switch (state) {
    case TelephonyManager.CALL_STATE_RINGING:

    Create a table if not exists and

    Read field mobileno array from database;

    if (mobileno contains incomingNumber) {

    Do Something;


  14. Did you try to run you code in debug mode? And do use Log.d method call to print various information about the internals of your logic. I don't see anything wrong with your logic, maybe you should put this same stuff in a separate thread as Android OS does not like lengthy operations such as database and http reads in UI threads and broadcast receivers as well.

  15. Excellent my friend. I will try all that you said and update you. Thank you. Mac

  16. It is simply not letting me add the DB within the PhoneStateListener class nor letting me add a service. When I say startService(Intent) it keeps saying create a method for startService. I am almost giving up :) - Mac

  17. context.Startservice() will work here, BTW I can look into your code and make it work for sure.

  18. Assalam-o-Alaikum Naeem Akram ! can u plz send me a complete project because i don't know how to i use your code OR how to i block specific number through this code ?
    Muhammad Faisal

  19. Faisal, Walekum Salam. If you combine the post about CLI and PhoneStateReceiver along with this one, you can easily figure out how to block calls from selective telephone numbers. Link below

    I am thinking to make my project "Best Call Blocker" open source and make it a public repo on GitHub, in case I do that I will post the news on this blog and then you could take a look.

  20. Help me please. I'm using this command: runtime.exec("service call phone 8 \n"), using Samsung Galaxy with Android 2.3 but not working.
    runtime.exec("service call phone 5 \n"), run fine using a Chinese phone with Android 4.2.

  21. Try a different number, I had a rooted phone and I granted SU permissions to the ADB shell process then I started from number 1 and went up to 23. In your case maybe you could create a simple activity with a text box and button and get the value of text box on button click to replace it with "service call phone %s\n".
    Different Android versions work with different numbers. :)

  22. Before doing that. Does anyone have a list of numbers and versions?. I would save some work.

  23. Don't be lazy Anonymous... Move some rocks by yourself, maybe you will find something unexpected and wonderful...

  24. ok. let's go. thanks.

  25. thanks!!!that's work on S3 android 4.3 AND samsng STARS android 4.1

  26. That's wonderful Said Dami, I will add these devices to the supported list as well.
    Thank you very much for the comment.

  27. Magic number for my SGS2 with Android 4.3 (cyanogenmod) is 6. Unfortunately, "service call phone 6" picks up the call in Android 4.4 AVD :(.

  28. Yet another cool piece of information! Thanks a lot for sharing, I will upgrade main article with this information some time. This is certainly not a very good technique, but unfortunately its the only way to disconnect a call discovered so far(for me at least). Keep up the good work...

  29. Finally got it working with your latest update.
    nexus 5 4.4.4

  30. That's a very good news... This technique works but unfortunately it is far from perfect... Still, I'm glad at least some people are benefiting :)

  31. Hi, Naeem!
    Your solution works! But how to remove the missed call notification?


Feel free to talk back...