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