美文网首页
Android程序接听及挂断电话,适配所有Android版本

Android程序接听及挂断电话,适配所有Android版本

作者: Soul1010 | 来源:发表于2019-07-30 18:19 被阅读0次

    接听来电

    
        fun acceptCall(context: Context) {
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager?
                    telecomManager?.acceptRingingCall()
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                    val mediaSessionManager = context.getSystemService(Context.MEDIA_SESSION_SERVICE) as MediaSessionManager
                    val mediaControllerList = mediaSessionManager.getActiveSessions(ComponentName(context, ListenerService::class.java))
                    for (m in mediaControllerList) {
                        if ("com.android.server.telecom" == m.packageName) {
                            m.dispatchMediaButtonEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK))
                            m.dispatchMediaButtonEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK))
                            break
                        }
                    }
                } else {
                    val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager?
                    val eventDown = KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK)
                    val eventUp = KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK)
                    audioManager?.dispatchMediaKeyEvent(eventDown)
                    audioManager?.dispatchMediaKeyEvent(eventUp)
                    Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK))
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
    

    拒接来电:

        fun rejectCall(context: Context) {
            if (Build.VERSION.SDK_INT >= 28) {
                val telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager?
                telecomManager?.endCall()
            } else {
                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)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    
    

    其中文中的接听电话android6-android7的处理方案是利用了监听通知使用权,所以还要新建一个NotificationListenerService的子类,叫ListenerService,需要在AndroidManifests中配置

            <service
                android:name="ListenerService所在路径"
                android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
                <intent-filter>
                    <action android:name="android.service.notification.NotificationListenerService"/>
                </intent-filter>
            </service>
    

    另外需要提示用户打开通知使用权才可以正常使用

    startActivity(new Intent(
            "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"));
    

    已测试通过了android6-android9各种机型,注意拒接来电在android9以上才有官方支持,所以需要设置compileSdkVersion=28。

    需要的权限为:Manifest.permission.CALL_PHONE,Manifest.permission.READ_PHONE_STATE

    8.0以上需要Manifest.permission.ANSWER_PHONE_CALLS,Manifest.permission.READ_CALL_LOG。

    还不行的请注意三点:
    1:检查权限是否都申请及在manifests里注册了
    2:compileSdkVersion是否为28
    3:android6到android7的手机的接听来电要依赖通知使用权,所以通知使用权打开才可以正常工作。

    相关文章

      网友评论

          本文标题:Android程序接听及挂断电话,适配所有Android版本

          本文链接:https://www.haomeiwen.com/subject/dpcorctx.html