Welcome to mirror list, hosted at ThFree Co, Russian Federation.

AndroidAddressBook.kt « vcard4android « bitfire « at « java « main « src - github.com/bitfireAT/vcard4android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c534ede9424676794179dc2860863980b685882c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * Copyright © Ricki Hirner (bitfire web engineering).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 */

package at.bitfire.vcard4android

import android.accounts.Account
import android.content.ContentProviderClient
import android.content.ContentValues
import android.net.Uri
import android.provider.ContactsContract
import android.provider.ContactsContract.Groups
import android.provider.ContactsContract.RawContacts
import at.bitfire.vcard4android.Utils.toContentValues
import java.io.FileNotFoundException
import java.util.*
import kotlin.jvm.Throws

open class AndroidAddressBook<T1: AndroidContact, T2: AndroidGroup>(
        var account: Account,
        val provider: ContentProviderClient?,
        protected val contactFactory: AndroidContactFactory<T1>,
        protected val groupFactory: AndroidGroupFactory<T2>
) {

    open var readOnly: Boolean = false

    var settings: ContentValues
        /**
         * Retrieves [ContactsContract.Settings] for the current address book.
         * @throws FileNotFoundException if the settings row couldn't be fetched.
         * @throws android.os.RemoteException on content provider errors
         */
        get() {
            provider!!.query(syncAdapterURI(ContactsContract.Settings.CONTENT_URI), null, null, null, null)?.use { cursor ->
                if (cursor.moveToNext())
                    return cursor.toContentValues()
            }
            throw FileNotFoundException()
        }

        /**
         * Updates [ContactsContract.Settings] by inserting the given values into
         * the current address book.
         * @param values settings to be updated
         * @throws android.os.RemoteException on content provider errors
         */
        set(values) {
            values.put(ContactsContract.Settings.ACCOUNT_NAME, account.name)
            values.put(ContactsContract.Settings.ACCOUNT_TYPE, account.type)
            provider!!.insert(syncAdapterURI(ContactsContract.Settings.CONTENT_URI), values)
        }

    var syncState: ByteArray?
        get() = ContactsContract.SyncState.get(provider, account)
        set(data) = ContactsContract.SyncState.set(provider, account, data)


    fun queryContacts(where: String?, whereArgs: Array<String>?): List<T1> {
        val contacts = LinkedList<T1>()
        provider!!.query(rawContactsSyncUri(),
                null, where, whereArgs, null)?.use { cursor ->
            while (cursor.moveToNext())
                contacts += contactFactory.fromProvider(this, cursor.toContentValues())
        }
        return contacts
    }

    fun queryGroups(where: String?, whereArgs: Array<String>?): List<T2> {
        val groups = LinkedList<T2>()
        provider!!.query(groupsSyncUri(),
                arrayOf(Groups._ID, AndroidGroup.COLUMN_FILENAME, AndroidGroup.COLUMN_ETAG),
                where, whereArgs, null)?.use { cursor ->
            while (cursor.moveToNext())
                groups += groupFactory.fromProvider(this, cursor.toContentValues())
        }
        return groups
    }

    @Throws(FileNotFoundException::class)
    fun findContactById(id: Long) =
            queryContacts("${RawContacts._ID}=?", arrayOf(id.toString())).firstOrNull() ?: throw FileNotFoundException()

    fun findContactByUid(uid: String) =
            queryContacts("${AndroidContact.COLUMN_UID}=?", arrayOf(uid)).firstOrNull()

    @Throws(FileNotFoundException::class)
    fun findGroupById(id: Long) =
        queryGroups("${Groups._ID}=?", arrayOf(id.toString())).firstOrNull() ?: throw FileNotFoundException()


    // helpers

    fun syncAdapterURI(uri: Uri) = uri.buildUpon()
            .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
            .appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name)
            .appendQueryParameter(RawContacts.ACCOUNT_TYPE, account.type)
            .build()!!

    fun rawContactsSyncUri() = syncAdapterURI(RawContacts.CONTENT_URI)
    fun groupsSyncUri() = syncAdapterURI(Groups.CONTENT_URI)

}