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

2019-07-30  本文已影响0人  Soul1010

接听来电


    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的手机的接听来电要依赖通知使用权,所以通知使用权打开才可以正常工作。

上一篇下一篇

猜你喜欢

热点阅读