diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 137a1d4e..4a3a7a77 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -69,7 +69,7 @@ class BaresipService: Service() { private lateinit var wifiLock: WifiManager.WifiLock private lateinit var bluetoothReceiver: BroadcastReceiver private lateinit var hotSpotReceiver: BroadcastReceiver - private lateinit var contentObserver: ContentObserver + private lateinit var androidContactsObserver: ContentObserver private lateinit var stopState: String private lateinit var quitTimer: CountDownTimer @@ -82,7 +82,7 @@ class BaresipService: Service() { private var hotSpotIsEnabled = false private var hotSpotAddresses = mapOf() private var mediaPlayer: MediaPlayer? = null - private var contentObserverRegistered = false + private var androidContactsObserverRegistered = false private var isServiceClean = false @SuppressLint("WakelockTimeout") @@ -318,9 +318,9 @@ class BaresipService: Service() { this.registerReceiver(bluetoothReceiver, filter) } - contentObserver = object : ContentObserver(null) { + androidContactsObserver = object : ContentObserver(null) { override fun onChange(self: Boolean) { - Log.d(TAG, "Contacts change") + Log.d(TAG, "Android contacts change") if (contactsMode != "baresip") { Contact.loadAndroidContacts(this@BaresipService.applicationContext) Contact.contactsUpdate() @@ -412,7 +412,7 @@ class BaresipService: Service() { Contact.restoreBaresipContacts() if (contactsMode != "baresip") { Contact.loadAndroidContacts(applicationContext) - registerContentObserver() + registerAndroidContactsObserver() } Contact.contactsUpdate() @@ -470,11 +470,11 @@ class BaresipService: Service() { } "Start Content Observer" -> { - registerContentObserver() + registerAndroidContactsObserver() } "Stop Content Observer" -> { - unRegisterContentObserver() + unRegisterAndroidContactsObserver() } "Call Answer" -> { @@ -1493,21 +1493,21 @@ class BaresipService: Service() { } } - private fun registerContentObserver() { - if (!contentObserverRegistered) + private fun registerAndroidContactsObserver() { + if (!androidContactsObserverRegistered) try { contentResolver.registerContentObserver(ContactsContract.Contacts.CONTENT_URI, - true, contentObserver) - contentObserverRegistered = true + true, androidContactsObserver) + androidContactsObserverRegistered = true } catch (e: SecurityException) { Log.i(TAG, "No Contacts permission") } } - private fun unRegisterContentObserver() { - if (contentObserverRegistered) { - contentResolver.unregisterContentObserver(contentObserver) - contentObserverRegistered = false + private fun unRegisterAndroidContactsObserver() { + if (androidContactsObserverRegistered) { + contentResolver.unregisterContentObserver(androidContactsObserver) + androidContactsObserverRegistered = false } } @@ -1529,8 +1529,8 @@ class BaresipService: Service() { proximityWakeLock.release() if (this::wifiLock.isInitialized) wifiLock.release() - if (this::contentObserver.isInitialized) - contentResolver.unregisterContentObserver(contentObserver) + if (this::androidContactsObserver.isInitialized) + contentResolver.unregisterContentObserver(androidContactsObserver) isServiceClean = true } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/Contact.kt b/app/src/main/kotlin/com/tutpro/baresip/Contact.kt index 7de1c0a5..25e6e67a 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Contact.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Contact.kt @@ -12,7 +12,8 @@ import java.util.ArrayList sealed class Contact { - class BaresipContact(var name: String, var uri: String, var color: Int, val id: Long): Contact() { + class BaresipContact(var name: String, var uri: String, var color: Int, val id: Long, + var favorite: Boolean): Contact() { var avatarImage: Bitmap? = null } @@ -110,7 +111,8 @@ sealed class Contact { fun saveBaresipContacts() { var contents = "" for (c in BaresipService.baresipContacts) - contents += "\"${c.name}\" <${c.uri}>;id=${c.id};color=${c.color}\n" + contents += "\"${c.name}\" <${c.uri}>;id=${c.id};color=${c.color}" + + ";favorite=${if (c.favorite) "yes" else "no"}\n" Utils.putFileContents(BaresipService.filesPath + "/contacts", contents.toByteArray()) } @@ -196,8 +198,9 @@ sealed class Contact { idValue.toLong() else baseId + contactNo + val favorite = Utils.paramValue(params, "favorite" ) == "yes" Log.d(TAG, "Restoring contact $name, $uri, $color, $id") - val contact = BaresipContact(name, uri, color, id) + val contact = BaresipContact(name, uri, color, id, favorite) val avatarFilePath = BaresipService.filesPath + "/$id.png" if (File(avatarFilePath).exists()) { try { @@ -254,7 +257,7 @@ sealed class Contact { private fun sortContacts() { BaresipService.contacts.sortBy{ when (it) { - is BaresipContact -> "1" + it.name + is BaresipContact -> if (it.favorite) "0" + it.name else "1" + it.name is AndroidContact -> if (it.favorite) "0" + it.name else "1" + it.name }} } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt index b3ee2a9f..cdc85f87 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactActivity.kt @@ -36,6 +36,7 @@ class ContactActivity : AppCompatActivity() { private lateinit var cardImageAvatarView: ImageView private lateinit var nameView: EditText private lateinit var uriView: EditText + private lateinit var favoriteCheck: CheckBox private lateinit var androidCheck: CheckBox private lateinit var menu: Menu @@ -65,6 +66,7 @@ class ContactActivity : AppCompatActivity() { cardImageAvatarView = binding.ImageAvatar nameView = binding.Name uriView = binding.Uri + favoriteCheck = binding.Favorite androidCheck = binding.Android newContact = intent.getBooleanExtra("new", false) @@ -87,6 +89,7 @@ class ContactActivity : AppCompatActivity() { else uriView.setText(uri) uOrI = uri + favoriteCheck.isChecked = false if ((BaresipService.contactsMode == "android")) { androidCheck.isChecked = true androidCheck.isClickable = false @@ -109,6 +112,7 @@ class ContactActivity : AppCompatActivity() { title = name nameView.setText(name) uriView.setText(contact.uri) + favoriteCheck.isChecked = contact.favorite uOrI = index.toString() } @@ -250,13 +254,14 @@ class ContactActivity : AppCompatActivity() { BaresipService.activities.removeAt(0) return true } else { - contact = Contact.BaresipContact(newName, newUri, color, id) + contact = Contact.BaresipContact(newName, newUri, color, id, favoriteCheck.isChecked) } } else { contact = Contact.contacts()[index] as Contact.BaresipContact contact.uri = newUri contact.name = newName contact.color = color + contact.favorite = favoriteCheck.isChecked } when (newAvatar) { @@ -286,7 +291,8 @@ class ContactActivity : AppCompatActivity() { BaresipService.activities.remove("contact,$newContact,$uOrI") val i = Intent(this, MainActivity::class.java) - i.putExtra("name", newName) + if (androidCheck.isChecked && contact.favorite) + i.putExtra("name", newName) setResult(Activity.RESULT_OK, i) finish() } @@ -384,6 +390,7 @@ class ContactActivity : AppCompatActivity() { .withValue(Data.MIMETYPE, mimeType) .withValue(Data.DATA1, contact.uri.substringAfter(":")) .build()) + if (contact.avatarImage != null) { val photoData: ByteArray? = bitmapToPNGByteArray(contact.avatarImage!!) if (photoData != null) { @@ -443,7 +450,7 @@ class ContactActivity : AppCompatActivity() { return try { contentResolver.update(ContactsContract.Data.CONTENT_URI, contentValues, where, null) } catch (e: Exception) { - Log.e(TAG, "Adding of SIP URI $uri failed") + Log.e(TAG, "Update of Android URI $uri failed") 0 } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/ContactListAdapter.kt b/app/src/main/kotlin/com/tutpro/baresip/ContactListAdapter.kt index 9800d710..84af1311 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/ContactListAdapter.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/ContactListAdapter.kt @@ -4,6 +4,7 @@ import android.app.Activity import android.content.Context import android.content.DialogInterface import android.content.Intent +import android.graphics.Typeface import android.os.Bundle import android.os.SystemClock import android.provider.ContactsContract @@ -65,6 +66,10 @@ class ContactListAdapter(private val ctx: Context, private val rows: ArrayList { + val androidContactsObserver = Observer { + if (newAndroidName != null) { + val contentValues = ContentValues() + contentValues.put(ContactsContract.Contacts.STARRED, 1) + try { + this.contentResolver.update( + ContactsContract.RawContacts.CONTENT_URI, contentValues, + ContactsContract.Contacts.DISPLAY_NAME + "='" + newAndroidName + "'", null + ) + } catch (e: Exception) { + Log.e(TAG, "Update of Android favorite failed") + } + newAndroidName = null + } clAdapter.notifyDataSetChanged() } - BaresipService.contactUpdate.observe(this, contactObserver) + BaresipService.contactUpdate.observe(this, androidContactsObserver) val contactRequest = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - if (it.resultCode == RESULT_OK) - clAdapter.notifyDataSetChanged() + if (it.resultCode == RESULT_OK) { + if (it.data != null && it.data!!.hasExtra("name")) + newAndroidName = it.data!!.getStringExtra("name") + } + clAdapter.notifyDataSetChanged() } val plusButton = binding.plusButton diff --git a/app/src/main/res/layout/activity_contact.xml b/app/src/main/res/layout/activity_contact.xml index 10c2dd98..85b309da 100644 --- a/app/src/main/res/layout/activity_contact.xml +++ b/app/src/main/res/layout/activity_contact.xml @@ -88,11 +88,38 @@ android:layout_height="wrap_content" android:paddingTop="10dp" android:orientation="horizontal" > + + + + + + + @@ -102,6 +129,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" + android:layout_centerVertical="true" android:layout_gravity="end" android:checked="false" > diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index ba0a238d..1326cc7b 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -429,6 +429,7 @@ Nimi SIP tai tel URI käyttäjä@domain tai puhelinnumero + Suosikki Virheellinen yhteystiedon nimi \'%1$s\' Yhteystieto \'%1$s\' on jo olemassa. Virheellinen SIP URI \'%1$s\' diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 10998269..1eab74fa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -399,6 +399,7 @@ Name SIP or tel URI user@domain or telephone number + Favorite Invalid contact name \'%1$s\' Contact \'%1$s\' already exists. Invalid SIP URI