Using TelephonyListener instead of PhoneStateListener that has been deprecated starting API 31
This commit is contained in:
parent
e65957f047
commit
2f912828ee
5 changed files with 194 additions and 33 deletions
|
@ -26,6 +26,7 @@ import android.content.pm.PackageManager
|
|||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Vibrator
|
||||
import android.telephony.TelephonyManager
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
|
@ -50,6 +51,14 @@ class Compatibility {
|
|||
}
|
||||
}
|
||||
|
||||
fun createPhoneListener(telephonyManager: TelephonyManager): PhoneStateInterface {
|
||||
return if (Version.sdkStrictlyBelow(Version.API31_ANDROID_12)) {
|
||||
PhoneStateListener(telephonyManager)
|
||||
} else {
|
||||
TelephonyListener(telephonyManager)
|
||||
}
|
||||
}
|
||||
|
||||
/* UI */
|
||||
|
||||
fun setShowWhenLocked(activity: Activity, enable: Boolean) {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.compatibility
|
||||
|
||||
interface PhoneStateInterface {
|
||||
fun destroy()
|
||||
|
||||
fun isInCall(): Boolean
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.compatibility
|
||||
|
||||
import android.telephony.PhoneStateListener
|
||||
import android.telephony.TelephonyManager
|
||||
import org.linphone.core.tools.Log
|
||||
|
||||
class PhoneStateListener(private val telephonyManager: TelephonyManager) : PhoneStateInterface {
|
||||
private var gsmCallActive = false
|
||||
private val phoneStateListener = object : PhoneStateListener() {
|
||||
override fun onCallStateChanged(state: Int, phoneNumber: String?) {
|
||||
gsmCallActive = when (state) {
|
||||
TelephonyManager.CALL_STATE_OFFHOOK -> {
|
||||
Log.i("[Context] Phone state is off hook")
|
||||
true
|
||||
}
|
||||
TelephonyManager.CALL_STATE_RINGING -> {
|
||||
Log.i("[Context] Phone state is ringing")
|
||||
true
|
||||
}
|
||||
TelephonyManager.CALL_STATE_IDLE -> {
|
||||
Log.i("[Context] Phone state is idle")
|
||||
false
|
||||
}
|
||||
else -> {
|
||||
Log.w("[Context] Phone state is unexpected: $state")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
Log.i("[Phone State Listener] Registering phone state listener")
|
||||
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
|
||||
}
|
||||
|
||||
override fun destroy() {
|
||||
Log.i("[Phone State Listener] Unregistering phone state listener")
|
||||
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
|
||||
}
|
||||
|
||||
override fun isInCall(): Boolean {
|
||||
return gsmCallActive
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2021 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-android
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.linphone.compatibility
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.telephony.TelephonyCallback
|
||||
import android.telephony.TelephonyManager
|
||||
import java.util.concurrent.Executor
|
||||
import org.linphone.core.tools.Log
|
||||
|
||||
@TargetApi(31)
|
||||
class TelephonyListener(private val telephonyManager: TelephonyManager) : PhoneStateInterface {
|
||||
private var gsmCallActive = false
|
||||
|
||||
private fun runOnUiThreadExecutor(): Executor {
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
return Executor() {
|
||||
handler.post(it)
|
||||
}
|
||||
}
|
||||
|
||||
inner class TelephonyListener : TelephonyCallback(), TelephonyCallback.CallStateListener {
|
||||
override fun onCallStateChanged(state: Int) {
|
||||
gsmCallActive = when (state) {
|
||||
TelephonyManager.CALL_STATE_OFFHOOK -> {
|
||||
Log.i("[Context] Phone state is off hook")
|
||||
true
|
||||
}
|
||||
TelephonyManager.CALL_STATE_RINGING -> {
|
||||
Log.i("[Context] Phone state is ringing")
|
||||
true
|
||||
}
|
||||
TelephonyManager.CALL_STATE_IDLE -> {
|
||||
Log.i("[Context] Phone state is idle")
|
||||
false
|
||||
}
|
||||
else -> {
|
||||
Log.w("[Context] Phone state is unexpected: $state")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private val telephonyListener = TelephonyListener()
|
||||
|
||||
init {
|
||||
Log.i("[Telephony Listener] Registering telephony callback")
|
||||
telephonyManager.registerTelephonyCallback(runOnUiThreadExecutor(), telephonyListener)
|
||||
}
|
||||
|
||||
override fun destroy() {
|
||||
Log.i("[Telephony Listener] Unregistering telephony callback")
|
||||
telephonyManager.unregisterTelephonyCallback(telephonyListener)
|
||||
}
|
||||
|
||||
override fun isInCall(): Boolean {
|
||||
return gsmCallActive
|
||||
}
|
||||
}
|
|
@ -27,7 +27,6 @@ import android.os.Handler
|
|||
import android.os.Looper
|
||||
import android.security.keystore.KeyGenParameterSpec
|
||||
import android.security.keystore.KeyProperties
|
||||
import android.telephony.PhoneStateListener
|
||||
import android.telephony.TelephonyManager
|
||||
import android.util.Base64
|
||||
import android.util.Pair
|
||||
|
@ -56,6 +55,7 @@ import org.linphone.activities.call.CallActivity
|
|||
import org.linphone.activities.call.IncomingCallActivity
|
||||
import org.linphone.activities.call.OutgoingCallActivity
|
||||
import org.linphone.compatibility.Compatibility
|
||||
import org.linphone.compatibility.PhoneStateInterface
|
||||
import org.linphone.contact.Contact
|
||||
import org.linphone.contact.ContactsManager
|
||||
import org.linphone.core.tools.Log
|
||||
|
@ -99,37 +99,13 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
}
|
||||
|
||||
private val loggingService = Factory.instance().loggingService
|
||||
|
||||
private val coroutineScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
|
||||
|
||||
private var gsmCallActive = false
|
||||
private val phoneStateListener = object : PhoneStateListener() {
|
||||
override fun onCallStateChanged(state: Int, phoneNumber: String?) {
|
||||
gsmCallActive = when (state) {
|
||||
TelephonyManager.CALL_STATE_OFFHOOK -> {
|
||||
Log.i("[Context] Phone state is off hook")
|
||||
true
|
||||
}
|
||||
TelephonyManager.CALL_STATE_RINGING -> {
|
||||
Log.i("[Context] Phone state is ringing")
|
||||
true
|
||||
}
|
||||
TelephonyManager.CALL_STATE_IDLE -> {
|
||||
Log.i("[Context] Phone state is idle")
|
||||
false
|
||||
}
|
||||
else -> {
|
||||
Log.w("[Context] Phone state is unexpected: $state")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var overlayX = 0f
|
||||
private var overlayY = 0f
|
||||
private var callOverlay: View? = null
|
||||
private var previousCallState = Call.State.Idle
|
||||
private lateinit var phoneStateListener: PhoneStateInterface
|
||||
|
||||
private val listener: CoreListenerStub = object : CoreListenerStub() {
|
||||
override fun onGlobalStateChanged(core: Core, state: GlobalState, message: String) {
|
||||
|
@ -159,6 +135,11 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
) {
|
||||
Log.i("[Context] Call state changed [$state]")
|
||||
if (state == Call.State.IncomingReceived || state == Call.State.IncomingEarlyMedia) {
|
||||
var gsmCallActive = false
|
||||
if (::phoneStateListener.isInitialized) {
|
||||
gsmCallActive = phoneStateListener.isInCall()
|
||||
}
|
||||
|
||||
if (gsmCallActive) {
|
||||
Log.w("[Context] Refusing the call with reason busy because a GSM call is active")
|
||||
call.decline(Reason.Busy)
|
||||
|
@ -324,9 +305,13 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
|
||||
configureCore()
|
||||
|
||||
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
Log.i("[Context] Registering phone state listener")
|
||||
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)
|
||||
try {
|
||||
phoneStateListener =
|
||||
Compatibility.createPhoneListener(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
|
||||
} catch (exception: SecurityException) {
|
||||
val hasReadPhoneStatePermission = PermissionHelper.get().hasReadPhoneState()
|
||||
Log.e("[Context] Failed to create phone state listener: $exception, READ_PHONE_STATE permission status is $hasReadPhoneStatePermission")
|
||||
}
|
||||
|
||||
EmojiCompat.init(BundledEmojiCompatConfig(context))
|
||||
collator.strength = Collator.NO_DECOMPOSITION
|
||||
|
@ -336,10 +321,9 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
|||
Log.i("[Context] Stopping")
|
||||
coroutineScope.cancel()
|
||||
|
||||
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||
Log.i("[Context] Unregistering phone state listener")
|
||||
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
|
||||
|
||||
if (::phoneStateListener.isInitialized) {
|
||||
phoneStateListener.destroy()
|
||||
}
|
||||
notificationsManager.destroy()
|
||||
contactsManager.destroy()
|
||||
|
||||
|
|
Loading…
Reference in a new issue