Added virtual mobile account
This commit is contained in:
@@ -5,45 +5,47 @@ import java.net.URLDecoder
|
|||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class Account(val accp: Long) {
|
class Account(val accp: Long, virtualAor: String? = null) {
|
||||||
|
|
||||||
|
var isMobile = false
|
||||||
var nickName = ""
|
var nickName = ""
|
||||||
var displayName = Api.account_display_name(accp)
|
var displayName = if (accp != 0L) Api.account_display_name(accp) else ""
|
||||||
val aor = Api.account_aor(accp)
|
val aor = if (accp != 0L) Api.account_aor(accp) else (virtualAor ?: "")
|
||||||
val luri = Api.account_luri(accp)
|
val luri = if (accp != 0L) Api.account_luri(accp) else (virtualAor ?: "")
|
||||||
var authUser = Api.account_auth_user(accp)
|
var authUser = if (accp != 0L) Api.account_auth_user(accp) else ""
|
||||||
var authPass = Api.account_auth_pass(accp)
|
var authPass = if (accp != 0L) Api.account_auth_pass(accp) else ""
|
||||||
var outbound = ArrayList<String>()
|
var outbound = ArrayList<String>()
|
||||||
var mediaNat = Api.account_medianat(accp)
|
var mediaNat = if (accp != 0L) Api.account_medianat(accp) else ""
|
||||||
var stunServer = Api.account_stun_uri(accp)
|
var stunServer = if (accp != 0L) Api.account_stun_uri(accp) else ""
|
||||||
var stunUser = Api.account_stun_user(accp)
|
var stunUser = if (accp != 0L) Api.account_stun_user(accp) else ""
|
||||||
var stunPass = Api.account_stun_pass(accp)
|
var stunPass = if (accp != 0L) Api.account_stun_pass(accp) else ""
|
||||||
var audioCodec = ArrayList<String>()
|
var audioCodec = ArrayList<String>()
|
||||||
var videoCodec = ArrayList<String>()
|
var videoCodec = ArrayList<String>()
|
||||||
var regint = Api.account_regint(accp)
|
var regint = if (accp != 0L) Api.account_regint(accp) else 0
|
||||||
var checkOrigin = Api.account_check_origin(accp)
|
var checkOrigin = if (accp != 0L) Api.account_check_origin(accp) else true
|
||||||
var configuredRegInt = REGISTRATION_INTERVAL
|
var configuredRegInt = REGISTRATION_INTERVAL
|
||||||
var mediaEnc = Api.account_mediaenc(accp)
|
var mediaEnc = if (accp != 0L) Api.account_mediaenc(accp) else ""
|
||||||
var rtcpMux = Api.account_rtcp_mux(accp)
|
var rtcpMux = if (accp != 0L) Api.account_rtcp_mux(accp) else false
|
||||||
var rel100Mode = Api.account_rel100_mode(accp)
|
var rel100Mode = if (accp != 0L) Api.account_rel100_mode(accp) else Api.REL100_DISABLED
|
||||||
var dtmfMode = Api.account_dtmfmode(accp)
|
var dtmfMode = if (accp != 0L) Api.account_dtmfmode(accp) else Api.DTMFMODE_AUTO
|
||||||
var answerMode = Api.account_answermode(accp)
|
var answerMode = if (accp != 0L) Api.account_answermode(accp) else Api.ANSWERMODE_MANUAL
|
||||||
var autoRedirect = Api.account_sip_autoredirect(accp)
|
var autoRedirect = if (accp != 0L) Api.account_sip_autoredirect(accp) else false
|
||||||
var blockUnknown = false
|
var blockUnknown = false
|
||||||
var vmUri = Api.account_vm_uri(accp)
|
var vmUri = if (accp != 0L) Api.account_vm_uri(accp) else ""
|
||||||
var vmNew = 0
|
var vmNew = 0
|
||||||
var vmOld = 0
|
var vmOld = 0
|
||||||
var missedCalls = false
|
var missedCalls = false
|
||||||
var unreadMessages = false
|
var unreadMessages = false
|
||||||
var callHistory = true
|
var callHistory = true
|
||||||
var countryCode = ""
|
var countryCode = ""
|
||||||
var telProvider = Utils.aorDomain(aor)
|
var telProvider = if (accp != 0L) Utils.aorDomain(aor) else ""
|
||||||
var resumeUri = ""
|
var resumeUri = ""
|
||||||
var numericKeypad = false
|
var numericKeypad = false
|
||||||
var customParams = ""
|
var customParams = ""
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
|
if (accp != 0L) {
|
||||||
if (authPass == "")
|
if (authPass == "")
|
||||||
authPass = NO_AUTH_PASS
|
authPass = NO_AUTH_PASS
|
||||||
|
|
||||||
@@ -83,9 +85,12 @@ class Account(val accp: Long) {
|
|||||||
numericKeypad = Utils.paramExists(extra, "numeric_keypad")
|
numericKeypad = Utils.paramExists(extra, "numeric_keypad")
|
||||||
customParams = extra.substringAfter("last=empty").substringAfter(";")
|
customParams = extra.substringAfter("last=empty").substringAfter(";")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun print() : String {
|
fun print() : String {
|
||||||
|
|
||||||
|
if (isMobile) return ""
|
||||||
|
|
||||||
var res = if (displayName != "")
|
var res = if (displayName != "")
|
||||||
"\"${displayName}\" "
|
"\"${displayName}\" "
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -232,14 +232,25 @@ private fun AccountContent(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.Start
|
horizontalArrangement = Arrangement.Start
|
||||||
) {
|
) {
|
||||||
|
val aorText = if (ua.account.isMobile) {
|
||||||
|
if (ua.account.aor == "tel:mobile")
|
||||||
|
stringResource(R.string.not_available)
|
||||||
|
else
|
||||||
|
ua.account.aor
|
||||||
|
} else
|
||||||
|
ua.account.luri
|
||||||
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = ua.account.luri,
|
value = aorText,
|
||||||
enabled = false,
|
enabled = false,
|
||||||
onValueChange = {},
|
onValueChange = {},
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
textStyle = TextStyle(fontSize = 18.sp),
|
textStyle = TextStyle(fontSize = 18.sp),
|
||||||
label = {
|
label = {
|
||||||
Text(text = stringResource(R.string.sip_uri), fontWeight = FontWeight.Bold)
|
Text(
|
||||||
|
text = stringResource(if (ua.account.isMobile) R.string.tel_uri else R.string.sip_uri),
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
},
|
},
|
||||||
colors = OutlinedTextFieldDefaults.colors(
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
disabledTextColor = MaterialTheme.colorScheme.onSurface,
|
disabledTextColor = MaterialTheme.colorScheme.onSurface,
|
||||||
|
|||||||
@@ -491,9 +491,10 @@ class BaresipService: Service() {
|
|||||||
activeNetwork = cm.activeNetwork
|
activeNetwork = cm.activeNetwork
|
||||||
Log.i(TAG, "Active network: $activeNetwork")
|
Log.i(TAG, "Active network: $activeNetwork")
|
||||||
|
|
||||||
if (telecom)
|
if (telecom) {
|
||||||
registerPhoneAccount()
|
registerPhoneAccount()
|
||||||
else
|
addMobileUserAgent()
|
||||||
|
} else
|
||||||
if (btAdapter != null) {
|
if (btAdapter != null) {
|
||||||
Log.i(TAG, "Registering bluetooth receiver")
|
Log.i(TAG, "Registering bluetooth receiver")
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
@@ -1512,6 +1513,7 @@ class BaresipService: Service() {
|
|||||||
fun started() {
|
fun started() {
|
||||||
Log.d(TAG, "Received 'started' from baresip")
|
Log.d(TAG, "Received 'started' from baresip")
|
||||||
isNativeReady = true
|
isNativeReady = true
|
||||||
|
if (telecom) addMobileUserAgent()
|
||||||
Api.net_debug()
|
Api.net_debug()
|
||||||
postServiceEvent(ServiceEvent("started", arrayListOf(callActionUri), System.nanoTime()))
|
postServiceEvent(ServiceEvent("started", arrayListOf(callActionUri), System.nanoTime()))
|
||||||
callActionUri = ""
|
callActionUri = ""
|
||||||
@@ -1748,15 +1750,18 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleExternalCall(telecomCall: android.telecom.Call) {
|
fun handleExternalCall(telecomCall: android.telecom.Call, preferredAor: String? = null) {
|
||||||
val uri = telecomCall.details.handle?.schemeSpecificPart ?: "Unknown"
|
val uri = telecomCall.details.handle?.schemeSpecificPart ?: "Unknown"
|
||||||
Log.d(TAG, "Handling external call from $uri")
|
Log.d(TAG, "Handling external call from $uri (preferredAor=$preferredAor)")
|
||||||
|
|
||||||
if (uas.value.isEmpty()) {
|
if (uas.value.isEmpty()) {
|
||||||
Log.e(TAG, "No User Agents available to handle external call")
|
Log.e(TAG, "No User Agents available to handle external call")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val ua = UserAgent.statusMap().keys.firstOrNull()?.let { UserAgent.ofAor(it) } ?: uas.value[0]
|
|
||||||
|
val ua = preferredAor?.let { UserAgent.ofAor(it) }
|
||||||
|
?: uas.value.find { it.account.isMobile }
|
||||||
|
?: uas.value[0]
|
||||||
|
|
||||||
val telecomState = if (VERSION.SDK_INT >= 31)
|
val telecomState = if (VERSION.SDK_INT >= 31)
|
||||||
telecomCall.details.state
|
telecomCall.details.state
|
||||||
@@ -1819,6 +1824,34 @@ class BaresipService: Service() {
|
|||||||
messageUpdate.postValue(System.currentTimeMillis())
|
messageUpdate.postValue(System.currentTimeMillis())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addMobileUserAgent() {
|
||||||
|
if (!telecom || Utils.pstnAccountHandle(this) == null) return
|
||||||
|
|
||||||
|
val mobileAor = Utils.getLine1Number(this)?.let { "tel:$it" } ?: "tel:mobile"
|
||||||
|
|
||||||
|
val existingMobileUa = uas.value.find { it.account.isMobile }
|
||||||
|
if (existingMobileUa != null) {
|
||||||
|
// If we previously had tel:mobile but now have a real number, replace it
|
||||||
|
if (existingMobileUa.account.aor == "tel:mobile" && mobileAor != "tel:mobile") {
|
||||||
|
val updatedUas = uas.value.toMutableList()
|
||||||
|
updatedUas.remove(existingMobileUa)
|
||||||
|
uas.value = updatedUas.toList()
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val account = Account(0L, mobileAor)
|
||||||
|
account.isMobile = true
|
||||||
|
account.nickName = "Mobile"
|
||||||
|
val mobileUa = UserAgent(0L, account)
|
||||||
|
|
||||||
|
val updatedUas = uas.value.toMutableList()
|
||||||
|
updatedUas.add(mobileUa)
|
||||||
|
uas.value = updatedUas.toList()
|
||||||
|
uasStatus.value = UserAgent.statusMap()
|
||||||
|
}
|
||||||
|
|
||||||
private fun toast(message: String, length: Int = Toast.LENGTH_SHORT) {
|
private fun toast(message: String, length: Int = Toast.LENGTH_SHORT) {
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
Toast.makeText(this@BaresipService.applicationContext, message, length).show()
|
Toast.makeText(this@BaresipService.applicationContext, message, length).show()
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class InCallService : InCallService() {
|
|||||||
// We just need to ensure the InCallService stays bound.
|
// We just need to ensure the InCallService stays bound.
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "InCallService: Identified as PSTN call from $handle")
|
Log.d(TAG, "InCallService: Identified as PSTN call from $handle")
|
||||||
// This is a cellular call. We need to wrap it so MainScreen can show it.
|
val aor = call.details.intentExtras?.getString("aor")
|
||||||
BaresipService.instance?.handleExternalCall(call)
|
BaresipService.instance?.handleExternalCall(call, aor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1472,17 +1472,15 @@ private fun CallRow(
|
|||||||
Row( modifier = Modifier
|
Row( modifier = Modifier
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.Absolute.SpaceBetween
|
horizontalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
if (isDialer) {
|
if (isDialer) {
|
||||||
dialerState.showCallPstnButton.value = Utils.pstnAccountHandle(ctx) != null
|
|
||||||
if (dialerState.showCallButton.value)
|
if (dialerState.showCallButton.value)
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.size(48.dp),
|
modifier = Modifier.size(48.dp),
|
||||||
enabled = dialerState.callButtonsEnabled.value,
|
enabled = dialerState.callButtonsEnabled.value,
|
||||||
onClick = {
|
onClick = {
|
||||||
if (!dialerState.callButtonsEnabled.value) return@IconButton
|
if (!dialerState.callButtonsEnabled.value) return@IconButton
|
||||||
dialerState.showCallPstnButton.value = false
|
|
||||||
dialerState.showCallConferenceButton.value = false
|
dialerState.showCallConferenceButton.value = false
|
||||||
dialerState.showSuggestions.value = false
|
dialerState.showSuggestions.value = false
|
||||||
callClick(ctx, viewModel, dialerState)
|
callClick(ctx, viewModel, dialerState)
|
||||||
@@ -1498,37 +1496,14 @@ private fun CallRow(
|
|||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (dialerState.showCallPstnButton.value)
|
|
||||||
IconButton(
|
|
||||||
modifier = Modifier.size(48.dp),
|
|
||||||
enabled = dialerState.callButtonsEnabled.value,
|
|
||||||
onClick = {
|
|
||||||
if (!dialerState.callButtonsEnabled.value) return@IconButton
|
|
||||||
dialerState.showCallButton.value = false
|
|
||||||
dialerState.showCallConferenceButton.value = false
|
|
||||||
dialerState.showSuggestions.value = false
|
|
||||||
callClick(ctx, viewModel, dialerState)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = ImageVector.vectorResource(R.drawable.call_tel),
|
|
||||||
modifier = Modifier.size(42.dp),
|
|
||||||
tint = colorResource(if (dialerState.callButtonsEnabled.value)
|
|
||||||
R.color.colorTrafficGreen
|
|
||||||
else
|
|
||||||
R.color.colorTrafficYellow),
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (dialerState.showCallConferenceButton.value) {
|
if (dialerState.showCallConferenceButton.value) {
|
||||||
Spacer(modifier = Modifier.weight(1f, true))
|
Spacer(modifier = Modifier.width(32.dp))
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = Modifier.size(48.dp),
|
modifier = Modifier.size(48.dp),
|
||||||
enabled = dialerState.callButtonsEnabled.value,
|
enabled = dialerState.callButtonsEnabled.value,
|
||||||
onClick = {
|
onClick = {
|
||||||
if (!dialerState.callButtonsEnabled.value) return@IconButton
|
if (!dialerState.callButtonsEnabled.value) return@IconButton
|
||||||
dialerState.showCallButton.value = false
|
dialerState.showCallButton.value = false
|
||||||
dialerState.showCallPstnButton.value = false
|
|
||||||
dialerState.showSuggestions.value = false
|
dialerState.showSuggestions.value = false
|
||||||
callClick(ctx, viewModel, dialerState)
|
callClick(ctx, viewModel, dialerState)
|
||||||
}
|
}
|
||||||
@@ -2131,7 +2106,7 @@ private fun makeCall(ctx: Context, viewModel: ViewModel, uriText: String,
|
|||||||
else
|
else
|
||||||
uriText
|
uriText
|
||||||
val uri = if (Utils.isTelUri(peerUri)) {
|
val uri = if (Utils.isTelUri(peerUri)) {
|
||||||
if (dialerState.showCallPstnButton.value)
|
if (ua.account.isMobile)
|
||||||
peerUri
|
peerUri
|
||||||
else if (ua.account.telProvider == "") {
|
else if (ua.account.telProvider == "") {
|
||||||
alertTitle.value = ctx.getString(R.string.notice)
|
alertTitle.value = ctx.getString(R.string.notice)
|
||||||
@@ -2150,7 +2125,7 @@ private fun makeCall(ctx: Context, viewModel: ViewModel, uriText: String,
|
|||||||
showAlert.value = true
|
showAlert.value = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
else if (dialerState.showCallPstnButton.value && !Utils.isTelUri(uri)) {
|
else if (ua.account.isMobile && !Utils.isTelUri(uri)) {
|
||||||
alertTitle.value = ctx.getString(R.string.notice)
|
alertTitle.value = ctx.getString(R.string.notice)
|
||||||
alertMessage.value = "Telephone call can only be made to telephone number"
|
alertMessage.value = "Telephone call can only be made to telephone number"
|
||||||
showAlert.value = true
|
showAlert.value = true
|
||||||
@@ -2164,14 +2139,15 @@ private fun makeCall(ctx: Context, viewModel: ViewModel, uriText: String,
|
|||||||
var error = ""
|
var error = ""
|
||||||
if (BaresipService.telecom) {
|
if (BaresipService.telecom) {
|
||||||
val tm = ctx.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
val tm = ctx.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
|
||||||
if (dialerState.showCallPstnButton.value) {
|
if (ua.account.isMobile) {
|
||||||
val phoneAccountHandle = Utils.pstnAccountHandle(ctx)
|
val phoneAccountHandle = Utils.pstnAccountHandle(ctx)
|
||||||
if (phoneAccountHandle != null) {
|
if (phoneAccountHandle != null) {
|
||||||
val extras = Bundle().apply {
|
val extras = Bundle().apply {
|
||||||
putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
|
putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
|
||||||
}
|
}
|
||||||
val callExtras = Bundle()
|
val callExtras = Bundle()
|
||||||
callExtras.putBoolean("pstnCall", dialerState.showCallPstnButton.value)
|
callExtras.putBoolean("pstnCall", true)
|
||||||
|
callExtras.putString("aor", aor)
|
||||||
extras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, callExtras)
|
extras.putBundle(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, callExtras)
|
||||||
try {
|
try {
|
||||||
Log.i(TAG, "Placing Telecom PSTN call to $uri with uap=${ua.uap}")
|
Log.i(TAG, "Placing Telecom PSTN call to $uri with uap=${ua.uap}")
|
||||||
@@ -2301,8 +2277,7 @@ private fun showCall(ctx: Context, viewModel: ViewModel, ua: UserAgent?, showCal
|
|||||||
viewModel.dialerState.callUriEnabled.value = true
|
viewModel.dialerState.callUriEnabled.value = true
|
||||||
}, 100)
|
}, 100)
|
||||||
viewModel.dialerState.showCallButton.value = true
|
viewModel.dialerState.showCallButton.value = true
|
||||||
viewModel.dialerState.showCallPstnButton.value = true
|
viewModel.dialerState.showCallConferenceButton.value = !ua.account.isMobile
|
||||||
viewModel.dialerState.showCallConferenceButton.value = true
|
|
||||||
viewModel.dialerState.callButtonsEnabled.value = true
|
viewModel.dialerState.callButtonsEnabled.value = true
|
||||||
viewModel.dialerState.showSuggestions.value = false
|
viewModel.dialerState.showSuggestions.value = false
|
||||||
dialpadButtonEnabled.value = true
|
dialpadButtonEnabled.value = true
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ import com.tutpro.baresip.BaresipService.Companion.colorblind
|
|||||||
import com.tutpro.baresip.BaresipService.Companion.uas
|
import com.tutpro.baresip.BaresipService.Companion.uas
|
||||||
import com.tutpro.baresip.BaresipService.Companion.uasStatus
|
import com.tutpro.baresip.BaresipService.Companion.uasStatus
|
||||||
|
|
||||||
class UserAgent(val uap: Long) {
|
class UserAgent(val uap: Long, virtualAccount: Account? = null) {
|
||||||
|
|
||||||
val account = Account(Api.ua_account(uap))
|
val account = virtualAccount ?: Account(Api.ua_account(uap))
|
||||||
var status = R.drawable.circle_white
|
var status = if (uap != 0L) R.drawable.circle_white else R.drawable.circle_green
|
||||||
|
|
||||||
fun callAlloc(xCall: Long, videoMode: Int): Long {
|
fun callAlloc(xCall: Long, videoMode: Int): Long {
|
||||||
|
if (uap == 0L) return 0L
|
||||||
return Api.ua_call_alloc(uap, xCall, videoMode)
|
return Api.ua_call_alloc(uap, xCall, videoMode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +50,7 @@ class UserAgent(val uap: Long) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun reRegister() {
|
fun reRegister() {
|
||||||
|
if (uap == 0L) return
|
||||||
this.status = circleYellow.getValue(colorblind)
|
this.status = circleYellow.getValue(colorblind)
|
||||||
if (this.account.regint == 0)
|
if (this.account.regint == 0)
|
||||||
Api.ua_unregister(this.uap)
|
Api.ua_unregister(this.uap)
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import android.os.Environment
|
|||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.provider.OpenableColumns
|
import android.provider.OpenableColumns
|
||||||
|
import android.telephony.SubscriptionManager
|
||||||
|
import android.telephony.TelephonyManager
|
||||||
import android.telecom.TelecomManager
|
import android.telecom.TelecomManager
|
||||||
import android.telecom.PhoneAccountHandle
|
import android.telecom.PhoneAccountHandle
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
@@ -1344,6 +1346,36 @@ object Utils {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("HardwareIds")
|
||||||
|
fun getLine1Number(ctx: Context): String? {
|
||||||
|
try {
|
||||||
|
if (Build.VERSION.SDK_INT >= 33) {
|
||||||
|
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
val sm = ctx.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
|
||||||
|
val number = sm.getPhoneNumber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)
|
||||||
|
if (number != "") {
|
||||||
|
Log.i(TAG, "Retrieved SIM number via SubscriptionManager")
|
||||||
|
return number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED ||
|
||||||
|
ContextCompat.checkSelfPermission(ctx, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
val tm = ctx.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val number = tm.line1Number
|
||||||
|
if (number != null) {
|
||||||
|
Log.i(TAG, "Retrieved SIM number via TelephonyManager")
|
||||||
|
return number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "getLine1Number failed: ${e.message}")
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun listFilesInDirectory(directoryPath: String): List<File> {
|
fun listFilesInDirectory(directoryPath: String): List<File> {
|
||||||
val directory = File(directoryPath)
|
val directory = File(directoryPath)
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ class ViewModel: ViewModel() {
|
|||||||
val callUriLabel: MutableState<String> = mutableStateOf(""),
|
val callUriLabel: MutableState<String> = mutableStateOf(""),
|
||||||
val showSuggestions: MutableState<Boolean> = mutableStateOf(false),
|
val showSuggestions: MutableState<Boolean> = mutableStateOf(false),
|
||||||
val showCallButton: MutableState<Boolean> = mutableStateOf(true),
|
val showCallButton: MutableState<Boolean> = mutableStateOf(true),
|
||||||
val showCallPstnButton: MutableState<Boolean> = mutableStateOf(true),
|
|
||||||
val showCallConferenceButton: MutableState<Boolean> = mutableStateOf(true),
|
val showCallConferenceButton: MutableState<Boolean> = mutableStateOf(true),
|
||||||
val callButtonsEnabled: MutableState<Boolean> = mutableStateOf(true),
|
val callButtonsEnabled: MutableState<Boolean> = mutableStateOf(true),
|
||||||
val conferenceCall: MutableState<Boolean> = mutableStateOf(false),
|
val conferenceCall: MutableState<Boolean> = mutableStateOf(false),
|
||||||
|
|||||||
@@ -530,6 +530,7 @@
|
|||||||
<string name="call_is_ringing">Puhelu soi</string>
|
<string name="call_is_ringing">Puhelu soi</string>
|
||||||
<string name="call_is_on_hold">Puhelu on pidossa</string>
|
<string name="call_is_on_hold">Puhelu on pidossa</string>
|
||||||
<string name="call_is_connected">Puhelu on yhdistetty</string>
|
<string name="call_is_connected">Puhelu on yhdistetty</string>
|
||||||
|
<string name="not_available">Ei saatavilla</string>
|
||||||
<string name="rec_in_call">Tallennus voidaan asettaa päälle tai pois vain silloin, kun puhelu
|
<string name="rec_in_call">Tallennus voidaan asettaa päälle tai pois vain silloin, kun puhelu
|
||||||
ei ole yhdistetty</string>
|
ei ole yhdistetty</string>
|
||||||
<string name="call_transfer">Puhelun siirto</string>
|
<string name="call_transfer">Puhelun siirto</string>
|
||||||
|
|||||||
@@ -480,6 +480,7 @@
|
|||||||
<string name="accept">Accept</string>
|
<string name="accept">Accept</string>
|
||||||
<string name="deny">Deny</string>
|
<string name="deny">Deny</string>
|
||||||
<string name="sip_uri" translatable="false">SIP URI</string>
|
<string name="sip_uri" translatable="false">SIP URI</string>
|
||||||
|
<string name="tel_uri" translatable="false">TEL URI</string>
|
||||||
<string name="add">Add</string>
|
<string name="add">Add</string>
|
||||||
<string name="delete">Delete</string>
|
<string name="delete">Delete</string>
|
||||||
<string name="edit">Edit</string>
|
<string name="edit">Edit</string>
|
||||||
@@ -513,6 +514,7 @@
|
|||||||
<string name="call_is_ringing">Call is ringing</string>
|
<string name="call_is_ringing">Call is ringing</string>
|
||||||
<string name="call_is_on_hold">Call is on hold</string>
|
<string name="call_is_on_hold">Call is on hold</string>
|
||||||
<string name="call_is_connected">Call is connected</string>
|
<string name="call_is_connected">Call is connected</string>
|
||||||
|
<string name="not_available">Not available</string>
|
||||||
<string name="rec_in_call">Recording can be turned on or off only when call is not
|
<string name="rec_in_call">Recording can be turned on or off only when call is not
|
||||||
connected</string>
|
connected</string>
|
||||||
<string name="call_transfer">Call Transfer</string>
|
<string name="call_transfer">Call Transfer</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user