我有一个工作代码可以断开 Android 4.4 (KitKat) 上的调用。
我使用了
中描述的“服务调用电话 5”技术
How to programmatically answer/end a call in Android 4.1?和 How can incoming calls be answered programmatically in Android 5.0 (Lollipop)?
但该代码无法断开 6.0 上的来电。我有一个在后台持续运行并监控电话号码列表并选择自动断开这些号码的后台服务。
如何以编程方式断开 Nexus5 和 Android 6.0 版的来电
编辑1
完整的代码 fragment 如下
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());
}
}
});
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
我又添加了一个权限
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
检测来电的类从 PhoneStateListener 扩展,我覆盖了该方法
@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());
}
}
});
}
在 logcat 中,我注意到我正在从上面的代码打印输出语句(因此调用了服务),但我的调用从未断开。我在 marshmallow (nexus 5) 上测试过它。
EDIT3
我的目标是 AndroidManifest.xml 中的 API 19。
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
EDIT4
这是我当前的代码库(现在修改了 sdkversion 以使整个工作正常。我仍然没有取得任何进展(同样的老问题)
构建.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'
}
主 Activity .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());
}
}
});
}
}
最佳答案
我搜索了文档,发现 MODIFY_PHONE_STATE 仅适用于系统应用程序。 Protected permissions .So atleast for detecting incoming call 你不需要这个。您应该在 list 中添加所有这些权限。
<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"/>
如果您在 Marshmallow 上工作,您也必须在运行时授予这些权限。像这样。把它放在 onCreate
/// granting permission ////
if(!checkPermission())
{
requestPermission();
}
/////////////////////////////
然后在类里面添加这些
/////////////////////// permission for marshmallow ///////////////////
private boolean checkPermission(){
int result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
int result3 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
int result4 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_INCOMING_CALLS);
int result5 = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
if (result1 == PackageManager.PERMISSION_GRANTED && result3 == PackageManager.PERMISSION_GRANTED && result4 == PackageManager.PERMISSION_GRANTED
&& result5 == PackageManager.PERMISSION_GRANTED){
return true;
} else {
//Toast.makeText(this,"You don't have permission to use further features",Toast.LENGTH_LONG).show();
return false;
}
}
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_OUTGOING_CALLS) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_INCOMING_CALLS) &&
ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)){
Toast.makeText(this,"Application needs permission to use your camera, calls, storage and location.",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(this,new String[{Manifest.permission.READ_PHONE_STATE,Manifest.permission.PROCESS_OUTGOING_CALLS,
Manifest.permission.PROCESS_INCOMING_CALLS, Manifest.permission.CALL_PHONE},1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED &&
grantResults[2] == PackageManager.PERMISSION_GRANTED &&
grantResults[3] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this,"Permission Granted.",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this,"Permission Denied.",Toast.LENGTH_LONG).show();
}
break;
}
}
////////////////////////////////////////////////////////////////////////
关于Android:如何在 Android 5.0+ 至 6.0 上阻止(或断开连接)调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38211762/