简体   繁体   English

android.permission.ANSWER_PHONE_CALLS 如何使用? 用于自动应答

[英]android.permission.ANSWER_PHONE_CALLS How I can use? for auto answer

As per android developer documentation根据android 开发人员文档

Android 8.0 (API level 26) introduces several new permissions related to telephony: The ANSWER_PHONE_CALLS permission allows your app to answer incoming phone calls programmatically. Android 8.0(API 级别 26)引入了几个与电话相关的新权限: ANSWER_PHONE_CALLS 权限允许您的应用以编程方式接听来电。 To handle an incoming phone call in your app, you can use the acceptRingingCall() method.要在您的应用中处理来电,您可以使用 acceptRingingCall() 方法。

How my app give voice answer to incoming call ?我的应用程序如何对来电进行语音应答?

but I have not found any guide or examples about of this .但我还没有找到任何关于此的指南或示例。 so所以

I want automatic answer with voice(from raw folder in app) (I have need guide or example code like answering machine)我想要语音自动应答(来自应用程序中的原始文件夹)(我需要指南或示例代码,如答录机)

Updates from Google :来自谷歌的更新:

telecomManager.acceptRingingCall();
telecomManager.acceptRingingCall(false);
telecomManager.endCall();

All these three commands are deprecated on and from Android Q所有这三个命令在 Android Q 上和从 Android Q 都已弃用

click to verify here 点击此处验证

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

Acccept Answer call is deprecated API LEVEL Q不推荐使用接受应答调用 API LEVEL Q

在此处输入图片说明

try {
                    Toast.makeText(CallAnswerDialog.this, "btn_answer click", Toast.LENGTH_SHORT).show();

                    TelecomManager tm = (TelecomManager) CallAnswerDialog.this.getSystemService(Context.TELECOM_SERVICE);
                    if (tm == null) {
                        // whether you want to handle this is up to you really
                        throw new NullPointerException("tm == null");
                    }
                    tm.acceptRingingCall();   // is deprecated Now API Level Q
                    btn_answer.setVisibility(View.GONE);
                }catch (Exception e){
                    e.printStackTrace(); }

For answering a phone call, this is available only from Android O. Before, it might not work.对于接听电话,此功能仅在 Android O 上可用。以前,它可能不起作用。 Here's a code for it:这是它的代码:

/**returns true iff we are sure that answering the phone call worked*/
fun answerCall(context: Context): Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(context, Manifest.permission.MODIFY_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.acceptRingingCall()
            return true
        }
        return false
    }
    // https://stackoverflow.com/a/29651130/878126
    // for HTC devices we need to broadcast a connected headset
    val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    val broadcastConnected = "htc" == Build.MANUFACTURER.toLowerCase(Locale.US) && !audioManager.isWiredHeadsetOn
    if (broadcastConnected)
        broadcastHeadsetConnected(context, false)
    try {
        try {
            Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK))
        } catch (e: IOException) {
            // Runtime.exec(String) had an I/O problem, try to fall back
            val enforcedPerm = "android.permission.CALL_PRIVILEGED"
            val btnDown = Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(Intent.EXTRA_KEY_EVENT, KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK))
            val btnUp = Intent(Intent.ACTION_MEDIA_BUTTON).putExtra(Intent.EXTRA_KEY_EVENT, KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK))
            context.sendOrderedBroadcast(btnDown, enforcedPerm)
            context.sendOrderedBroadcast(btnUp, enforcedPerm)
        }
    } finally {
        if (broadcastConnected)
            broadcastHeadsetConnected(context, false)
    }
    return false
}

For hanging up a call, this was added officially on Android P, but the workaround seems to work on most cases I've tried so far (doesn't work on Nexus 5x with Android 8.1, for example) .对于挂断电话,这是在 Android P 上正式添加的,但该解决方法似乎适用于我迄今为止尝试过的大多数情况(例如,不适用于带有 Android 8.1 的 Nexus 5x)。 Here's code for this :这是代码:

@SuppressLint("PrivateApi")
fun endCall(context: Context): Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
        if (telecomManager != null && ContextCompat.checkSelfPermission(context, Manifest.permission.ANSWER_PHONE_CALLS) == PackageManager.PERMISSION_GRANTED) {
            telecomManager.endCall()
            return true
        }
        return false
    }
    //use unofficial API for older Android versions, as written here: https://stackoverflow.com/a/8380418/878126
    try {
        val telephonyClass = Class.forName("com.android.internal.telephony.ITelephony")
        val telephonyStubClass = telephonyClass.classes[0]
        val serviceManagerClass = Class.forName("android.os.ServiceManager")
        val serviceManagerNativeClass = Class.forName("android.os.ServiceManagerNative")
        val getService = serviceManagerClass.getMethod("getService", String::class.java)
        val tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder::class.java)
        val tmpBinder = Binder()
        tmpBinder.attachInterface(null, "fake")
        val serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder)
        val retbinder = getService.invoke(serviceManagerObject, "phone") as IBinder
        val serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder::class.java)
        val telephonyObject = serviceMethod.invoke(null, retbinder)
        val telephonyEndCall = telephonyClass.getMethod("endCall")
        telephonyEndCall.invoke(telephonyObject)
        return false
    } catch (e: Exception) {
        e.printStackTrace()
        return false
    }
}

So, for both answering and rejecting calls, the safest way to do it, is to have it run on Android P... :(因此,对于接听和拒接电话,最安全的方法是让它在 Android P 上运行... :(

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM