fix #112, change the way device accounts are fetched

This commit is contained in:
tibbi 2018-04-29 19:22:39 +02:00
parent 1bff08d7a2
commit 5cb9f886b6
5 changed files with 28 additions and 57 deletions

View File

@ -45,7 +45,7 @@ ext {
} }
dependencies { dependencies {
implementation 'com.simplemobiletools:commons:3.20.5' implementation 'com.simplemobiletools:commons:3.20.6'
implementation 'joda-time:joda-time:2.9.9' implementation 'joda-time:joda-time:2.9.9'
implementation 'com.facebook.stetho:stetho:1.5.0' implementation 'com.facebook.stetho:stetho:1.5.0'

View File

@ -9,6 +9,8 @@
<uses-permission android:name="android.permission.READ_CONTACTS"/> <uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/> <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission <uses-permission
android:name="android.permission.USE_FINGERPRINT" android:name="android.permission.USE_FINGERPRINT"

View File

@ -234,16 +234,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
private fun storeLocalAccountData() { private fun storeLocalAccountData() {
if (config.localAccountType == "-1") { 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 { ContactsHelper(this).getContactSources {
var localAccountType = "" var localAccountType = ""
var localAccountName = "" var localAccountName = ""

View File

@ -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_EVENT_TYPE = CommonDataKinds.Event.TYPE_BIRTHDAY
const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK const val DEFAULT_ORGANIZATION_TYPE = CommonDataKinds.Organization.TYPE_WORK
const val DEFAULT_WEBSITE_TYPE = CommonDataKinds.Website.TYPE_HOMEPAGE 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"
)

View File

@ -1,9 +1,7 @@
package com.simplemobiletools.contacts.helpers package com.simplemobiletools.contacts.helpers
import android.content.ContentProviderOperation import android.accounts.AccountManager
import android.content.ContentProviderResult import android.content.*
import android.content.ContentUris
import android.content.ContentValues
import android.database.Cursor import android.database.Cursor
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri import android.net.Uri
@ -621,64 +619,34 @@ class ContactsHelper(val activity: BaseSimpleActivity) {
fun getContactSources(callback: (ArrayList<ContactSource>) -> Unit) { fun getContactSources(callback: (ArrayList<ContactSource>) -> Unit) {
Thread { Thread {
val sources = LinkedHashSet<ContactSource>() val sources = getDeviceContactSources()
getDeviceContactSources(sources)
sources.add(ContactSource(activity.getString(R.string.phone_storage_hidden), SMT_PRIVATE)) sources.add(ContactSource(activity.getString(R.string.phone_storage_hidden), SMT_PRIVATE))
callback(ArrayList(sources)) callback(ArrayList(sources))
}.start() }.start()
} }
private fun getDeviceContactSources(sources: LinkedHashSet<ContactSource>) { private fun getDeviceContactSources(): LinkedHashSet<ContactSource> {
val sources = LinkedHashSet<ContactSource>()
if (!activity.hasContactPermissions()) { if (!activity.hasContactPermissions()) {
return return sources
} }
val uri = ContactsContract.RawContacts.CONTENT_URI val accountManager = AccountManager.get(activity)
val projection = arrayOf(ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE) accountManager.accounts.filter { it.name.contains("@") || localAccountTypes.contains(it.type) }.forEach {
if (ContentResolver.getIsSyncable(it, ContactsContract.Contacts.CONTENT_URI.authority) == 1) {
var cursor: Cursor? = null val contactSource = ContactSource(it.name, it.type)
try { sources.add(contactSource)
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())
} }
} catch (e: Exception) {
activity.showErrorToast(e)
} finally {
cursor?.close()
} }
if (sources.isEmpty() && activity.config.localAccountName.isEmpty() && activity.config.localAccountType.isEmpty()) { if (sources.isEmpty() && activity.config.localAccountName.isEmpty() && activity.config.localAccountType.isEmpty()) {
sources.add(ContactSource("", "")) sources.add(ContactSource("", ""))
} }
return sources
} }
private fun getContactSourceType(accountName: String): String { private fun getContactSourceType(accountName: String) = getDeviceContactSources().firstOrNull { it.name == accountName }?.type ?: ""
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 getContactProjection() = arrayOf( private fun getContactProjection() = arrayOf(
ContactsContract.Data.CONTACT_ID, ContactsContract.Data.CONTACT_ID,