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

以编程方式结束android中的调用,android,phone-call,Android,Phone Call,我看到很多问题,在Android中不可能以编程方式结束调用。 与此同时,我在Google Play market上看到了很多拨号应用程序,在那里你可以激活电话,也可以挂断电话。它们是如何工作的 编辑:我在某个地方读到,我的应用程序必须是系统应用程序。那么,如何使it系统化,以及系统应用程序和用户应用程序之间的区别是什么?您不需要成为系统应用程序。首先,在项目中创建包com.android.internal.telephony,并将其放入名为“ITelephony.aidl”的文件中: 一旦您拥有

我看到很多问题,在Android中不可能以编程方式结束调用。 与此同时,我在Google Play market上看到了很多拨号应用程序,在那里你可以激活电话,也可以挂断电话。它们是如何工作的


编辑:我在某个地方读到,我的应用程序必须是系统应用程序。那么,如何使it系统化,以及系统应用程序和用户应用程序之间的区别是什么?

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

一旦您拥有该功能,您可以使用以下代码结束通话:

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

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

编辑:为糟糕的格式道歉,我仍然不知道如何正确地在这里执行代码块:/

消音器(
不适用于android 2.3+版本。只要注释一下,其他代码就可以了。
希望这对你有用

除了添加android电话接口和广播接收器外,您还需要为想要处理intent的接收者添加带有action
android.intent.action.PHONE_STATE
的android清单接收器条目

如果添加

uses-permission android:name="android.permission.MODIFY_PHONE_STATE`
在您的清单文件中。但是,即使我们删除它,它也会自动拒绝传入呼叫。

对于Android p(自Beta 2版起)及更高版本,最终有一个正式的endCall API:

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

清单中需要
接听电话
权限:

<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
同时,
TelephonyManager
下的原始
endCall()
方法现在受到
MODIFY\u PHONE\u STATE
权限的保护,并且在没有权限的情况下,非系统应用程序不能再通过反射调用该方法(否则将触发安全异常)。

了解更多信息

在某些情况下可能有用。使用
InCallService
类有一个潜在的解决方法。大部分必需的信息都在这里

它确实需要将您的应用程序设置为默认手机应用程序,并确保授予以下权限

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


如果您实现了自己的类扩展
InCallService
,那么当调用启动时,调用将绑定到您的应用程序,您可以通过
onCallAdded()
函数获得调用信息。然后,您只需调用.disconnect(),调用就会结束。

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

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


然后在活动中请求权限。总的来说,我请求了这些权限以使其正常工作(读取电话状态、呼叫电话、接听电话、读取联系人、读取呼叫日志)

切断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;
        }
    }
}
//此代码将在安卓N(Api 28及以上)上运行


无法使用,并且没有上述权限,您无法在运行时访问TelephonyManager。@我记得在调试时在logcat中收到了一条类似“不授予权限”“修改电话状态”的警告,但这似乎不是问题,因为上述代码在各种设备上都能正常工作。也许许可不是必需的?@MAHANTESH此特定项目是使用minSdkVersion=“8”和targetSdkVersion=“15”构建的。我只是重新检查确认,它确实编译和部署没有任何问题。当应用程序被执行时,它会在logcat中发出警告“不授予权限修改手机状态”。不过,这似乎不会以任何方式影响功能,所以我猜实际上并不需要权限。您是在编译时还是在运行时收到错误?这仅在minSdkVersion为14或更低时有效。如果您将minSdkVersion设置为15或更高,它将停止工作。@WijaySharma此代码在2013年使用过,它基本上是用来访问android telephony的内部功能的,否则它不会公开。自2013年以来,许多内部结构都发生了变化,因此这几乎可以保证不再起作用(至少很可能不会以本文所示的方式),从我的角度来看,我认为安卓4.0.3仍在发挥作用,但不确定以后的版本。对于我来说,有更好的[Solutionion][1]来实现这一点。[1] :有关如何使应用程序成为系统应用程序的说明,请参阅。请检查此答案以避免编译或任何其他错误。您提供了非常有用的信息,但如何在Oreo中处理此问题?因为我没有得到endcall方法。@Panache请查看Oreo的已接受答案,或者在关于访问TelephonyManager中隐藏的endcall方法之前。我得到无法解析endcall方法,我确实安装了API 28,有什么提示吗?@David您是否在
build.gradle
中将
compileSdkVersion
设置为28?它在API级别29中已被正式弃用。重要提示:要使用iCalService,您需要从设置中将应用设置为默认手机应用。这意味着,当你有来电时,其他应用程序将无法控制,你必须处理应用程序中的所有呼叫功能。此代码需要api 26及以上版本。确保在您的清单中添加:项。
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
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;
        }
    }
}
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;
}