diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
index a339f35e..058d3afc 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
@@ -65,6 +65,7 @@ import androidx.compose.runtime.setValue
import androidx.core.app.ActivityCompat
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
+import androidx.core.net.toUri
import androidx.lifecycle.MutableLiveData
import androidx.media.AudioAttributesCompat
import androidx.media.AudioFocusRequestCompat
@@ -83,7 +84,6 @@ class BaresipService: Service() {
internal lateinit var intent: Intent
private lateinit var am: AudioManager
- private lateinit var rt: Ringtone
private lateinit var nt: Ringtone
private lateinit var nm: NotificationManager
private lateinit var snb: NotificationCompat.Builder
@@ -131,8 +131,10 @@ class BaresipService: Service() {
RingtoneManager.TYPE_NOTIFICATION)
nt = RingtoneManager.getRingtone(applicationContext, ntUri)
- val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
- RingtoneManager.TYPE_RINGTONE)
+ val rtUri = if (Preferences(applicationContext).ringtoneUri == "")
+ Settings.System.RINGTONE.toUri()
+ else
+ Preferences(applicationContext).ringtoneUri!!.toUri()
rt = RingtoneManager.getRingtone(applicationContext, rtUri)
nm = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
@@ -1311,8 +1313,8 @@ class BaresipService: Service() {
}
private fun startRinging() {
- rt.isLooping = true
- rt.play()
+ rt!!.isLooping = true
+ rt!!.play()
if (shouldVibrate()) {
vbTimer = Timer()
vbTimer!!.schedule(object : TimerTask() {
@@ -1346,7 +1348,7 @@ class BaresipService: Service() {
}
private fun stopRinging() {
- rt.stop()
+ rt!!.stop()
if (vbTimer != null) {
vbTimer!!.cancel()
vbTimer = null
@@ -1663,6 +1665,7 @@ class BaresipService: Service() {
var aecAvailable = false
private var aec: AcousticEchoCanceler? = null
var agcAvailable = false
+ var rt: Ringtone? = null
private var agc: AutomaticGainControl? = null
private val nsAvailable = NoiseSuppressor.isAvailable()
private var ns: NoiseSuppressor? = null
diff --git a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
index 72263ed8..fb7fb8e8 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
@@ -6,7 +6,9 @@ import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
-import android.os.Build
+import android.media.RingtoneManager
+import android.net.Uri
+import android.os.Build.VERSION
import android.os.Bundle
import android.os.PowerManager
import android.provider.Settings
@@ -14,8 +16,10 @@ import android.window.OnBackInvokedCallback
import android.window.OnBackInvokedDispatcher
import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedCallback
+import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
+import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
@@ -65,6 +69,7 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
+import androidx.core.net.toUri
import com.tutpro.baresip.CustomElements.AlertDialog
import com.tutpro.baresip.CustomElements.Checkbox
import com.tutpro.baresip.CustomElements.LabelText
@@ -95,6 +100,8 @@ class ConfigActivity : ComponentActivity() {
private var newCaFile = false
private var oldUserAgent = ""
private var newUserAgent = ""
+ private var oldRingtoneUri = ""
+ private var newRingtoneUri = ""
private var oldBatteryOptimizations = false
private var newBatteryOptimizations = false
private var oldDefaultDialer = false
@@ -208,7 +215,7 @@ class ConfigActivity : ComponentActivity() {
enableEdgeToEdge()
- if (Build.VERSION.SDK_INT >= 33)
+ if (VERSION.SDK_INT >= 33)
registerBackInvokedCallback()
else {
onBackPressedCallback = object : OnBackPressedCallback(true) {
@@ -274,11 +281,11 @@ class ConfigActivity : ComponentActivity() {
) {
Log.d(TAG, "dialerRoleRequest succeeded: " +
"${it.resultCode == RESULT_OK}")
- if (Build.VERSION.SDK_INT >= 29)
+ if (VERSION.SDK_INT >= 29)
newDefaultDialer = roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
}
- if (Build.VERSION.SDK_INT >= 29) {
+ if (VERSION.SDK_INT >= 29) {
roleManager = getSystemService(ROLE_SERVICE) as RoleManager
oldDefaultDialer = roleManager.isRoleHeld(RoleManager.ROLE_DIALER)
}
@@ -413,8 +420,9 @@ class ConfigActivity : ComponentActivity() {
CaFile(ctx)
UserAgent()
AudioSettings(ctx)
+ Ringtone()
BatteryOptimizations()
- if (Build.VERSION.SDK_INT >= 29)
+ if (VERSION.SDK_INT >= 29)
DefaultDialer()
Contacts(ctx)
DarkTheme()
@@ -628,7 +636,7 @@ class ConfigActivity : ComponentActivity() {
tlsCertificateFile = it
newTlsCertificateFile = tlsCertificateFile
if (it)
- if (Build.VERSION.SDK_INT < 29) {
+ if (VERSION.SDK_INT < 29) {
tlsCertificateFile = false
when {
ContextCompat.checkSelfPermission(
@@ -733,7 +741,7 @@ class ConfigActivity : ComponentActivity() {
caFile = it
newCaFile = caFile
if (it) {
- if (Build.VERSION.SDK_INT < 29) {
+ if (VERSION.SDK_INT < 29) {
caFile = false
when {
ContextCompat.checkSelfPermission(ctx,
@@ -834,6 +842,54 @@ class ConfigActivity : ComponentActivity() {
}
}
+ @Composable
+ private fun Ringtone() {
+ oldRingtoneUri = if (Preferences(applicationContext).ringtoneUri == "")
+ RingtoneManager.getActualDefaultRingtoneUri(applicationContext, RingtoneManager.TYPE_RINGTONE).toString()
+ else
+ Preferences(applicationContext).ringtoneUri!!
+ newRingtoneUri = oldRingtoneUri
+ val launcher = rememberLauncherForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) { result: ActivityResult ->
+ if (result.resultCode == RESULT_OK) {
+ val uri: Uri? = if (VERSION.SDK_INT >= 33)
+ result.data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, Uri::class.java)
+ else
+ @Suppress("DEPRECATION")
+ result.data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
+ if (uri != null)
+ newRingtoneUri = uri.toString()
+ }
+ }
+ Row(
+ Modifier
+ .fillMaxWidth()
+ .padding(top = 12.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.Start
+ ) {
+ Text(
+ text = stringResource(R.string.ringtone),
+ modifier = Modifier
+ .weight(1f)
+ .clickable {
+ val intent = Intent(RingtoneManager.ACTION_RINGTONE_PICKER)
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,
+ RingtoneManager.TYPE_RINGTONE)
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, getString(R.string.select_ringtone))
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, newRingtoneUri.toUri())
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false)
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true)
+ launcher.launch(intent)
+ },
+ color = LocalCustomColors.current.itemText,
+ fontSize = 18.sp,
+ fontWeight = FontWeight.Bold
+ )
+ }
+ }
+
@Composable
private fun BatteryOptimizations() {
Row(
@@ -1240,6 +1296,11 @@ class ConfigActivity : ComponentActivity() {
restart = true
}
+ Log.d(TAG, "Old/new ringtone: $oldRingtoneUri / $newRingtoneUri")
+ if (newRingtoneUri != oldRingtoneUri) {
+ Preferences(applicationContext).ringtoneUri = newRingtoneUri
+ BaresipService.rt = RingtoneManager.getRingtone(applicationContext, newRingtoneUri.toUri())
+ }
if (oldContactsMode != newContactsMode) {
Config.replaceVariable("contacts_mode", newContactsMode)
BaresipService.contactsMode = newContactsMode
@@ -1301,7 +1362,7 @@ class ConfigActivity : ComponentActivity() {
}
override fun onDestroy() {
- if (Build.VERSION.SDK_INT >= 33) {
+ if (VERSION.SDK_INT >= 33) {
if (backInvokedCallback != null)
onBackInvokedDispatcher.unregisterOnBackInvokedCallback(backInvokedCallback!!)
}
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Preferences.kt b/app/src/main/kotlin/com/tutpro/baresip/Preferences.kt
index ddb2d54f..d5abef9f 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Preferences.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Preferences.kt
@@ -2,6 +2,7 @@ package com.tutpro.baresip
import android.content.Context
import androidx.preference.PreferenceManager
+import androidx.core.content.edit
class Preferences(context: Context) {
@@ -12,6 +13,9 @@ class Preferences(context: Context) {
private val preferences = PreferenceManager.getDefaultSharedPreferences(context)
var displayTheme = preferences.getInt(DISPLAY_THEME, -1)
- set(value) = preferences.edit().putInt(DISPLAY_THEME, value).apply()
+ set(value) = preferences.edit() { putInt(DISPLAY_THEME, value) }
+
+ var ringtoneUri = preferences.getString("ringtone_uri", "")
+ set(value) = preferences.edit() { putString("ringtone_uri", value) }
}
\ No newline at end of file
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 3dfc6c2b..bd24bd58 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -405,6 +405,8 @@
Videokehysten lähetystaajuus per sekuntti, jota tarjotaan
SDP-neuvottelun aikana. Arvon on oltava välillä 10-30.
Virheellinen videokehysten lähetystaajuus \'%1$d\'
+ Soittoääni
+ Valitse soittoääni
User Agent
Räätälöity SIP sanoman User-Agent otsikkokentän arvo
Virheellinen User-Agent otsikkokentän arvo
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 024580fc..f9e85561 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -378,6 +378,8 @@
Video frame rate that will be offered during the SDP handshake.
Valid values are from 10 to 30.
Invalid Frames Per Second \'%1$d\'
+ Ringtone
+ Select Ringtone
User Agent
Custom SIP request/response User-Agent header field value
Invalid User-Agent header field value