以编程方式在android中结束调用

时间:2013-08-05 18:28:23

标签: android phone-call

我看到很多问题,在Android中以编程方式结束调用是不可能的。 与此同时,我在googleplay市场上看到很多拨号应用,你可以在其中激活呼叫并将其丢弃。他们是如何运作的?

编辑:我在某处读过我的应用必须是系统应用。那么如何制作系统,以及系统和用户应用程序之间有什么区别?

8 个答案:

答案 0 :(得分:44)

您不需要是系统应用程序。首先,在项目中创建包com.android.internal.telephony,并将其放在名为" ITelephony.aidl"的文件中:

package com.android.internal.telephony; 

interface ITelephony {      

boolean endCall();     

void answerRingingCall();      

void silenceRinger(); 

}

完成后,您可以使用此代码结束通话:

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();

例如,您可以在PhoneStateListener中使用它。为此,您需要清单中的权限:

<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" />

编辑:为可怕的格式化道歉,我仍然无法弄清楚如何在这里正确执行代码块:/

答案 1 :(得分:9)

对于Android P(自Beta 2开始)及以上版本,最终有一个正式的endCall API:

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

清单中需要ANSWER_PHONE_CALLS权限:

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

获得API级别28或以上的许可:

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

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

同时,endCall()下的原始TelephonyManager方法现在受MODIFY_PHONE_STATE权限保护,未经许可不得再通过反映由非系统应用调用(否则将触发安全例外。)

答案 2 :(得分:1)

除了添加Android电话接口和广播接收器之外,您还需要为要处理意图的接收者添加动作android.intent.action.PHONE_STATE的android清单接收器条目。

如果添加

,将出现编译时错误
uses-permission android:name="android.permission.MODIFY_PHONE_STATE`
清单文件中的

。但即使我们删除它,它也会自动拒绝来电。

答案 3 :(得分:1)

有关信息。

在某些情况下可能有用。使用InCallService类有可能的解决方法。大多数必需的信息都在这里。https://developer.android.com/reference/android/telecom/InCallService.html#onCallRemoved(android.telecom.Call)

这确实需要将您的应用设置为默认电话应用,并确保已批准以下内容。

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

如果实现自己的扩展InCallService的类,则当呼叫开始时,呼叫将绑定到您的应用程序,并且您将通过onCallAdded()函数获得呼叫信息。然后,您只需call.disconnect(),通话就会结束。

答案 4 :(得分:1)

切断对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;
        }
    }
}

//此代码将在Android N(Api 28及更高版本)上运行

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;
}

答案 5 :(得分:0)

SilenceRinger()不适用于Android 2.3+版本。只需评论它,其他代码将正常工作。 希望这对你有用!

答案 6 :(得分:0)

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;
}

答案 7 :(得分:0)

只需添加到@headuck的答案中即可。对于API 28,您还需要添加:

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

然后在您的活动中请求许可。我总共要求这些权限以使其正常运行(READ_PHONE_STATE,CALL_PHONE,ANSWER_PHONE_CALLS,READ_CONTACTS,READ_CALL_LOG)