Contact Store is a modern API that makes access to contacts on Android devices simple to use.
The default way of accessing contacts on Android is based off ContentProviders. Despite powerful, ContentProviders can be error-prone and frustrating to use.
Contact Store is a refreshed take on the Contacts API. It provides solutions to contacts' most frequent use cases and uses modern developer practices for an enjoyable developer experience.
Install the API using Gradle:
repositories {
...
mavenCentral()
}
dependencies {
implementation 'com.alexstyl:contactstore:1.7.0'
// extension functions for kotlin coroutines
implementation 'com.alexstyl:contactstore-coroutines:1.7.0'
// extension functions for rxJava 3
implementation 'com.alexstyl:contactstore-reactive:1.7.0'
// optional dependency for tests
testImplementation 'com.alexstyl:contactstore-test:1.7.0'
}
val store = ContactStore.newInstance(application)
store.fetchContacts()
.collect { contacts ->
println("Contacts emitted: $contacts")
}
val store = ContactStore.newInstance(application)
store.fetchContacts(
predicate = ContactLookup(contactId),
columnsToFetch = allContactColumns()
)
.collect { contacts ->
val contact = contacts.firstOrNull()
if (contact == null) {
println("Contact not found")
} else {
println("Contact found: $contact")
// Use contact.phones, contact.mails, contact.customDataItems etc
}
}
val store = ContactStore.newInstance(application)
store.execute {
insert(InternetAcount("paolo@gmail.com", "gmail.com")) {
firstName = "Paolo"
lastName = "Melendez"
phone(
value = PhoneNumber("555"),
label = Label.PhoneNumberMobile
)
mail(
address = "paolo@paolo.com",
label = Label.LocationWork
)
event(
dayOfMonth = 23,
month = 11,
year = 2021,
label = Label.DateBirthday
)
postalAddress(
street = "85 Somewhere Str",
label = Label.LocationHome
)
webAddress(
address = "paolo@paolo.com",
label = Label.LocationWork
)
groupMembership(groupId = 123)
}
}
val foundContacts = store.fetchContacts(
predicate = ContactLookup(contactId = 5L),
columnsToFetch = listOf(ContactColumn.Note)
).blockingGet()
if (foundContacts.isEmpty()) return // the contact was not found
val contact = foundContacts.first()
store.execute {
update(contact.mutableCopy {
note = Note("To infinity and beyond!")
})
}
store.execute {
delete(contactId = 5L)
}
Probably not and this is not the aim of the project. The existing Contacts API has been out there for 10 years or so without much update. It is powerful given that you have access to an SQL-like syntax. I am assuming that a lot of the features it provides were introduced because the platform developers were coding against the ContactProvider interface instead of supporting the features app developers would eventually end up using.
Keeping the API lean allows for faster iterations/releases too as there is less things to maintain. I am not saying that the features of the default API are not important or that they will never make it to Contact Store. Instead, I would rather have the features and capabilities of the API to be driven by dev requirements.
If you believe you are missing a specific feature, open a new feature request on Github.
You should be able to use Contact Store through Java as you can call Kotlin code from Java, but it won't be ideal. Check this Github issue and write your experience.
Checkout the project documentation to learn about about Contact Store features in detail. To report a specific problem or feature request, open a new issue on Github.
Apache 2.0. See the LICENSE file for details.
Made by Alex Styl. Follow @alexstyl on Twitter for future updates.