diff --git a/app/build.gradle b/app/build.gradle index b357cbab..bdd914c4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -45,7 +45,7 @@ ext { } dependencies { - implementation 'com.simplemobiletools:commons:3.19.21' + implementation 'com.simplemobiletools:commons:3.20.6' implementation 'joda-time:joda-time:2.9.9' implementation 'com.facebook.stetho:stetho:1.5.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cdb40add..f8b1cd21 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,8 @@ + + - - @@ -190,5 +190,30 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> + + + + + + + + + + + + + + + diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt index 031f561f..8b57dafd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/EditContactActivity.kt @@ -87,6 +87,7 @@ class EditContactActivity : ContactActivity() { if (wasActivityInitialized) { menu.findItem(R.id.delete).isVisible = contact?.id != 0 menu.findItem(R.id.share).isVisible = contact?.id != 0 + menu.findItem(R.id.open_with).isVisible = contact?.id != 0 && contact?.source != SMT_PRIVATE } return true } @@ -94,8 +95,9 @@ class EditContactActivity : ContactActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.save -> saveContact() - R.id.delete -> deleteContact() R.id.share -> shareContact() + R.id.open_with -> openWith() + R.id.delete -> deleteContact() else -> return super.onOptionsItemSelected(item) } return true @@ -224,6 +226,14 @@ class EditContactActivity : ContactActivity() { invalidateOptionsMenu() } + private fun openWith() { + Intent().apply { + action = Intent.ACTION_EDIT + data = getContactPublicUri(contact!!) + startActivity(this) + } + } + private fun startCropPhotoIntent(uri: Uri?) { if (uri == null) { toast(R.string.unknown_error_occurred) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt index 22722186..03a277aa 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/MainActivity.kt @@ -234,16 +234,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener { private fun storeLocalAccountData() { if (config.localAccountType == "-1") { - // some manufacturer contact account types from https://stackoverflow.com/a/44802016/1967672 - val localAccountTypes = arrayListOf("vnd.sec.contact.phone", - "com.htc.android.pcsc", - "com.sonyericsson.localcontacts", - "com.lge.sync", - "com.lge.phone", - "vnd.tmobileus.contact.phone", - "com.android.huawei.phone", - "Local Phone Account") - ContactsHelper(this).getContactSources { var localAccountType = "" var localAccountName = "" diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt index 675e2ad1..bab426b8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SelectContactActivity.kt @@ -17,6 +17,7 @@ import com.simplemobiletools.contacts.adapters.SelectContactsAdapter import com.simplemobiletools.contacts.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.dialogs.FilterContactSourcesDialog import com.simplemobiletools.contacts.extensions.config +import com.simplemobiletools.contacts.extensions.getContactPublicUri import com.simplemobiletools.contacts.helpers.ContactsHelper import com.simplemobiletools.contacts.helpers.SMT_PRIVATE import com.simplemobiletools.contacts.models.Contact @@ -98,9 +99,7 @@ class SelectContactActivity : SimpleActivity() { } as ArrayList val contactSources = config.displayContactSources - if (!config.showAllContacts()) { - contacts = contacts.filter { contactSources.contains(it.source) } as ArrayList - } + contacts = contacts.filter { contactSources.contains(it.source) } as ArrayList Contact.sorting = config.sorting Contact.startWithSurname = config.startNameWithSurname @@ -135,8 +134,7 @@ class SelectContactActivity : SimpleActivity() { Uri.withAppendedPath(ContactsContract.Data.CONTENT_URI, contactId) } else -> { - val lookupKey = ContactsHelper(this).getContactLookupKey(contact.id.toString()) - Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey) + getContactPublicUri(contact) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SimpleActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SimpleActivity.kt index a207163d..94e97fce 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SimpleActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/SimpleActivity.kt @@ -1,5 +1,13 @@ package com.simplemobiletools.contacts.activities import com.simplemobiletools.commons.activities.BaseSimpleActivity +import com.simplemobiletools.contacts.R -open class SimpleActivity : BaseSimpleActivity() +open class SimpleActivity : BaseSimpleActivity() { + override fun getAppIconIDs() = arrayListOf( + R.mipmap.ic_launcher_red, + R.mipmap.ic_launcher + ) + + override fun getAppLauncherName() = getString(R.string.app_launcher_name) +} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt index 80e754d8..a0cd2ade 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/activities/ViewContactActivity.kt @@ -49,13 +49,18 @@ class ViewContactActivity : ContactActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_view_contact, menu) + menu.apply { + findItem(R.id.open_with).isVisible = contact?.source != SMT_PRIVATE + } return true } + override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.edit -> editContact(contact!!) R.id.share -> shareContact() + R.id.open_with -> openWith() R.id.delete -> deleteContact() else -> return super.onOptionsItemSelected(item) } @@ -151,6 +156,14 @@ class ViewContactActivity : ContactActivity() { setupContactSource() } + private fun openWith() { + Intent().apply { + action = ContactsContract.QuickContact.ACTION_QUICK_CONTACT + data = getContactPublicUri(contact!!) + startActivity(this) + } + } + private fun setupFavorite() { contact_toggle_favorite.apply { beVisible() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt index 3dcd8deb..b1c6ab53 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/adapters/FilterContactSourcesAdapter.kt @@ -21,7 +21,7 @@ class FilterContactSourcesAdapter(val activity: SimpleActivity, private val cont init { contactSources.forEachIndexed { index, contactSource -> - if (activity.config.showAllContacts() || displayContactSources.contains(contactSource.name)) { + if (displayContactSources.contains(contactSource.name)) { selectedPositions.add(index) } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt index 358a7dcd..eed613d0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/dialogs/SelectContactsDialog.kt @@ -19,9 +19,7 @@ class SelectContactsDialog(val activity: SimpleActivity, initialContacts: ArrayL var allContacts = initialContacts if (selectContacts == null) { val contactSources = activity.config.displayContactSources - if (!activity.config.showAllContacts()) { - allContacts = allContacts.filter { contactSources.contains(it.source) } as ArrayList - } + allContacts = allContacts.filter { contactSources.contains(it.source) } as ArrayList initiallySelectedContacts = allContacts.filter { it.starred == 1 } as ArrayList } else { diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt index a02e7101..e7b4eabb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/extensions/Activity.kt @@ -2,6 +2,7 @@ package com.simplemobiletools.contacts.extensions import android.content.Intent import android.net.Uri +import android.provider.ContactsContract import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.extensions.sharePathIntent @@ -175,3 +176,8 @@ fun BaseSimpleActivity.removeContactsFromGroup(contacts: ArrayList, gro dbHelper.removeContactsFromGroup(contacts, groupId) } } + +fun BaseSimpleActivity.getContactPublicUri(contact: Contact): Uri { + val lookupKey = ContactsHelper(this).getContactLookupKey(contact.id.toString()) + return Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey) +} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt index 4e632c8c..ac4fbfcb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/fragments/MyViewPagerFragment.kt @@ -99,15 +99,11 @@ abstract class MyViewPagerFragment(context: Context, attributeSet: AttributeSet) contacts.sort() allContacts = contacts - val filtered = if (this is GroupsFragment) { - contacts - } else if (this is FavoritesFragment) { - contacts.filter { it.starred == 1 } as ArrayList - } else { - val contactSources = config.displayContactSources - if (config.showAllContacts()) { - contacts - } else { + val filtered = when { + this is GroupsFragment -> contacts + this is FavoritesFragment -> contacts.filter { it.starred == 1 } as ArrayList + else -> { + val contactSources = config.displayContactSources contacts.filter { contactSources.contains(it.source) } as ArrayList } } diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt index ec516108..444a814c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Config.kt @@ -12,8 +12,6 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getStringSet(DISPLAY_CONTACT_SOURCES, hashSetOf("-1")) set(displayContactSources) = prefs.edit().remove(DISPLAY_CONTACT_SOURCES).putStringSet(DISPLAY_CONTACT_SOURCES, displayContactSources).apply() - fun showAllContacts() = displayContactSources.size == 1 && displayContactSources.first() == "-1" - var showContactThumbnails: Boolean get() = prefs.getBoolean(SHOW_CONTACT_THUMBNAILS, true) set(showContactThumbnails) = prefs.edit().putBoolean(SHOW_CONTACT_THUMBNAILS, showContactThumbnails).apply() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt index a4f0b9b7..0b2e1b25 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/Constants.kt @@ -93,3 +93,14 @@ const val DEFAULT_ADDRESS_TYPE = CommonDataKinds.StructuredPostal.TYPE_HOME const val DEFAULT_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK const val DEFAULT_WEBSITE_TYPE = CommonDataKinds.Website.TYPE_HOMEPAGE + +// some manufacturer contact account types from https://stackoverflow.com/a/44802016/1967672 +val localAccountTypes = arrayListOf("vnd.sec.contact.phone", + "com.htc.android.pcsc", + "com.sonyericsson.localcontacts", + "com.lge.sync", + "com.lge.phone", + "vnd.tmobileus.contact.phone", + "com.android.huawei.phone", + "Local Phone Account" +) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt index fc09e35d..c100807c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/ContactsHelper.kt @@ -1,9 +1,7 @@ package com.simplemobiletools.contacts.helpers -import android.content.ContentProviderOperation -import android.content.ContentProviderResult -import android.content.ContentUris -import android.content.ContentValues +import android.accounts.AccountManager +import android.content.* import android.database.Cursor import android.graphics.Bitmap import android.net.Uri @@ -37,7 +35,9 @@ class ContactsHelper(val activity: BaseSimpleActivity) { val contactsSize = contacts.size() var resultContacts = ArrayList(contactsSize) (0 until contactsSize).mapTo(resultContacts) { contacts.valueAt(it) } - resultContacts = resultContacts.distinctBy { it.contactId } as ArrayList + resultContacts = resultContacts.distinctBy { + it.getHashToCompare() + } as ArrayList // groups are obtained with contactID, not rawID, so assign them to proper contacts like this val groups = getContactGroups(getStoredGroups()) @@ -90,6 +90,7 @@ class ContactsHelper(val activity: BaseSimpleActivity) { val websites = ArrayList() val contact = Contact(id, prefix, firstName, middleName, surname, suffix, photoUri, number, emails, addresses, events, accountName, starred, contactId, thumbnailUri, null, notes, groups, organization, websites) + contacts.put(id, contact) } while (cursor.moveToNext()) } @@ -621,64 +622,34 @@ class ContactsHelper(val activity: BaseSimpleActivity) { fun getContactSources(callback: (ArrayList) -> Unit) { Thread { - val sources = LinkedHashSet() - getDeviceContactSources(sources) + val sources = getDeviceContactSources() sources.add(ContactSource(activity.getString(R.string.phone_storage_hidden), SMT_PRIVATE)) callback(ArrayList(sources)) }.start() } - private fun getDeviceContactSources(sources: LinkedHashSet) { + private fun getDeviceContactSources(): LinkedHashSet { + val sources = LinkedHashSet() if (!activity.hasContactPermissions()) { - return + return sources } - val uri = ContactsContract.RawContacts.CONTENT_URI - val projection = arrayOf(ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE) - - var cursor: Cursor? = null - try { - cursor = activity.contentResolver.query(uri, projection, null, null, null) - if (cursor?.moveToFirst() == true) { - do { - val name = cursor.getStringValue(ContactsContract.RawContacts.ACCOUNT_NAME) ?: continue - val type = cursor.getStringValue(ContactsContract.RawContacts.ACCOUNT_TYPE) ?: continue - val contactSource = ContactSource(name, type) - sources.add(contactSource) - } while (cursor.moveToNext()) + val accountManager = AccountManager.get(activity) + accountManager.accounts.filter { it.name.contains("@") || localAccountTypes.contains(it.type) }.forEach { + if (ContentResolver.getIsSyncable(it, ContactsContract.AUTHORITY) == 1) { + val contactSource = ContactSource(it.name, it.type) + sources.add(contactSource) } - } catch (e: Exception) { - activity.showErrorToast(e) - } finally { - cursor?.close() } if (sources.isEmpty() && activity.config.localAccountName.isEmpty() && activity.config.localAccountType.isEmpty()) { sources.add(ContactSource("", "")) } + + return sources } - private fun getContactSourceType(accountName: String): String { - if (accountName.isEmpty()) { - return "" - } - - val uri = ContactsContract.RawContacts.CONTENT_URI - val projection = arrayOf(ContactsContract.RawContacts.ACCOUNT_TYPE) - val selection = "${ContactsContract.RawContacts.ACCOUNT_NAME} = ?" - val selectionArgs = arrayOf(accountName) - - var cursor: Cursor? = null - try { - cursor = activity.contentResolver.query(uri, projection, selection, selectionArgs, null) - if (cursor?.moveToFirst() == true) { - return cursor.getStringValue(ContactsContract.RawContacts.ACCOUNT_TYPE) - } - } finally { - cursor?.close() - } - return "" - } + private fun getContactSourceType(accountName: String) = getDeviceContactSources().firstOrNull { it.name == accountName }?.type ?: "" private fun getContactProjection() = arrayOf( ContactsContract.Data.CONTACT_ID, @@ -1060,14 +1031,16 @@ class ContactsHelper(val activity: BaseSimpleActivity) { } // organization - ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { - withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) - withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) - withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) - withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) - withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) - withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) - operations.add(build()) + if (!contact.organization.isEmpty()) { + ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).apply { + withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0) + withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.Organization.CONTENT_ITEM_TYPE) + withValue(CommonDataKinds.Organization.COMPANY, contact.organization.company) + withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) + withValue(CommonDataKinds.Organization.TITLE, contact.organization.jobPosition) + withValue(CommonDataKinds.Organization.TYPE, DEFAULT_ORGANIZATION_TYPE) + operations.add(build()) + } } // websites @@ -1246,16 +1219,14 @@ class ContactsHelper(val activity: BaseSimpleActivity) { activity.dbHelper.deleteContacts(localContacts) try { - val contactIDs = HashSet() val operations = ArrayList() val selection = "${ContactsContract.Data.CONTACT_ID} = ?" contacts.filter { it.source != SMT_PRIVATE }.forEach { ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI).apply { val selectionArgs = arrayOf(it.contactId.toString()) withSelection(selection, selectionArgs) - operations.add(this.build()) + operations.add(build()) } - contactIDs.add(it.id.toString()) } activity.contentResolver.applyBatch(ContactsContract.AUTHORITY, operations) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt index c082d6bf..e3729c19 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/helpers/DBHelper.kt @@ -119,6 +119,10 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont fun deleteContact(id: Int) = deleteContacts(arrayOf(id.toString())) fun deleteContacts(ids: Array) { + if (ids.isEmpty()) { + return + } + val args = TextUtils.join(", ", ids) val selection = "$CONTACTS_TABLE_NAME.$COL_ID IN ($args)" mDb.delete(CONTACTS_TABLE_NAME, selection, null) diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt index a4a422a3..42cc04cd 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/models/Contact.kt @@ -12,6 +12,7 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m companion object { var sorting = 0 var startWithSurname = false + val pattern = "\\D+".toRegex() } override fun compareTo(other: Contact): Int { @@ -81,4 +82,10 @@ data class Contact(val id: Int, var prefix: String, var firstName: String, var m fullName } } + + fun getHashToCompare(): Int { + val newPhoneNumbers = ArrayList() + phoneNumbers.mapTo(newPhoneNumbers, { PhoneNumber(it.value.replace(pattern, ""), 0) }) + return copy(id = 0, phoneNumbers = newPhoneNumbers).hashCode() + } } diff --git a/app/src/main/res/layout/activity_edit_contact.xml b/app/src/main/res/layout/activity_edit_contact.xml index f09f6d3d..534ac995 100644 --- a/app/src/main/res/layout/activity_edit_contact.xml +++ b/app/src/main/res/layout/activity_edit_contact.xml @@ -341,7 +341,7 @@ android:layout_marginTop="@dimen/normal_margin" android:layout_toRightOf="@+id/contact_notes_image" android:hint="@string/notes" - android:inputType="textCapWords|textMultiLine" + android:inputType="textCapSentences|textMultiLine" android:textCursorDrawable="@null" android:textSize="@dimen/bigger_text_size"/> diff --git a/app/src/main/res/menu/menu_edit_contact.xml b/app/src/main/res/menu/menu_edit_contact.xml index 12208f19..ed26a9c6 100644 --- a/app/src/main/res/menu/menu_edit_contact.xml +++ b/app/src/main/res/menu/menu_edit_contact.xml @@ -11,6 +11,10 @@ android:icon="@drawable/ic_share" android:title="@string/share" app:showAsAction="ifRoom"/> + + Organização Cargo Site - Send SMS to contacts - Send email to contacts - Send SMS to group - Send email to group + Enviar SMS aos contactos + Enviar e-mail aos contactos + Enviar SMS para o grupo + Enviar e-mail para o grupo Novo contacto Editar contacto @@ -73,7 +73,7 @@ Adicionar favoritos Adicionar aos favoritos Remover dos favoritos - You must be at the Edit screen to modify a contact + Tem que estar no ecrã de edição para alterar um contacto Pesquisar contactos diff --git a/build.gradle b/build.gradle index 9b9625a9..8e5373c7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.40' + ext.kotlin_version = '1.2.41' repositories { google()