I have a working code that disconnects the calls on Android 4.4 (KitKat).
I use the technique of "service call phone 5" that was described at
How to programmatically answer/end a call in Android 4.1? and How can incoming calls be answered programmatically in Android 5.0 (Lollipop)?
But that code failed to disconnect the incoming call on 6.0. I have a background service that runs continously in the background and monitors a list of phone numbers and chose to automatically disconnect these numbers.
How can I programmatically disconnect the incoming calls on Nexus5 and Android version 6.0
Edit1
Complete code snippet is as follows
Executor eS = Executors.newSingleThreadExecutor();
eS.execute(new Runnable() {
@Override
public void run() {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("service call phone 5 \n");
} catch (Exception exc) {
Log.e("XX", exc.getMessage());
}
}
});
Following permissions are defined in Android.xml
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
EDIT2
I added one more permission
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
The class to detect incoming call extends from PhoneStateListener and I override the method
@Override
public void onCallStateChanged(int state, String incomingNumber) {
Log.e("XX","*************IncomingPhoneStateListener........"+state+" incoming no:"+incomingNumber);
Executor eS = Executors.newSingleThreadExecutor();
eS.execute(new Runnable() {
@Override
public void run() {
Runtime runtime = Runtime.getRuntime();
try {
Log.e("XX", "*DISCONNECTING THE CALL* \n" );
runtime.exec("service call phone 5 \n");
} catch (Exception exc) {
Log.e("XX", exc.getMessage());
}
}
});
}
From logcat, I notice output statements that I am printing from my above code (hence service is getting called), but my call never gets disconnected. I tested it on marshmallow (nexus 5).
EDIT3
I am targeting API 19 in AndroidManifest.xml.
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
EDIT4
Here is my current code base (modified sdkversion for now to get this whole thing working. I still didnt make any progress (same old problems)
Build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.XX.disconnectcall"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private IncomingPhoneStateListener phoneStateListener;
public static final int PERMISSION_REQUEST_CODE = 1001;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("TAG ","onCreate");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Log.e("TAG ","VERSION_CODES.M");
/* if (ContextCompat.checkSelfPermission(MainActivity.this,
Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED) {
*/
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.MODIFY_PHONE_STATE,Manifest
.permission.CALL_PHONE,Manifest.permission.PROCESS_OUTGOING_CALLS},
PERMISSION_REQUEST_CODE);
// }
} else {
phoneStateListener = new IncomingPhoneStateListener();
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onDestroy() {
super.onDestroy();
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.e("TAG ","onRequestPermissionsResult");
boolean permissionBoolean = true;
if (requestCode == PERMISSION_REQUEST_CODE) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
permissionBoolean = false;
}
}
if (permissionBoolean) {
phoneStateListener = new IncomingPhoneStateListener();
}
}
}
}
IncomingPhoneStateListener
public class IncomingPhoneStateListener extends PhoneStateListener {
int callState;
String callNumber;
public IncomingPhoneStateListener() {
super();
}
@Override
public void onCallStateChanged(int state, final String incomingNumber) {
callState = state;
callNumber = incomingNumber;
Log.e("TAG", "callState "+callState);
Executor eS = Executors.newSingleThreadExecutor();
eS.execute(new Runnable() {
@Override
public void run() {
Runtime runtime = Runtime.getRuntime();
try {
Log.e("TAG", "DISCONNECTING THE CALL From Number "+incomingNumber);
runtime.exec("service call phone 5 \n");
} catch (Exception exc) {
Log.e(" ", exc.getMessage());
}
}
});
}
}