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

后端 未结 3 1442
没有蜡笔的小新
没有蜡笔的小新 2021-01-07 04:59

As per android developer documentation

Android 8.0 (API level 26) introduces several new permissions related to telephony: The ANSWER_PHONE_CALLS p

相关标签:
3条回答
  • 2021-01-07 05:40

    Updates from Google :

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

    All these three commands are deprecated on and from Android Q

    click to verify here

    0 讨论(0)
  • 2021-01-07 05:44

    For answering a phone call, this is available only from Android O. Before, it might not work. 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) . 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... :(

    0 讨论(0)
  • 2021-01-07 05:56

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

    Acccept Answer call is deprecated 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(); }
    
    0 讨论(0)
提交回复
热议问题