繁体   English   中英

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

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

根据android 开发人员文档

Android 8.0(API 级别 26)引入了几个与电话相关的新权限: ANSWER_PHONE_CALLS 权限允许您的应用以编程方式接听来电。 要在您的应用中处理来电,您可以使用 acceptRingingCall() 方法。

我的应用程序如何对来电进行语音应答?

但我还没有找到任何关于此的指南或示例。 所以

我想要语音自动应答(来自应用程序中的原始文件夹)(我需要指南或示例代码,如答录机)

来自谷歌的更新:

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

所有这三个命令在 Android Q 上和从 Android Q 都已弃用

点击此处验证

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

不推荐使用接受应答调用 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(); }

对于接听电话,此功能仅在 Android O 上可用。以前,它可能不起作用。 这是它的代码:

/**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
}

对于挂断电话,这是在 Android P 上正式添加的,但该解决方法似乎适用于我迄今为止尝试过的大多数情况(例如,不适用于带有 Android 8.1 的 Nexus 5x)。 这是代码:

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

因此,对于接听和拒接电话,最安全的方法是让它在 Android P 上运行... :(

暂无
暂无

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

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