- New version 9.3.4.
- Use communication mode only when call is (being) established. - Introduced 2.5 sec delay to placing of a call in order to avoid loss of audio at the beginning of call. - Fixed initializing default contacts when baresip is started the first time. - Clear call URI when call is closed.
This commit is contained in:
+2
-2
@@ -8,8 +8,8 @@ android {
|
|||||||
applicationId = 'com.tutpro.baresip'
|
applicationId = 'com.tutpro.baresip'
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode = 70
|
versionCode = 71
|
||||||
versionName = '8.3.3'
|
versionName = '8.3.4'
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
cFlags '-DHAVE_INTTYPES_H'
|
cFlags '-DHAVE_INTTYPES_H'
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ class BaresipService: Service() {
|
|||||||
filesPath = filesDir.absolutePath
|
filesPath = filesDir.absolutePath
|
||||||
|
|
||||||
am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
// Setting this when call is established, causes on some devices 3-4 sec delay
|
|
||||||
// to hearing of audio
|
|
||||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
|
||||||
|
|
||||||
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
|
val rtUri = RingtoneManager.getActualDefaultRingtoneUri(applicationContext,
|
||||||
RingtoneManager.TYPE_RINGTONE)
|
RingtoneManager.TYPE_RINGTONE)
|
||||||
@@ -75,10 +72,12 @@ class BaresipService: Service() {
|
|||||||
Log.d(LOG_TAG, "Network '$network' is available")
|
Log.d(LOG_TAG, "Network '$network' is available")
|
||||||
// This is followed by onLinkPropertiesChanged
|
// This is followed by onLinkPropertiesChanged
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLost(network: Network) {
|
override fun onLost(network: Network) {
|
||||||
super.onLost(network)
|
super.onLost(network)
|
||||||
Log.d(LOG_TAG, "Network '$network' is lost")
|
Log.d(LOG_TAG, "Network '$network' is lost")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
|
override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
|
||||||
super.onLinkPropertiesChanged(network, linkProperties)
|
super.onLinkPropertiesChanged(network, linkProperties)
|
||||||
Log.d(LOG_TAG, "Network $network link properties changed")
|
Log.d(LOG_TAG, "Network $network link properties changed")
|
||||||
@@ -154,7 +153,7 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ContactsActivity.restoreContacts(applicationContext.filesDir)
|
ContactsActivity.restoreContacts(applicationContext.filesDir, "contacts")
|
||||||
|
|
||||||
Thread(Runnable { baresipStart(filesPath) }).start()
|
Thread(Runnable { baresipStart(filesPath) }).start()
|
||||||
isServiceRunning = true
|
isServiceRunning = true
|
||||||
@@ -162,9 +161,6 @@ class BaresipService: Service() {
|
|||||||
|
|
||||||
if (Config.variable("dyn_dns")[0] == "yes")
|
if (Config.variable("dyn_dns")[0] == "yes")
|
||||||
Config.remove("dns_server")
|
Config.remove("dns_server")
|
||||||
|
|
||||||
Log.d(LOG_TAG, "AudioManager mode is ${am.mode}")
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"Call Show", "Call Answer" -> {
|
"Call Show", "Call Answer" -> {
|
||||||
@@ -236,8 +232,8 @@ class BaresipService: Service() {
|
|||||||
Log.w(LOG_TAG, "onStartCommand did not find UA $uap")
|
Log.w(LOG_TAG, "onStartCommand did not find UA $uap")
|
||||||
else
|
else
|
||||||
ChatsActivity.saveUaMessage(ua.account.aor,
|
ChatsActivity.saveUaMessage(ua.account.aor,
|
||||||
intent.getStringExtra("time").toLong(),
|
intent.getStringExtra("time").toLong(),
|
||||||
applicationContext.filesDir.absolutePath)
|
applicationContext.filesDir.absolutePath)
|
||||||
nm.cancel(BaresipService.MESSAGE_NOTIFICATION_ID)
|
nm.cancel(BaresipService.MESSAGE_NOTIFICATION_ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +341,11 @@ class BaresipService: Service() {
|
|||||||
status[account_index] = R.drawable.dot_yellow
|
status[account_index] = R.drawable.dot_yellow
|
||||||
updateStatusNotification()
|
updateStatusNotification()
|
||||||
}
|
}
|
||||||
"call ringing" -> {
|
"call progress", "call ringing" -> {
|
||||||
|
if (!isAudioFocused()) {
|
||||||
|
requestAudioFocus(AudioManager.STREAM_VOICE_CALL)
|
||||||
|
setCallVolume()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"call incoming" -> {
|
"call incoming" -> {
|
||||||
val peerUri = Api.call_peeruri(callp)
|
val peerUri = Api.call_peeruri(callp)
|
||||||
@@ -356,7 +356,7 @@ class BaresipService: Service() {
|
|||||||
CallHistory.save(filesPath)
|
CallHistory.save(filesPath)
|
||||||
ua.account.missedCalls = true
|
ua.account.missedCalls = true
|
||||||
if (!Utils.isVisible())
|
if (!Utils.isVisible())
|
||||||
return
|
return
|
||||||
newEvent = "call rejected"
|
newEvent = "call rejected"
|
||||||
} else {
|
} else {
|
||||||
Log.d(LOG_TAG, "Incoming call $uap/$callp/$peerUri")
|
Log.d(LOG_TAG, "Incoming call $uap/$callp/$peerUri")
|
||||||
@@ -416,15 +416,13 @@ class BaresipService: Service() {
|
|||||||
CallHistory.add(CallHistory(aor, call.peerURI, call.dir, true))
|
CallHistory.add(CallHistory(aor, call.peerURI, call.dir, true))
|
||||||
CallHistory.save(filesPath)
|
CallHistory.save(filesPath)
|
||||||
call.hasHistory = true
|
call.hasHistory = true
|
||||||
if (call.dir == "in") stopRinging()
|
if (call.dir == "in") {
|
||||||
if (!isAudioFocused()) requestAudioFocus(AudioManager.STREAM_VOICE_CALL)
|
stopRinging()
|
||||||
if (callVolume != 0) {
|
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||||
origCallVolume = am.getStreamVolume(am.mode)
|
}
|
||||||
am.setStreamVolume(am.mode,
|
if (!isAudioFocused()) {
|
||||||
(callVolume * 0.1 * am.getStreamMaxVolume(am.mode)).roundToInt(),
|
requestAudioFocus(AudioManager.STREAM_VOICE_CALL)
|
||||||
0)
|
setCallVolume()
|
||||||
Log.d(LOG_TAG, "Original/new call volume of stream ${am.mode} is " +
|
|
||||||
"$origCallVolume/${am.getStreamVolume(am.mode)}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"call verified", "call secure" -> {
|
"call verified", "call secure" -> {
|
||||||
@@ -450,8 +448,8 @@ class BaresipService: Service() {
|
|||||||
val intent = Intent(this, BaresipService::class.java)
|
val intent = Intent(this, BaresipService::class.java)
|
||||||
intent.action = "Transfer Show"
|
intent.action = "Transfer Show"
|
||||||
intent.putExtra("uap", uap)
|
intent.putExtra("uap", uap)
|
||||||
.putExtra("callp", callp)
|
.putExtra("callp", callp)
|
||||||
.putExtra("uri", ev[1])
|
.putExtra("uri", ev[1])
|
||||||
val pi = PendingIntent.getService(this, TRANSFER_REQ_CODE,
|
val pi = PendingIntent.getService(this, TRANSFER_REQ_CODE,
|
||||||
intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
intent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
||||||
@@ -472,8 +470,8 @@ class BaresipService: Service() {
|
|||||||
val acceptIntent = Intent(this, BaresipService::class.java)
|
val acceptIntent = Intent(this, BaresipService::class.java)
|
||||||
acceptIntent.action = "Transfer Accept"
|
acceptIntent.action = "Transfer Accept"
|
||||||
acceptIntent.putExtra("uap", uap)
|
acceptIntent.putExtra("uap", uap)
|
||||||
.putExtra("callp", callp)
|
.putExtra("callp", callp)
|
||||||
.putExtra("uri", ev[1])
|
.putExtra("uri", ev[1])
|
||||||
val acceptPendingIntent = PendingIntent.getService(this,
|
val acceptPendingIntent = PendingIntent.getService(this,
|
||||||
ACCEPT_REQ_CODE, acceptIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
ACCEPT_REQ_CODE, acceptIntent, PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
val denyIntent = Intent(this, BaresipService::class.java)
|
val denyIntent = Intent(this, BaresipService::class.java)
|
||||||
@@ -506,11 +504,8 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
if (Call.calls().size == 0) {
|
if (Call.calls().size == 0) {
|
||||||
abandonAudioFocus()
|
abandonAudioFocus()
|
||||||
if (origCallVolume != -1) {
|
resetCallVolume()
|
||||||
am.setStreamVolume(am.mode, origCallVolume, 0)
|
am.mode = AudioManager.MODE_NORMAL
|
||||||
origCallVolume = -1
|
|
||||||
}
|
|
||||||
Log.d(LOG_TAG, "Call volume of stream ${am.mode} is ${am.getStreamVolume(am.mode)}")
|
|
||||||
if (am.isSpeakerphoneOn) am.isSpeakerphoneOn = false
|
if (am.isSpeakerphoneOn) am.isSpeakerphoneOn = false
|
||||||
speakerPhone = false
|
speakerPhone = false
|
||||||
}
|
}
|
||||||
@@ -711,7 +706,6 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun abandonAudioFocus() {
|
private fun abandonAudioFocus() {
|
||||||
Log.d(LOG_TAG, "Abandonin audio focus")
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
if (audioFocusRequest != null) {
|
if (audioFocusRequest != null) {
|
||||||
am.abandonAudioFocusRequest(audioFocusRequest!!)
|
am.abandonAudioFocusRequest(audioFocusRequest!!)
|
||||||
@@ -723,6 +717,8 @@ class BaresipService: Service() {
|
|||||||
audioFocused = false
|
audioFocused = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isAudioFocused())
|
||||||
|
Log.w(LOG_TAG, "Failed to abandon audio focus")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startRinging() {
|
private fun startRinging() {
|
||||||
@@ -755,7 +751,25 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
abandonAudioFocus()
|
abandonAudioFocus()
|
||||||
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
}
|
||||||
|
|
||||||
|
private fun setCallVolume() {
|
||||||
|
if (callVolume != 0) {
|
||||||
|
origCallVolume = am.getStreamVolume(am.mode)
|
||||||
|
am.setStreamVolume(am.mode,
|
||||||
|
(callVolume * 0.1 * am.getStreamMaxVolume(am.mode)).roundToInt(),
|
||||||
|
0)
|
||||||
|
Log.d(LOG_TAG, "Original/new call volume of stream ${am.mode} is " +
|
||||||
|
"$origCallVolume/${am.getStreamVolume(am.mode)}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetCallVolume() {
|
||||||
|
if (origCallVolume != -1) {
|
||||||
|
am.setStreamVolume(am.mode, origCallVolume, 0)
|
||||||
|
origCallVolume = -1
|
||||||
|
}
|
||||||
|
Log.d(LOG_TAG, "Call volume of stream ${am.mode} is ${am.getStreamVolume(am.mode)}")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanService() {
|
private fun cleanService() {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class ContactActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Contact.contacts().sortBy { Contact -> Contact.name }
|
Contact.contacts().sortBy { Contact -> Contact.name }
|
||||||
ContactsActivity.saveContacts(applicationContext.filesDir)
|
ContactsActivity.saveContacts(applicationContext.filesDir, "contacts")
|
||||||
|
|
||||||
i.putExtra("name", newName)
|
i.putExtra("name", newName)
|
||||||
setResult(Activity.RESULT_OK, i)
|
setResult(Activity.RESULT_OK, i)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class ContactListAdapter(private val cxt: Context, private val rows: ArrayList<C
|
|||||||
when (which) {
|
when (which) {
|
||||||
DialogInterface.BUTTON_POSITIVE -> {
|
DialogInterface.BUTTON_POSITIVE -> {
|
||||||
Contact.contacts().removeAt(pos)
|
Contact.contacts().removeAt(pos)
|
||||||
ContactsActivity.saveContacts(cxt.applicationContext.filesDir)
|
ContactsActivity.saveContacts(cxt.applicationContext.filesDir, "contacts")
|
||||||
this.notifyDataSetChanged()
|
this.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
DialogInterface.BUTTON_NEGATIVE -> {
|
DialogInterface.BUTTON_NEGATIVE -> {
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class ContactsActivity : AppCompatActivity() {
|
|||||||
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.export_contacts -> {
|
R.id.export_contacts -> {
|
||||||
if (saveContacts(dir))
|
if (saveContacts(dir, "contacts.bs"))
|
||||||
Utils.alertView(this, "",
|
Utils.alertView(this, "",
|
||||||
getString(R.string.exported_contacts))
|
getString(R.string.exported_contacts))
|
||||||
else
|
else
|
||||||
@@ -65,11 +65,11 @@ class ContactsActivity : AppCompatActivity() {
|
|||||||
getString(R.string.export_error))
|
getString(R.string.export_error))
|
||||||
}
|
}
|
||||||
R.id.import_contacts -> {
|
R.id.import_contacts -> {
|
||||||
if (restoreContacts(dir)) {
|
if (restoreContacts(dir, "contacts.bs")) {
|
||||||
Utils.alertView(this, "",
|
Utils.alertView(this, "",
|
||||||
getString(R.string.imported_contacts))
|
getString(R.string.imported_contacts))
|
||||||
clAdapter.notifyDataSetChanged()
|
clAdapter.notifyDataSetChanged()
|
||||||
saveContacts(applicationContext.filesDir)
|
saveContacts(applicationContext.filesDir, "contacts")
|
||||||
} else
|
} else
|
||||||
Utils.alertView(this,getString(R.string.error),
|
Utils.alertView(this,getString(R.string.error),
|
||||||
getString(R.string.import_error))
|
getString(R.string.import_error))
|
||||||
@@ -93,15 +93,15 @@ class ContactsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun saveContacts(path: File): Boolean {
|
fun saveContacts(path: File, file: String): Boolean {
|
||||||
var contents = ""
|
var contents = ""
|
||||||
for (c in Contact.contacts())
|
for (c in Contact.contacts())
|
||||||
contents += "\"${c.name}\" ${c.uri}\n"
|
contents += "\"${c.name}\" ${c.uri}\n"
|
||||||
return Utils.putFileContents(File(path, "contacts.bs"), contents)
|
return Utils.putFileContents(File(path, file), contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun restoreContacts(path: File): Boolean {
|
fun restoreContacts(path: File, file: String): Boolean {
|
||||||
val content = Utils.getFileContents(File(path, "contacts.bs"))
|
val content = Utils.getFileContents(File(path, file))
|
||||||
if (content == "Failed") return false
|
if (content == "Failed") return false
|
||||||
Api.contacts_remove()
|
Api.contacts_remove()
|
||||||
Contact.contacts().clear()
|
Contact.contacts().clear()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import android.content.pm.PackageManager
|
|||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
|
import android.os.Handler
|
||||||
import android.support.v4.content.LocalBroadcastManager
|
import android.support.v4.content.LocalBroadcastManager
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
@@ -257,11 +258,25 @@ class MainActivity : AppCompatActivity() {
|
|||||||
uri = "$uri@$host"
|
uri = "$uri@$host"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Utils.checkSipUri(uri))
|
if (!Utils.checkSipUri(uri)) {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
Utils.alertView(this, getString(R.string.notice),
|
||||||
"${getString(R.string.invalid_sip_uri)} '$uri'")
|
"${getString(R.string.invalid_sip_uri)} '$uri'")
|
||||||
else
|
} else {
|
||||||
call(ua, uri, "outgoing")
|
// Set audio mode to MODE_IN_COMMUNICATION and wait 2.5 sec before
|
||||||
|
// placing to call in order to avoid missing audio from callee due to
|
||||||
|
// a bug in many Android devices.
|
||||||
|
val am = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
|
am.mode = AudioManager.MODE_IN_COMMUNICATION
|
||||||
|
callButton.visibility = View.INVISIBLE
|
||||||
|
hangupButton.visibility = View.VISIBLE
|
||||||
|
Handler().postDelayed({
|
||||||
|
if (!call(ua, uri, "outgoing")) {
|
||||||
|
am.mode = AudioManager.MODE_NORMAL
|
||||||
|
callButton.visibility = View.VISIBLE
|
||||||
|
hangupButton.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
}, 2500)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val latest = CallHistory.aorLatestHistory(aor)
|
val latest = CallHistory.aorLatestHistory(aor)
|
||||||
if (latest != null)
|
if (latest != null)
|
||||||
@@ -976,12 +991,12 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun call(ua: UserAgent, uri: String, status: String) {
|
private fun call(ua: UserAgent, uri: String, status: String): Boolean {
|
||||||
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.RECORD_AUDIO)
|
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.RECORD_AUDIO)
|
||||||
== PackageManager.PERMISSION_DENIED) {
|
== PackageManager.PERMISSION_DENIED) {
|
||||||
Toast.makeText(applicationContext,
|
Toast.makeText(applicationContext,
|
||||||
getString(R.string.no_microphone_permission), Toast.LENGTH_SHORT).show()
|
getString(R.string.no_microphone_permission), Toast.LENGTH_SHORT).show()
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
if (ua != UserAgent.uas()[aorSpinner.selectedItemPosition])
|
if (ua != UserAgent.uas()[aorSpinner.selectedItemPosition])
|
||||||
spinToAor(ua.account.aor)
|
spinToAor(ua.account.aor)
|
||||||
@@ -990,9 +1005,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
Log.d("Baresip", "Adding outgoing call ${ua.uap}/$callp/$uri")
|
Log.d("Baresip", "Adding outgoing call ${ua.uap}/$callp/$uri")
|
||||||
Call.calls().add(Call(callp, ua, uri, "out", status, Utils.dtmfWatcher(callp)))
|
Call.calls().add(Call(callp, ua, uri, "out", status, Utils.dtmfWatcher(callp)))
|
||||||
showCall(ua)
|
showCall(ua)
|
||||||
|
return true
|
||||||
} else {
|
} else {
|
||||||
Log.e("Baresip", "ua_connect ${ua.uap}/$uri failed")
|
Log.e("Baresip", "ua_connect ${ua.uap}/$uri failed")
|
||||||
callButton.visibility = View.VISIBLE
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1040,6 +1056,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private fun showCall(ua: UserAgent) {
|
private fun showCall(ua: UserAgent) {
|
||||||
if (Call.uaCalls(ua, "").size == 0) {
|
if (Call.uaCalls(ua, "").size == 0) {
|
||||||
callTitle.text = getString(R.string.outgoing_call_to_dots)
|
callTitle.text = getString(R.string.outgoing_call_to_dots)
|
||||||
|
callUri.text.clear()
|
||||||
callUri.hint = getString(R.string.callee)
|
callUri.hint = getString(R.string.callee)
|
||||||
callUri.isFocusable = true
|
callUri.isFocusable = true
|
||||||
callUri.isFocusableInTouchMode = true
|
callUri.isFocusableInTouchMode = true
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- Use communication mode only when call is (being) established.
|
||||||
|
- Introduced 2.5 sec delay to placing of a call in order to avoid loss of
|
||||||
|
audio at the beginning of call.
|
||||||
|
- Fixed initializing default contacts when baresip is started the first time.
|
||||||
|
- Clear call URI when call is closed.
|
||||||
Reference in New Issue
Block a user