Added possibility to use Android contacts
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
class AndroidContact(val id: Long, var name: String, var color: Int, val thumbnailUri: String?) {
|
class AndroidContact(val id: Long, var name: String, var color: Int, var thumbnailUri: Uri?) {
|
||||||
|
|
||||||
val uris = ArrayList<String>()
|
val uris = ArrayList<String>()
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,16 @@
|
|||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.*
|
import android.widget.ImageView
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import android.widget.LinearLayout
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.cardview.widget.CardView
|
import androidx.cardview.widget.CardView
|
||||||
import androidx.core.app.ActivityCompat
|
|
||||||
import androidx.core.net.toUri
|
|
||||||
import com.google.android.material.snackbar.Snackbar
|
|
||||||
import com.tutpro.baresip.Utils.showSnackBar
|
|
||||||
import com.tutpro.baresip.databinding.ActivityAndroidContactBinding
|
import com.tutpro.baresip.databinding.ActivityAndroidContactBinding
|
||||||
|
|
||||||
class AndroidContactActivity : AppCompatActivity() {
|
class AndroidContactActivity : AppCompatActivity() {
|
||||||
@@ -28,7 +23,6 @@ class AndroidContactActivity : AppCompatActivity() {
|
|||||||
private lateinit var nameView: TextView
|
private lateinit var nameView: TextView
|
||||||
private lateinit var ulAdapter: AndroidUriListAdapter
|
private lateinit var ulAdapter: AndroidUriListAdapter
|
||||||
private lateinit var aor: String
|
private lateinit var aor: String
|
||||||
private lateinit var requestPermissionsLauncher: ActivityResultLauncher<Array<String>>
|
|
||||||
|
|
||||||
private var index = 0
|
private var index = 0
|
||||||
private var color = 0
|
private var color = 0
|
||||||
@@ -49,7 +43,7 @@ class AndroidContactActivity : AppCompatActivity() {
|
|||||||
cardImageAvatarView = binding.ImageAvatar
|
cardImageAvatarView = binding.ImageAvatar
|
||||||
nameView = binding.Name
|
nameView = binding.Name
|
||||||
|
|
||||||
val contact = AndroidContactsActivity.androidContacts[index]
|
val contact = BaresipService.androidContacts[index]
|
||||||
val name = contact.name
|
val name = contact.name
|
||||||
color = contact.color
|
color = contact.color
|
||||||
id = contact.id
|
id = contact.id
|
||||||
@@ -69,53 +63,6 @@ class AndroidContactActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
requestPermissionsLauncher =
|
|
||||||
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
|
|
||||||
grandResults: IntArray) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grandResults)
|
|
||||||
when (requestCode) {
|
|
||||||
CONTACT_PERMISSION_REQUEST_CODE -> {
|
|
||||||
var allowed = true
|
|
||||||
for (res in grandResults)
|
|
||||||
allowed = allowed && res == PackageManager.PERMISSION_GRANTED
|
|
||||||
if (!allowed) {
|
|
||||||
when {
|
|
||||||
ActivityCompat.shouldShowRequestPermissionRationale(this,
|
|
||||||
Manifest.permission.READ_CONTACTS) -> {
|
|
||||||
layout.showSnackBar(
|
|
||||||
binding.root,
|
|
||||||
getString(R.string.no_android_contacts),
|
|
||||||
Snackbar.LENGTH_INDEFINITE,
|
|
||||||
getString(R.string.ok)
|
|
||||||
) {
|
|
||||||
requestPermissionsLauncher.launch(permissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ActivityCompat.shouldShowRequestPermissionRationale(this,
|
|
||||||
Manifest.permission.WRITE_CONTACTS) -> {
|
|
||||||
layout.showSnackBar(
|
|
||||||
binding.root,
|
|
||||||
getString(R.string.no_android_contacts),
|
|
||||||
Snackbar.LENGTH_INDEFINITE,
|
|
||||||
getString(R.string.ok)
|
|
||||||
) {
|
|
||||||
requestPermissionsLauncher.launch(permissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
requestPermissionsLauncher.launch(permissions)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
|
||||||
if (BaresipService.activities.indexOf("android contact,$aor,$index") == -1) return true
|
if (BaresipService.activities.indexOf("android contact,$aor,$index") == -1) return true
|
||||||
@@ -151,10 +98,10 @@ class AndroidContactActivity : AppCompatActivity() {
|
|||||||
textAvatarView.text = "${name[0]}"
|
textAvatarView.text = "${name[0]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showImageAvatar(thumbNailUri: String) {
|
private fun showImageAvatar(thumbNailUri: Uri) {
|
||||||
textAvatarView.visibility = View.GONE
|
textAvatarView.visibility = View.GONE
|
||||||
cardAvatarView.visibility = View.VISIBLE
|
cardAvatarView.visibility = View.VISIBLE
|
||||||
cardImageAvatarView.setImageURI(thumbNailUri.toUri())
|
cardImageAvatarView.setImageURI(thumbNailUri)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import android.widget.ArrayAdapter
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.core.content.ContextCompat.startActivity
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.core.net.toUri
|
|
||||||
|
|
||||||
class AndroidContactListAdapter(private val ctx: Context,
|
class AndroidContactListAdapter(private val ctx: Context,
|
||||||
private val rows: ArrayList<AndroidContact>,
|
private val rows: ArrayList<AndroidContact>,
|
||||||
@@ -45,7 +44,7 @@ class AndroidContactListAdapter(private val ctx: Context,
|
|||||||
|
|
||||||
val thumbNailUri = contact.thumbnailUri
|
val thumbNailUri = contact.thumbnailUri
|
||||||
if (thumbNailUri != null) {
|
if (thumbNailUri != null) {
|
||||||
viewHolder.imageAvatarView.setImageURI(thumbNailUri.toUri())
|
viewHolder.imageAvatarView.setImageURI(thumbNailUri)
|
||||||
} else {
|
} else {
|
||||||
contact.color = Utils.randomColor()
|
contact.color = Utils.randomColor()
|
||||||
viewHolder.textAvatarView.background.setTint(contact.color)
|
viewHolder.textAvatarView.background.setTint(contact.color)
|
||||||
|
|||||||
@@ -1,35 +1,64 @@
|
|||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.*
|
import android.content.*
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.widget.RelativeLayout
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import com.tutpro.baresip.Utils.showSnackBar
|
||||||
import com.tutpro.baresip.databinding.ActivityAndroidContactsBinding
|
import com.tutpro.baresip.databinding.ActivityAndroidContactsBinding
|
||||||
|
|
||||||
class AndroidContactsActivity : AppCompatActivity() {
|
class AndroidContactsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityAndroidContactsBinding
|
private lateinit var binding: ActivityAndroidContactsBinding
|
||||||
|
private lateinit var layout: RelativeLayout
|
||||||
private lateinit var clAdapter: AndroidContactListAdapter
|
private lateinit var clAdapter: AndroidContactListAdapter
|
||||||
private lateinit var aor: String
|
private lateinit var aor: String
|
||||||
private var lastSwap: Long = 0
|
private var lastSwap: Long = 0
|
||||||
|
private lateinit var permissionsLauncher: ActivityResultLauncher<Array<String>>
|
||||||
|
private val permissions = arrayOf(Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)
|
||||||
|
|
||||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityAndroidContactsBinding.inflate(layoutInflater)
|
binding = ActivityAndroidContactsBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
layout = binding.AndroidContactsView
|
||||||
|
|
||||||
aor = intent.getStringExtra("aor")!!
|
aor = intent.getStringExtra("aor")!!
|
||||||
|
|
||||||
val listView = binding.androidContacts
|
val listView = binding.androidContacts
|
||||||
|
|
||||||
getAndroidContacts(this)
|
permissionsLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
|
||||||
clAdapter = AndroidContactListAdapter(this, androidContacts, aor)
|
var allowed = true
|
||||||
|
permissions.entries.forEach {
|
||||||
|
allowed = allowed && it.value
|
||||||
|
}
|
||||||
|
if (allowed) {
|
||||||
|
fetchAndroidContacts(this)
|
||||||
|
clAdapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= 23 && !Utils.checkPermissions(this, permissions))
|
||||||
|
requestPermissions(permissions, CONTACT_PERMISSION_REQUEST_CODE)
|
||||||
|
else
|
||||||
|
fetchAndroidContacts(this)
|
||||||
|
|
||||||
|
clAdapter = AndroidContactListAdapter(this, BaresipService.androidContacts, aor)
|
||||||
listView.adapter = clAdapter
|
listView.adapter = clAdapter
|
||||||
|
|
||||||
Utils.addActivity("android contacts,$aor")
|
Utils.addActivity("android contacts,$aor")
|
||||||
@@ -45,7 +74,7 @@ class AndroidContactsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
|
|
||||||
R.id.swapContactsIcon -> {
|
R.id.swapIcon -> {
|
||||||
if (SystemClock.elapsedRealtime() - lastSwap > 1000) {
|
if (SystemClock.elapsedRealtime() - lastSwap > 1000) {
|
||||||
lastSwap = SystemClock.elapsedRealtime()
|
lastSwap = SystemClock.elapsedRealtime()
|
||||||
BaresipService.activities.remove("android contacts,$aor")
|
BaresipService.activities.remove("android contacts,$aor")
|
||||||
@@ -76,30 +105,78 @@ class AndroidContactsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getAndroidContacts(ctx: Context) {
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
|
||||||
|
grandResults: IntArray) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grandResults)
|
||||||
|
when (requestCode) {
|
||||||
|
CONTACT_PERMISSION_REQUEST_CODE -> {
|
||||||
|
var allowed = true
|
||||||
|
for (res in grandResults)
|
||||||
|
allowed = allowed && res == PackageManager.PERMISSION_GRANTED
|
||||||
|
if (allowed) {
|
||||||
|
fetchAndroidContacts(this)
|
||||||
|
clAdapter.notifyDataSetChanged()
|
||||||
|
} else {
|
||||||
|
when {
|
||||||
|
ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||||
|
Manifest.permission.READ_CONTACTS) -> {
|
||||||
|
layout.showSnackBar(
|
||||||
|
binding.root,
|
||||||
|
getString(R.string.no_android_contacts),
|
||||||
|
Snackbar.LENGTH_INDEFINITE,
|
||||||
|
getString(R.string.ok)
|
||||||
|
) {
|
||||||
|
permissionsLauncher.launch(permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||||
|
Manifest.permission.WRITE_CONTACTS) -> {
|
||||||
|
layout.showSnackBar(
|
||||||
|
binding.root,
|
||||||
|
getString(R.string.no_android_contacts),
|
||||||
|
Snackbar.LENGTH_INDEFINITE,
|
||||||
|
getString(R.string.ok)
|
||||||
|
) {
|
||||||
|
permissionsLauncher.launch(permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
permissionsLauncher.launch(permissions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun fetchAndroidContacts(ctx: Context) {
|
||||||
val projection = arrayOf(ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME,
|
val projection = arrayOf(ContactsContract.Data.CONTACT_ID, ContactsContract.Data.DISPLAY_NAME,
|
||||||
ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1,
|
ContactsContract.Data.MIMETYPE, ContactsContract.Data.DATA1,
|
||||||
ContactsContract.Data.PHOTO_THUMBNAIL_URI)
|
ContactsContract.Data.PHOTO_THUMBNAIL_URI)
|
||||||
val selection =
|
val selection =
|
||||||
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' OR " +
|
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' OR " +
|
||||||
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'"
|
ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE + "'"
|
||||||
Log.d(TAG, "******* selection = /$selection/")
|
|
||||||
val cur: Cursor? = ctx.contentResolver.query(ContactsContract.Data.CONTENT_URI, projection,
|
val cur: Cursor? = ctx.contentResolver.query(ContactsContract.Data.CONTENT_URI, projection,
|
||||||
selection, null, null)
|
selection, null, null)
|
||||||
val contacts = HashMap<Long, AndroidContact>()
|
val contacts = HashMap<Long, AndroidContact>()
|
||||||
while (cur != null && cur.moveToNext()) {
|
while (cur != null && cur.moveToNext()) {
|
||||||
val id = cur.getLong(0)
|
val id = cur.getLong(0)
|
||||||
val name = cur.getString(1) // display name
|
val name = cur.getString(1) ?: ""
|
||||||
val mime = cur.getString(2) // type of data
|
val mime = cur.getString(2)
|
||||||
val data = cur.getString(3) // data
|
val data = cur.getString(3)
|
||||||
val thumb = cur.getString(4) // thumbnail
|
val thumb = cur.getString(4)?.toUri()
|
||||||
// Log.d(TAG, "****** $id - $name - $mime - $data - $thumb")
|
|
||||||
val contact = if (contacts.containsKey(id))
|
val contact = if (contacts.containsKey(id))
|
||||||
contacts[id]!!
|
contacts[id]!!
|
||||||
else
|
else
|
||||||
AndroidContact(id, name, 0, thumb)
|
AndroidContact(id, name, 0, thumb)
|
||||||
|
if (contact.name == "" && name != "")
|
||||||
|
contact.name = name
|
||||||
|
if (contact.thumbnailUri == null && thumb != null)
|
||||||
|
contact.thumbnailUri = thumb
|
||||||
if (mime == ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
if (mime == ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
|
||||||
contact.uris.add("tel:$data")
|
contact.uris.add("tel:${data.filterNot{setOf('-', ' ').contains(it)}}")
|
||||||
else if (mime == ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
else if (mime == ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
||||||
contact.uris.add("sip:$data")
|
contact.uris.add("sip:$data")
|
||||||
else
|
else
|
||||||
@@ -108,14 +185,30 @@ class AndroidContactsActivity : AppCompatActivity() {
|
|||||||
contacts[id] = contact
|
contacts[id] = contact
|
||||||
}
|
}
|
||||||
cur?.close()
|
cur?.close()
|
||||||
androidContacts.clear()
|
BaresipService.androidContacts.clear()
|
||||||
for ((_, value) in contacts)
|
for ((_, value) in contacts)
|
||||||
androidContacts.add(value)
|
if (value.name != "")
|
||||||
|
BaresipService.androidContacts.add(value)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
fun findContact(uri: String): AndroidContact? {
|
||||||
val androidContacts = ArrayList<AndroidContact>()
|
for (c in BaresipService.androidContacts)
|
||||||
|
for (u in c.uris)
|
||||||
|
if (Utils.uriMatch(u, uri))
|
||||||
|
return c
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return contact name of uri or uri itself if contact with uri is not found
|
||||||
|
fun contactName(uri: String): String {
|
||||||
|
val userPart = Utils.uriUserPart(uri)
|
||||||
|
return if (Utils.isTelNumber(userPart))
|
||||||
|
findContact("tel:$userPart")?.name ?: uri
|
||||||
|
else
|
||||||
|
findContact(uri)?.name ?: uri
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ class BaresipService: Service() {
|
|||||||
this.registerReceiver(bluetoothReceiver, filter)
|
this.registerReceiver(bluetoothReceiver, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AndroidContactsActivity.fetchAndroidContacts(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
@@ -648,8 +649,7 @@ class BaresipService: Service() {
|
|||||||
PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, intent,
|
PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, intent,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
||||||
val caller = Utils.friendlyUri(ContactsActivity.contactName(peerUri),
|
val caller = Utils.friendlyUri(Utils.contactName(peerUri), Utils.aorDomain(aor))
|
||||||
Utils.aorDomain(aor))
|
|
||||||
nb.setSmallIcon(R.drawable.ic_stat_call)
|
nb.setSmallIcon(R.drawable.ic_stat_call)
|
||||||
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
|
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
|
||||||
.setContentIntent(pi)
|
.setContentIntent(pi)
|
||||||
@@ -743,8 +743,7 @@ class BaresipService: Service() {
|
|||||||
PendingIntent.getActivity(applicationContext, TRANSFER_REQ_CODE,
|
PendingIntent.getActivity(applicationContext, 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)
|
||||||
val target = Utils.friendlyUri(ContactsActivity.contactName(ev[1]),
|
val target = Utils.friendlyUri(Utils.contactName(ev[1]), Utils.aorDomain(aor))
|
||||||
Utils.aorDomain(aor))
|
|
||||||
nb.setSmallIcon(R.drawable.ic_stat_call)
|
nb.setSmallIcon(R.drawable.ic_stat_call)
|
||||||
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
|
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
|
||||||
.setContentIntent(pi)
|
.setContentIntent(pi)
|
||||||
@@ -820,8 +819,7 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
if (!Utils.isVisible()) {
|
if (!Utils.isVisible()) {
|
||||||
if (missed) {
|
if (missed) {
|
||||||
val caller = Utils.friendlyUri(ContactsActivity.contactName(call.peerUri),
|
val caller = Utils.friendlyUri(Utils.contactName(call.peerUri), Utils.aorDomain(aor))
|
||||||
Utils.aorDomain(aor))
|
|
||||||
val intent = Intent(applicationContext, MainActivity::class.java)
|
val intent = Intent(applicationContext, MainActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
|
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or
|
||||||
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
@@ -927,8 +925,7 @@ class BaresipService: Service() {
|
|||||||
PendingIntent.getActivity(applicationContext, MESSAGE_REQ_CODE, intent,
|
PendingIntent.getActivity(applicationContext, MESSAGE_REQ_CODE, intent,
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT)
|
PendingIntent.FLAG_UPDATE_CURRENT)
|
||||||
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID)
|
||||||
val sender = Utils.friendlyUri(ContactsActivity.contactName(peer),
|
val sender = Utils.friendlyUri(Utils.contactName(peer), Utils.aorDomain(ua.account.aor))
|
||||||
Utils.aorDomain(ua.account.aor))
|
|
||||||
nb.setSmallIcon(R.drawable.ic_stat_message)
|
nb.setSmallIcon(R.drawable.ic_stat_message)
|
||||||
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
|
.setColor(ContextCompat.getColor(this, R.color.colorBaresip))
|
||||||
.setContentIntent(pi)
|
.setContentIntent(pi)
|
||||||
@@ -1111,8 +1108,12 @@ class BaresipService: Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun requestAudioFocus(type: Int) {
|
private fun requestAudioFocus(type: Int) {
|
||||||
if (audioFocusRequest != null && audioFocusRequest!!.audioAttributesCompat.contentType == type)
|
if (audioFocusRequest != null) {
|
||||||
|
if (audioFocusRequest!!.audioAttributesCompat.contentType == type)
|
||||||
return
|
return
|
||||||
|
else
|
||||||
|
abandonAudioFocus()
|
||||||
|
}
|
||||||
val attributes = AudioAttributesCompat.Builder()
|
val attributes = AudioAttributesCompat.Builder()
|
||||||
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
|
.setUsage(AudioAttributesCompat.USAGE_VOICE_COMMUNICATION)
|
||||||
.setContentType(type)
|
.setContentType(type)
|
||||||
@@ -1418,6 +1419,7 @@ class BaresipService: Service() {
|
|||||||
val messageUpdate = MutableLiveData<Long>()
|
val messageUpdate = MutableLiveData<Long>()
|
||||||
val registrationUpdate = MutableLiveData<Long>()
|
val registrationUpdate = MutableLiveData<Long>()
|
||||||
val contacts = ArrayList<Contact>()
|
val contacts = ArrayList<Contact>()
|
||||||
|
val androidContacts = ArrayList<AndroidContact>()
|
||||||
val chatTexts: MutableMap<String, String> = mutableMapOf()
|
val chatTexts: MutableMap<String, String> = mutableMapOf()
|
||||||
val activities = mutableListOf<String>()
|
val activities = mutableListOf<String>()
|
||||||
var dnsServers = listOf<InetAddress>()
|
var dnsServers = listOf<InetAddress>()
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.tutpro.baresip
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -12,8 +11,6 @@ import android.widget.ImageView
|
|||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class CallListAdapter(private val ctx: Context, private val aor: String, private val rows: ArrayList<CallRow>) :
|
class CallListAdapter(private val ctx: Context, private val aor: String, private val rows: ArrayList<CallRow>) :
|
||||||
ArrayAdapter<CallRow>(ctx, R.layout.call_row, rows) {
|
ArrayAdapter<CallRow>(ctx, R.layout.call_row, rows) {
|
||||||
|
|
||||||
@@ -44,23 +41,7 @@ class CallListAdapter(private val ctx: Context, private val aor: String, private
|
|||||||
|
|
||||||
val callRow = rows[position]
|
val callRow = rows[position]
|
||||||
|
|
||||||
val contact = ContactsActivity.findContact(callRow.peerUri)
|
Utils.setAvatar(ctx, viewHolder.imageAvatarView, viewHolder.textAvatarView, callRow.peerUri)
|
||||||
if (contact != null) {
|
|
||||||
val avatarImage = contact.avatarImage
|
|
||||||
if (avatarImage != null) {
|
|
||||||
viewHolder.imageAvatarView.setImageBitmap(avatarImage)
|
|
||||||
} else {
|
|
||||||
viewHolder.textAvatarView.background.setTint(contact.color)
|
|
||||||
if (contact.name.isNotEmpty())
|
|
||||||
viewHolder.textAvatarView.text = "${contact.name[0]}"
|
|
||||||
else
|
|
||||||
viewHolder.textAvatarView.text = ""
|
|
||||||
viewHolder.imageAvatarView.setImageBitmap(Utils.bitmapFromView(viewHolder.textAvatarView))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val bitmap = BitmapFactory.decodeResource(ctx.resources, R.drawable.person_image)
|
|
||||||
viewHolder.imageAvatarView.setImageBitmap(bitmap)
|
|
||||||
}
|
|
||||||
|
|
||||||
viewHolder.directionsView.removeAllViews()
|
viewHolder.directionsView.removeAllViews()
|
||||||
var count = 1
|
var count = 1
|
||||||
@@ -81,7 +62,7 @@ class CallListAdapter(private val ctx: Context, private val aor: String, private
|
|||||||
if (count <= 3)
|
if (count <= 3)
|
||||||
viewHolder.etcView.text = ""
|
viewHolder.etcView.text = ""
|
||||||
|
|
||||||
val contactName = ContactsActivity.contactName(callRow.peerUri)
|
val contactName = Utils.contactName(callRow.peerUri)
|
||||||
if (contactName.startsWith("sip:"))
|
if (contactName.startsWith("sip:"))
|
||||||
viewHolder.peerURIView.text = Utils.friendlyUri(contactName, Utils.aorDomain(callRow.aor))
|
viewHolder.peerURIView.text = Utils.friendlyUri(contactName, Utils.aorDomain(callRow.aor))
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class CallsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
listView.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ ->
|
listView.onItemClickListener = AdapterView.OnItemClickListener { _, _, pos, _ ->
|
||||||
val peerUri = uaHistory[pos].peerUri
|
val peerUri = uaHistory[pos].peerUri
|
||||||
var peerName = ContactsActivity.contactName(peerUri)
|
var peerName = Utils.contactName(peerUri)
|
||||||
if (peerName.startsWith("sip:"))
|
if (peerName.startsWith("sip:"))
|
||||||
peerName = Utils.friendlyUri(peerName, Utils.aorDomain(aor))
|
peerName = Utils.friendlyUri(peerName, Utils.aorDomain(aor))
|
||||||
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
||||||
@@ -95,7 +95,7 @@ class CallsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
listView.onItemLongClickListener = AdapterView.OnItemLongClickListener { _, _, pos, _ ->
|
listView.onItemLongClickListener = AdapterView.OnItemLongClickListener { _, _, pos, _ ->
|
||||||
val peerUri = uaHistory[pos].peerUri
|
val peerUri = uaHistory[pos].peerUri
|
||||||
val peerName = ContactsActivity.contactName(peerUri)
|
val peerName = Utils.contactName(peerUri)
|
||||||
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
val dialogClickListener = DialogInterface.OnClickListener { _, which ->
|
||||||
when (which) {
|
when (which) {
|
||||||
DialogInterface.BUTTON_NEGATIVE -> {
|
DialogInterface.BUTTON_NEGATIVE -> {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class ChatActivity : AppCompatActivity() {
|
|||||||
imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
this@ChatActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
|
this@ChatActivity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
|
||||||
|
|
||||||
var chatPeer = ContactsActivity.contactName(peerUri)
|
var chatPeer = Utils.contactName(peerUri)
|
||||||
if (chatPeer.startsWith("sip:"))
|
if (chatPeer.startsWith("sip:"))
|
||||||
chatPeer = Utils.friendlyUri(chatPeer, Utils.aorDomain(aor))
|
chatPeer = Utils.friendlyUri(chatPeer, Utils.aorDomain(aor))
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ class ChatActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val builder = AlertDialog.Builder(this@ChatActivity, R.style.Theme_AppCompat)
|
val builder = AlertDialog.Builder(this@ChatActivity, R.style.Theme_AppCompat)
|
||||||
if (ContactsActivity.contactName(peerUri) == peerUri)
|
if (Utils.contactName(peerUri) == peerUri)
|
||||||
with (builder) {
|
with (builder) {
|
||||||
setMessage(String.format(getString(R.string.long_message_question),
|
setMessage(String.format(getString(R.string.long_message_question),
|
||||||
chatPeer))
|
chatPeer))
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
package com.tutpro.baresip
|
package com.tutpro.baresip
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.BitmapFactory
|
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import android.text.format.DateUtils.isToday
|
import android.text.format.DateUtils.isToday
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.*
|
import android.widget.ArrayAdapter
|
||||||
|
import android.widget.ImageView
|
||||||
import java.util.*
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class ChatListAdapter(private val ctx: Context, private val rows: ArrayList<Message>) :
|
class ChatListAdapter(private val ctx: Context, private val rows: ArrayList<Message>) :
|
||||||
ArrayAdapter<Message>(ctx, R.layout.message, rows) {
|
ArrayAdapter<Message>(ctx, R.layout.message, rows) {
|
||||||
@@ -43,26 +44,7 @@ class ChatListAdapter(private val ctx: Context, private val rows: ArrayList<Mess
|
|||||||
|
|
||||||
val message = rows[position]
|
val message = rows[position]
|
||||||
|
|
||||||
val contact = ContactsActivity.findContact(message.peerUri)
|
Utils.setAvatar(ctx, viewHolder.imageAvatarView, viewHolder.textAvatarView, message.peerUri)
|
||||||
val peer: String
|
|
||||||
if (contact != null) {
|
|
||||||
peer = contact.name
|
|
||||||
val avatarImage = contact.avatarImage
|
|
||||||
if (avatarImage != null) {
|
|
||||||
viewHolder.imageAvatarView.setImageBitmap(avatarImage)
|
|
||||||
} else {
|
|
||||||
viewHolder.textAvatarView.background.setTint(contact.color)
|
|
||||||
if (peer.isNotEmpty())
|
|
||||||
viewHolder.textAvatarView.text = "${peer[0]}"
|
|
||||||
else
|
|
||||||
viewHolder.textAvatarView.text = ""
|
|
||||||
viewHolder.imageAvatarView.setImageBitmap(Utils.bitmapFromView(viewHolder.textAvatarView))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
peer = Utils.friendlyUri(message.peerUri, message.aor)
|
|
||||||
val bitmap = BitmapFactory.decodeResource(ctx.resources, R.drawable.person_image)
|
|
||||||
viewHolder.imageAvatarView.setImageBitmap(bitmap)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((message.direction == R.drawable.arrow_down_green) ||
|
if ((message.direction == R.drawable.arrow_down_green) ||
|
||||||
(message.direction == R.drawable.arrow_down_red))
|
(message.direction == R.drawable.arrow_down_red))
|
||||||
@@ -70,7 +52,11 @@ class ChatListAdapter(private val ctx: Context, private val rows: ArrayList<Mess
|
|||||||
else
|
else
|
||||||
viewHolder.layoutView.setBackgroundResource(R.drawable.message_out_bg)
|
viewHolder.layoutView.setBackgroundResource(R.drawable.message_out_bg)
|
||||||
|
|
||||||
viewHolder.peerView.text = peer
|
val peerName = Utils.contactName(message.peerUri)
|
||||||
|
viewHolder.peerView.text = if (peerName !=message.peerUri )
|
||||||
|
peerName
|
||||||
|
else
|
||||||
|
Utils.friendlyUri(message.peerUri, message.aor)
|
||||||
|
|
||||||
val cal = GregorianCalendar()
|
val cal = GregorianCalendar()
|
||||||
cal.timeInMillis = message.timeStamp
|
cal.timeInMillis = message.timeStamp
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class ChatsActivity: AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val builder = AlertDialog.Builder(this@ChatsActivity, R.style.Theme_AppCompat)
|
val builder = AlertDialog.Builder(this@ChatsActivity, R.style.Theme_AppCompat)
|
||||||
val peer = ContactsActivity.contactName(uaMessages[pos].peerUri)
|
val peer = Utils.contactName(uaMessages[pos].peerUri)
|
||||||
if (peer.startsWith("sip:"))
|
if (peer.startsWith("sip:"))
|
||||||
with (builder) {
|
with (builder) {
|
||||||
setMessage(String.format(getString(R.string.long_chat_question),
|
setMessage(String.format(getString(R.string.long_chat_question),
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ import android.content.Intent
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.provider.Settings
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -528,13 +526,6 @@ class ConfigActivity : AppCompatActivity() {
|
|||||||
binding.AudioSettingsTitle.setOnClickListener {
|
binding.AudioSettingsTitle.setOnClickListener {
|
||||||
startActivity(Intent(this, AudioActivity::class.java))
|
startActivity(Intent(this, AudioActivity::class.java))
|
||||||
}
|
}
|
||||||
binding.AndroidSettings.setOnClickListener {
|
|
||||||
val i = Intent()
|
|
||||||
i.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
|
||||||
i.data = Uri.parse("package:${applicationContext.packageName}")
|
|
||||||
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
|
|
||||||
startActivity(i)
|
|
||||||
}
|
|
||||||
binding.DarkThemeTitle.setOnClickListener {
|
binding.DarkThemeTitle.setOnClickListener {
|
||||||
Utils.alertView(this, getString(R.string.dark_theme),
|
Utils.alertView(this, getString(R.string.dark_theme),
|
||||||
getString(R.string.dark_theme_help))
|
getString(R.string.dark_theme_help))
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import com.tutpro.baresip.databinding.ActivityContactBinding
|
|||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
class ContactActivity : AppCompatActivity() {
|
class ContactActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityContactBinding
|
private lateinit var binding: ActivityContactBinding
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ class ContactsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
|
|
||||||
R.id.swapContactsIcon -> {
|
R.id.swapIcon -> {
|
||||||
if (SystemClock.elapsedRealtime() - lastClick > 1000) {
|
if (SystemClock.elapsedRealtime() - lastClick > 1000) {
|
||||||
lastClick = SystemClock.elapsedRealtime()
|
lastClick = SystemClock.elapsedRealtime()
|
||||||
BaresipService.activities.remove("contacts,$aor")
|
BaresipService.activities.remove("contacts,$aor")
|
||||||
@@ -117,9 +117,10 @@ class ContactsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun findContact(uri: String): Contact? {
|
fun findContact(uri: String): Contact? {
|
||||||
for (c in Contact.contacts())
|
for (c in Contact.contacts()) {
|
||||||
if (Utils.uriMatch(c.uri, uri))
|
if (Utils.uriMatch(c.uri, uri))
|
||||||
return c
|
return c
|
||||||
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1105,8 +1105,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
val call = Call.ofCallp(callp)!!
|
val call = Call.ofCallp(callp)!!
|
||||||
val titleView = View.inflate(this, R.layout.alert_title, null) as TextView
|
val titleView = View.inflate(this, R.layout.alert_title, null) as TextView
|
||||||
titleView.text = getString(R.string.transfer_request)
|
titleView.text = getString(R.string.transfer_request)
|
||||||
val target = Utils.friendlyUri(ContactsActivity.contactName(ev[1]),
|
val target = Utils.friendlyUri(Utils.contactName(ev[1]), Utils.aorDomain(aor))
|
||||||
Utils.aorDomain(aor))
|
|
||||||
with(AlertDialog.Builder(this)) {
|
with(AlertDialog.Builder(this)) {
|
||||||
setCustomTitle(titleView)
|
setCustomTitle(titleView)
|
||||||
setMessage(String.format(getString(R.string.transfer_request_query),
|
setMessage(String.format(getString(R.string.transfer_request_query),
|
||||||
@@ -1752,8 +1751,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
val latest = NewCallHistory.aorLatestHistory(aor)
|
val latest = NewCallHistory.aorLatestHistory(aor)
|
||||||
if (latest != null)
|
if (latest != null)
|
||||||
callUri.setText(
|
callUri.setText(
|
||||||
Utils.friendlyUri(
|
Utils.friendlyUri(Utils.contactName(latest.peerUri), Utils.aorDomain(aor)
|
||||||
ContactsActivity.contactName(latest.peerUri), Utils.aorDomain(aor)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1799,7 +1797,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
else
|
else
|
||||||
getString(R.string.outgoing_call_to_dots)
|
getString(R.string.outgoing_call_to_dots)
|
||||||
callTimer.visibility = View.INVISIBLE
|
callTimer.visibility = View.INVISIBLE
|
||||||
callUri.setText(Utils.friendlyUri(ContactsActivity.contactName(call.peerUri),
|
callUri.setText(Utils.friendlyUri(Utils.contactName(call.peerUri),
|
||||||
Utils.aorDomain(ua.account.aor)))
|
Utils.aorDomain(ua.account.aor)))
|
||||||
securityButton.visibility = View.INVISIBLE
|
securityButton.visibility = View.INVISIBLE
|
||||||
callButton.visibility = View.INVISIBLE
|
callButton.visibility = View.INVISIBLE
|
||||||
@@ -1814,7 +1812,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
"incoming" -> {
|
"incoming" -> {
|
||||||
callTitle.text = getString(R.string.incoming_call_from_dots)
|
callTitle.text = getString(R.string.incoming_call_from_dots)
|
||||||
callTimer.visibility = View.INVISIBLE
|
callTimer.visibility = View.INVISIBLE
|
||||||
callUri.setText(Utils.friendlyUri(ContactsActivity.contactName(call.peerUri),
|
callUri.setText(Utils.friendlyUri(Utils.contactName(call.peerUri),
|
||||||
Utils.aorDomain(ua.account.aor)))
|
Utils.aorDomain(ua.account.aor)))
|
||||||
callUri.setAdapter(null)
|
callUri.setAdapter(null)
|
||||||
securityButton.visibility = View.INVISIBLE
|
securityButton.visibility = View.INVISIBLE
|
||||||
@@ -1834,7 +1832,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
if (call.referTo != "") {
|
if (call.referTo != "") {
|
||||||
callTitle.text = getString(R.string.transferring_call_to_dots)
|
callTitle.text = getString(R.string.transferring_call_to_dots)
|
||||||
callUri.setText(Utils.friendlyUri(ContactsActivity.contactName(call.referTo),
|
callUri.setText(Utils.friendlyUri(Utils.contactName(call.referTo),
|
||||||
Utils.aorDomain(ua.account.aor)))
|
Utils.aorDomain(ua.account.aor)))
|
||||||
transferButton.isEnabled = false
|
transferButton.isEnabled = false
|
||||||
} else {
|
} else {
|
||||||
@@ -1842,7 +1840,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
callTitle.text = getString(R.string.outgoing_call_to_dots)
|
callTitle.text = getString(R.string.outgoing_call_to_dots)
|
||||||
else
|
else
|
||||||
callTitle.text = getString(R.string.incoming_call_from_dots)
|
callTitle.text = getString(R.string.incoming_call_from_dots)
|
||||||
callUri.setText(Utils.friendlyUri(ContactsActivity.contactName(call.peerUri),
|
callUri.setText(Utils.friendlyUri(Utils.contactName(call.peerUri),
|
||||||
Utils.aorDomain(ua.account.aor)))
|
Utils.aorDomain(ua.account.aor)))
|
||||||
transferButton.isEnabled = true
|
transferButton.isEnabled = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class MessageListAdapter(private val ctx: Context, private val rows: ArrayList<M
|
|||||||
val peer: String = if (down) {
|
val peer: String = if (down) {
|
||||||
lp.setMargins(0, 10, 75, 10)
|
lp.setMargins(0, 10, 75, 10)
|
||||||
viewHolder.layoutView.setBackgroundResource(R.drawable.message_in_bg)
|
viewHolder.layoutView.setBackgroundResource(R.drawable.message_in_bg)
|
||||||
val contactName = ContactsActivity.contactName(message.peerUri)
|
val contactName = Utils.contactName(message.peerUri)
|
||||||
if (contactName.startsWith("sip:") &&
|
if (contactName.startsWith("sip:") &&
|
||||||
(Utils.uriHostPart(message.peerUri) == Utils.uriHostPart(message.aor)))
|
(Utils.uriHostPart(message.peerUri) == Utils.uriHostPart(message.aor)))
|
||||||
Utils.uriUserPart(message.peerUri)
|
Utils.uriUserPart(message.peerUri)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import android.content.Intent
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Bitmap.createScaledBitmap
|
import android.graphics.Bitmap.createScaledBitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.net.*
|
import android.net.*
|
||||||
@@ -22,6 +23,7 @@ import android.text.TextWatcher
|
|||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
@@ -107,7 +109,7 @@ object Utils {
|
|||||||
|
|
||||||
fun uriMatch(firstUri: String, secondUri: String): Boolean {
|
fun uriMatch(firstUri: String, secondUri: String): Boolean {
|
||||||
if (firstUri.startsWith("tel:"))
|
if (firstUri.startsWith("tel:"))
|
||||||
return firstUri == secondUri
|
return firstUri == secondUri || firstUri.substringAfter(":") == uriUserPart(secondUri)
|
||||||
if (firstUri.startsWith("sip:"))
|
if (firstUri.startsWith("sip:"))
|
||||||
return uriUserPart(firstUri) == uriUserPart(secondUri) &&
|
return uriUserPart(firstUri) == uriUserPart(secondUri) &&
|
||||||
uriHostPart(firstUri) == uriHostPart(secondUri)
|
uriHostPart(firstUri) == uriHostPart(secondUri)
|
||||||
@@ -318,6 +320,49 @@ object Utils {
|
|||||||
name.lines().size == 1 && !name.contains('"')
|
name.lines().size == 1 && !name.contains('"')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun contactName(uri: String) : String {
|
||||||
|
val name = ContactsActivity.contactName(uri)
|
||||||
|
return if (name != uri)
|
||||||
|
name
|
||||||
|
else
|
||||||
|
AndroidContactsActivity.contactName(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setAvatar(ctx: Context, imageView: ImageView, textView: TextView, uri: String) {
|
||||||
|
val contact = ContactsActivity.findContact(uri)
|
||||||
|
if (contact != null) {
|
||||||
|
val avatarImage = contact.avatarImage
|
||||||
|
if (avatarImage != null) {
|
||||||
|
imageView.setImageBitmap(avatarImage)
|
||||||
|
} else {
|
||||||
|
textView.background.setTint(contact.color)
|
||||||
|
if (contact.name.isNotEmpty())
|
||||||
|
textView.text = "${contact.name[0]}"
|
||||||
|
else
|
||||||
|
textView.text = ""
|
||||||
|
imageView.setImageBitmap(bitmapFromView(textView))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val androidContact = AndroidContactsActivity.findContact(uri)
|
||||||
|
if (androidContact != null) {
|
||||||
|
val thumbnailUri = androidContact.thumbnailUri
|
||||||
|
if (thumbnailUri != null) {
|
||||||
|
imageView.setImageURI(thumbnailUri)
|
||||||
|
} else {
|
||||||
|
textView.background.setTint(androidContact.color)
|
||||||
|
if (androidContact.name.isNotEmpty())
|
||||||
|
textView.text = "${androidContact.name[0]}"
|
||||||
|
else
|
||||||
|
textView.text = ""
|
||||||
|
imageView.setImageBitmap(bitmapFromView(textView))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val bitmap = BitmapFactory.decodeResource(ctx.resources, R.drawable.person_image)
|
||||||
|
imageView.setImageBitmap(bitmap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun checkIfName(name: String): Boolean {
|
fun checkIfName(name: String): Boolean {
|
||||||
if ((name.length < 2) || !name.first().isLetter()) return false
|
if ((name.length < 2) || !name.first().isLetter()) return false
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M6.54,5c0.06,0.89 0.21,1.76 0.45,2.59l-1.2,1.2c-0.41,-1.2 -0.67,-2.47 -0.76,-3.79h1.51m9.86,12.02c0.85,0.24 1.72,0.39 2.6,0.45v1.49c-1.32,-0.09 -2.59,-0.35 -3.8,-0.75l1.2,-1.19M7.5,3H4c-0.55,0 -1,0.45 -1,1 0,9.39 7.61,17 17,17 0.55,0 1,-0.45 1,-1v-3.49c0,-0.55 -0.45,-1 -1,-1 -1.24,0 -2.45,-0.2 -3.57,-0.57 -0.1,-0.04 -0.21,-0.05 -0.31,-0.05 -0.26,0 -0.51,0.1 -0.71,0.29l-2.2,2.2c-2.83,-1.45 -5.15,-3.76 -6.59,-6.59l2.2,-2.2c0.28,-0.28 0.36,-0.67 0.25,-1.02C8.7,6.45 8.5,5.25 8.5,4c0,-0.55 -0.45,-1 -1,-1z"/>
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:tint="?attr/colorControlNormal"
|
||||||
|
android:autoMirrored="true">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M21,5c-1.11,-0.35 -2.33,-0.5 -3.5,-0.5c-1.95,0 -4.05,0.4 -5.5,1.5c-1.45,-1.1 -3.55,-1.5 -5.5,-1.5S2.45,4.9 1,6v14.65c0,0.25 0.25,0.5 0.5,0.5c0.1,0 0.15,-0.05 0.25,-0.05C3.1,20.45 5.05,20 6.5,20c1.95,0 4.05,0.4 5.5,1.5c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.65,0 3.35,0.3 4.75,1.05c0.1,0.05 0.15,0.05 0.25,0.05c0.25,0 0.5,-0.25 0.5,-0.5V6C22.4,5.55 21.75,5.25 21,5zM21,18.5c-1.1,-0.35 -2.3,-0.5 -3.5,-0.5c-1.7,0 -4.15,0.65 -5.5,1.5V8c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.2,0 2.4,0.15 3.5,0.5V18.5z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M17.5,10.5c0.88,0 1.73,0.09 2.5,0.26V9.24C19.21,9.09 18.36,9 17.5,9c-1.7,0 -3.24,0.29 -4.5,0.83v1.66C14.13,10.85 15.7,10.5 17.5,10.5z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M13,12.49v1.66c1.13,-0.64 2.7,-0.99 4.5,-0.99c0.88,0 1.73,0.09 2.5,0.26V11.9c-0.79,-0.15 -1.64,-0.24 -2.5,-0.24C15.8,11.66 14.26,11.96 13,12.49z"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M17.5,14.33c-1.7,0 -3.24,0.29 -4.5,0.83v1.66c1.13,-0.64 2.7,-0.99 4.5,-0.99c0.88,0 1.73,0.09 2.5,0.26v-1.52C19.21,14.41 18.36,14.33 17.5,14.33z"/>
|
||||||
|
</vector>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 402 B |
Binary file not shown.
|
Before Width: | Height: | Size: 278 B |
Binary file not shown.
|
Before Width: | Height: | Size: 522 B |
Binary file not shown.
|
Before Width: | Height: | Size: 773 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -1,5 +1,5 @@
|
|||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector android:autoMirrored="true" android:height="24dp"
|
||||||
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
|
android:tint="@android:color/white" android:viewportHeight="24"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<path android:fillColor="#000" android:pathData="M20,15.5C18.8,15.5 17.5,15.3 16.4,14.9C16.3,14.9 16.2,14.9 16.1,14.9C15.8,14.9 15.6,15 15.4,15.2L13.2,17.4C10.4,15.9 8,13.6 6.6,10.8L8.8,8.6C9.1,8.3 9.2,7.9 9,7.6C8.7,6.5 8.5,5.2 8.5,4C8.5,3.5 8,3 7.5,3H4C3.5,3 3,3.5 3,4C3,13.4 10.6,21 20,21C20.5,21 21,20.5 21,20V16.5C21,16 20.5,15.5 20,15.5M5,5H6.5C6.6,5.9 6.8,6.8 7,7.6L5.8,8.8C5.4,7.6 5.1,6.3 5,5M19,19C17.7,18.9 16.4,18.6 15.2,18.2L16.4,17C17.2,17.2 18.1,17.4 19,17.4V19Z"/>
|
<path android:fillColor="#000000" android:pathData="M20,15.5C18.8,15.5 17.5,15.3 16.4,14.9C16.3,14.9 16.2,14.9 16.1,14.9C15.8,14.9 15.6,15 15.4,15.2L13.2,17.4C10.4,15.9 8,13.6 6.6,10.8L8.8,8.6C9.1,8.3 9.2,7.9 9,7.6C8.7,6.5 8.5,5.2 8.5,4C8.5,3.5 8,3 7.5,3H4C3.5,3 3,3.5 3,4C3,13.4 10.6,21 20,21C20.5,21 21,20.5 21,20V16.5C21,16 20.5,15.5 20,15.5M5,5H6.5C6.6,5.9 6.8,6.8 7,7.6L5.8,8.8C5.4,7.6 5.1,6.3 5,5M19,19C17.7,18.9 16.4,18.6 15.2,18.2L16.4,17C17.2,17.2 18.1,17.4 19,17.4V19Z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<vector android:autoMirrored="true" android:height="48dp"
|
|
||||||
android:tint="?attr/colorControlNormal" android:viewportHeight="24"
|
|
||||||
android:viewportWidth="24" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M17.5,4.5c-1.95,0 -4.05,0.4 -5.5,1.5c-1.45,-1.1 -3.55,-1.5 -5.5,-1.5S2.45,4.9 1,6v14.65c0,0.65 0.73,0.45 0.75,0.45C3.1,20.45 5.05,20 6.5,20c1.95,0 4.05,0.4 5.5,1.5c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.65,0 3.35,0.3 4.75,1.05C22.66,21.26 23,20.86 23,20.6V6C21.51,4.88 19.37,4.5 17.5,4.5zM21,18.5c-1.1,-0.35 -2.3,-0.5 -3.5,-0.5c-1.7,0 -4.15,0.65 -5.5,1.5V8c1.35,-0.85 3.8,-1.5 5.5,-1.5c1.2,0 2.4,0.15 3.5,0.5V18.5z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/AndroidContactsView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
|
|||||||
@@ -221,16 +221,6 @@
|
|||||||
android:text="@string/audio_settings" >
|
android:text="@string/audio_settings" >
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/AndroidSettings"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginBottom="12dp"
|
|
||||||
android:text="@string/android_settings"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:textSize="18sp">
|
|
||||||
</TextView>
|
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/aorSpinner"
|
android:layout_below="@id/aorSpinner"
|
||||||
android:layout_marginTop="31dp"
|
android:layout_marginTop="12dp"
|
||||||
android:orientation="horizontal" >
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/swapContactsIcon"
|
android:id="@+id/swapIcon"
|
||||||
android:title=""
|
android:title=""
|
||||||
app:showAsAction="always"
|
app:showAsAction="always"
|
||||||
android:icon="@drawable/swap_contacts" />
|
android:icon="@drawable/ic_test_swap" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
||||||
|
|||||||
@@ -520,7 +520,7 @@
|
|||||||
Tallennustila-käyttöoikeutta.</string>
|
Tallennustila-käyttöoikeutta.</string>
|
||||||
<string name="no_restore">Et voi palauttaa sovelluksen tietoja ilman
|
<string name="no_restore">Et voi palauttaa sovelluksen tietoja ilman
|
||||||
Tallennustila-käyttöoikeutta.</string>
|
Tallennustila-käyttöoikeutta.</string>
|
||||||
<string name="no_android_contacts">Et voi lisätä tai poistaa Android-yhteystietoja ilman
|
<string name="no_android_contacts">Et voi käsitellä Androidin yhteystietoja ilman
|
||||||
Kontaktit-käyttöoikeutta.</string>
|
Kontaktit-käyttöoikeutta.</string>
|
||||||
<string name="no_cameras">Sinulla ei ole yhtään tuettua video-kameraa.</string>
|
<string name="no_cameras">Sinulla ei ole yhtään tuettua video-kameraa.</string>
|
||||||
<string name="show_password">Näytä salasana</string>
|
<string name="show_password">Näytä salasana</string>
|
||||||
|
|||||||
@@ -475,7 +475,7 @@
|
|||||||
<string name="no_video_calls">Grant \"Camera\" permission to make or answer video calls.</string>
|
<string name="no_video_calls">Grant \"Camera\" permission to make or answer video calls.</string>
|
||||||
<string name="no_backup">You are not able create backup without \"Storage\" permission.</string>
|
<string name="no_backup">You are not able create backup without \"Storage\" permission.</string>
|
||||||
<string name="no_restore">You are not able restore backup without \"Storage\" permission.</string>
|
<string name="no_restore">You are not able restore backup without \"Storage\" permission.</string>
|
||||||
<string name="no_android_contacts">You are not able add or remove Android contacts without
|
<string name="no_android_contacts">You are not able to access Android contacts without
|
||||||
\"Contacts\" permission.</string>
|
\"Contacts\" permission.</string>
|
||||||
<string name="no_cameras">You don\'t have any supported video cameras.</string>
|
<string name="no_cameras">You don\'t have any supported video cameras.</string>
|
||||||
<string name="show_password">Show Password</string>
|
<string name="show_password">Show Password</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user