Try to prevent databinding build issue + few changes for contact editor to be able to choose in which sync account create the contact
This commit is contained in:
parent
f1f58d49e7
commit
f8ac74ee97
6 changed files with 59 additions and 30 deletions
|
@ -181,3 +181,6 @@ ktlint {
|
||||||
}
|
}
|
||||||
|
|
||||||
project.tasks['preBuild'].dependsOn 'ktlintFormat'
|
project.tasks['preBuild'].dependsOn 'ktlintFormat'
|
||||||
|
|
||||||
|
// Always clean on pre-build, prevents build issues caused by data binding
|
||||||
|
project.tasks['preBuild'].dependsOn 'clean'
|
|
@ -31,7 +31,6 @@ import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
import org.linphone.LinphoneApplication.Companion.corePreferences
|
||||||
import org.linphone.contact.*
|
import org.linphone.contact.*
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.AppUtils
|
|
||||||
import org.linphone.utils.ImageUtils
|
import org.linphone.utils.ImageUtils
|
||||||
import org.linphone.utils.PermissionHelper
|
import org.linphone.utils.PermissionHelper
|
||||||
|
|
||||||
|
@ -82,14 +81,14 @@ class ContactEditorViewModel(val c: Contact?) : ViewModel(), ContactViewModelInt
|
||||||
if (contact == null) {
|
if (contact == null) {
|
||||||
created = true
|
created = true
|
||||||
contact = if (PermissionHelper.get().hasWriteContactsPermission()) {
|
contact = if (PermissionHelper.get().hasWriteContactsPermission()) {
|
||||||
NativeContact(AppUtils.createAndroidContact().toString())
|
NativeContact(NativeContactEditor.createAndroidContact(null, null).toString())
|
||||||
} else {
|
} else {
|
||||||
Contact()
|
Contact()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contact is NativeContact) {
|
if (contact is NativeContact) {
|
||||||
NativeContactEditor(contact)
|
NativeContactEditor(contact, null, null)
|
||||||
.setFirstAndLastNames(firstName.value.orEmpty(), lastName.value.orEmpty())
|
.setFirstAndLastNames(firstName.value.orEmpty(), lastName.value.orEmpty())
|
||||||
.setOrganization(organization.value.orEmpty())
|
.setOrganization(organization.value.orEmpty())
|
||||||
.setPhoneNumbers(numbers.value.orEmpty())
|
.setPhoneNumbers(numbers.value.orEmpty())
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.linphone.contact
|
||||||
|
|
||||||
import android.accounts.Account
|
import android.accounts.Account
|
||||||
import android.accounts.AccountManager
|
import android.accounts.AccountManager
|
||||||
|
import android.content.ContentResolver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.database.ContentObserver
|
import android.database.ContentObserver
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -256,6 +257,26 @@ class ContactsManager(private val context: Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAvailableSyncAccounts(): List<Pair<String, String>> {
|
||||||
|
val accountManager = context.getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
|
||||||
|
val syncAdapters = ContentResolver.getSyncAdapterTypes()
|
||||||
|
val available = arrayListOf<Pair<String, String>>()
|
||||||
|
|
||||||
|
for (syncAdapter in syncAdapters) {
|
||||||
|
if (syncAdapter.authority == "com.android.contacts" && syncAdapter.isUserVisible) {
|
||||||
|
Log.i("[Contacts Manager] Found sync adapter for com.android.contacts authority: ${syncAdapter.accountType}")
|
||||||
|
val accounts = accountManager.getAccountsByType(syncAdapter.accountType)
|
||||||
|
for (account in accounts) {
|
||||||
|
Log.i("[Contacts Manager] Found account for account type ${syncAdapter.accountType}: ${account.name}")
|
||||||
|
val pair = Pair(account.name, account.type)
|
||||||
|
available.add(pair)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return available
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun refreshContactOnPresenceReceived(friend: Friend): Boolean {
|
private fun refreshContactOnPresenceReceived(friend: Friend): Boolean {
|
||||||
if (friend.userData == null) return false
|
if (friend.userData == null) return false
|
||||||
|
@ -272,7 +293,7 @@ class ContactsManager(private val context: Context) {
|
||||||
val sipAddress = contact.getContactForPhoneNumberOrAddress(phoneNumber)
|
val sipAddress = contact.getContactForPhoneNumberOrAddress(phoneNumber)
|
||||||
if (sipAddress != null) {
|
if (sipAddress != null) {
|
||||||
Log.i("[Contacts Manager] Found presence information to store in native contact $contact")
|
Log.i("[Contacts Manager] Found presence information to store in native contact $contact")
|
||||||
NativeContactEditor(contact).setPresenceInformation(phoneNumber, sipAddress).commit()
|
NativeContactEditor(contact, null, null).setPresenceInformation(phoneNumber, sipAddress).commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.linphone.contact
|
||||||
|
|
||||||
import android.content.ContentProviderOperation
|
import android.content.ContentProviderOperation
|
||||||
import android.content.ContentUris
|
import android.content.ContentUris
|
||||||
|
import android.content.ContentValues
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.ContactsContract
|
import android.provider.ContactsContract
|
||||||
import android.provider.ContactsContract.CommonDataKinds
|
import android.provider.ContactsContract.CommonDataKinds
|
||||||
|
@ -33,7 +34,29 @@ import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.AppUtils
|
import org.linphone.utils.AppUtils
|
||||||
import org.linphone.utils.PermissionHelper
|
import org.linphone.utils.PermissionHelper
|
||||||
|
|
||||||
class NativeContactEditor(val contact: NativeContact) {
|
class NativeContactEditor(
|
||||||
|
val contact: NativeContact,
|
||||||
|
private var syncAccountName: String?,
|
||||||
|
private var syncAccountType: String?
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
fun createAndroidContact(accountName: String?, accountType: String?): Long {
|
||||||
|
val values = ContentValues()
|
||||||
|
|
||||||
|
if (accountName == null && accountType == null && corePreferences.useLinphoneSyncAccount) {
|
||||||
|
values.put(RawContacts.ACCOUNT_NAME, AppUtils.getString(R.string.sync_account_name))
|
||||||
|
values.put(RawContacts.ACCOUNT_TYPE, AppUtils.getString(R.string.sync_account_type))
|
||||||
|
} else {
|
||||||
|
values.put(RawContacts.ACCOUNT_NAME, accountName)
|
||||||
|
values.put(RawContacts.ACCOUNT_TYPE, accountType)
|
||||||
|
}
|
||||||
|
|
||||||
|
val rawContactUri = coreContext.context.contentResolver
|
||||||
|
.insert(RawContacts.CONTENT_URI, values)
|
||||||
|
return ContentUris.parseId(rawContactUri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val changes = arrayListOf<ContentProviderOperation>()
|
private val changes = arrayListOf<ContentProviderOperation>()
|
||||||
private val selection =
|
private val selection =
|
||||||
"${ContactsContract.Data.CONTACT_ID} =? AND ${ContactsContract.Data.MIMETYPE} =?"
|
"${ContactsContract.Data.CONTACT_ID} =? AND ${ContactsContract.Data.MIMETYPE} =?"
|
||||||
|
@ -49,10 +72,13 @@ class NativeContactEditor(val contact: NativeContact) {
|
||||||
private var pictureByteArray: ByteArray? = null
|
private var pictureByteArray: ByteArray? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val contentResolver = coreContext.context.contentResolver
|
if (syncAccountName == null && syncAccountType == null && useLinphoneSyncAccount) {
|
||||||
val syncAccountType = AppUtils.getString(R.string.sync_account_type)
|
syncAccountName = AppUtils.getString(R.string.sync_account_name)
|
||||||
val syncAccountName = AppUtils.getString(R.string.sync_account_name)
|
syncAccountType = AppUtils.getString(R.string.sync_account_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i("[Native Contact Editor] Using sync account $syncAccountName with type $syncAccountType")
|
||||||
|
val contentResolver = coreContext.context.contentResolver
|
||||||
val cursor = contentResolver.query(
|
val cursor = contentResolver.query(
|
||||||
RawContacts.CONTENT_URI,
|
RawContacts.CONTENT_URI,
|
||||||
arrayOf(RawContacts._ID, RawContacts.ACCOUNT_TYPE),
|
arrayOf(RawContacts._ID, RawContacts.ACCOUNT_TYPE),
|
||||||
|
@ -76,7 +102,7 @@ class NativeContactEditor(val contact: NativeContact) {
|
||||||
}
|
}
|
||||||
cursor?.close()
|
cursor?.close()
|
||||||
|
|
||||||
// When contact has been created with AppUtils.createAndroidContact this is required
|
// When contact has been created with NativeContactEditor.createAndroidContact this is required
|
||||||
if (rawId == null) rawId = contact.nativeId
|
if (rawId == null) rawId = contact.nativeId
|
||||||
|
|
||||||
if (linphoneRawId == null && useLinphoneSyncAccount) {
|
if (linphoneRawId == null && useLinphoneSyncAccount) {
|
||||||
|
|
|
@ -228,7 +228,7 @@ class CorePreferences constructor(private val context: Context) {
|
||||||
get() = config.getBool("app", "display_contact_organization", true)
|
get() = config.getBool("app", "display_contact_organization", true)
|
||||||
|
|
||||||
// If enabled, SIP addresses will be stored in a different raw id than the contact and with a custom MIME type
|
// If enabled, SIP addresses will be stored in a different raw id than the contact and with a custom MIME type
|
||||||
// If disabled, account won't be created
|
// If disabled, contacts will be created in default account & addresses will be stored in native SIP field
|
||||||
val useLinphoneSyncAccount: Boolean
|
val useLinphoneSyncAccount: Boolean
|
||||||
get() = config.getBool("app", "use_linphone_tag", true)
|
get() = config.getBool("app", "use_linphone_tag", true)
|
||||||
|
|
||||||
|
|
|
@ -21,14 +21,12 @@ package org.linphone.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.*
|
import android.content.*
|
||||||
import android.provider.ContactsContract
|
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import androidx.core.text.HtmlCompat
|
import androidx.core.text.HtmlCompat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import org.linphone.LinphoneApplication.Companion.coreContext
|
import org.linphone.LinphoneApplication.Companion.coreContext
|
||||||
import org.linphone.LinphoneApplication.Companion.corePreferences
|
|
||||||
import org.linphone.R
|
import org.linphone.R
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
|
|
||||||
|
@ -102,24 +100,6 @@ class AppUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createAndroidContact(): Long {
|
|
||||||
var accountType: String? = null
|
|
||||||
var accountName: String? = null
|
|
||||||
|
|
||||||
if (corePreferences.useLinphoneSyncAccount) {
|
|
||||||
accountType = getString(org.linphone.R.string.sync_account_type)
|
|
||||||
accountName = getString(org.linphone.R.string.sync_account_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
val values = ContentValues()
|
|
||||||
values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType)
|
|
||||||
values.put(ContactsContract.RawContacts.ACCOUNT_NAME, accountName)
|
|
||||||
|
|
||||||
val rawContactUri = coreContext.context.contentResolver
|
|
||||||
.insert(ContactsContract.RawContacts.CONTENT_URI, values)
|
|
||||||
return ContentUris.parseId(rawContactUri)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun pixelsToDp(pixels: Float): Float {
|
fun pixelsToDp(pixels: Float): Float {
|
||||||
return TypedValue.applyDimension(
|
return TypedValue.applyDimension(
|
||||||
TypedValue.COMPLEX_UNIT_DIP,
|
TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
|
Loading…
Reference in a new issue