1 package eu
.alefzero
.owncloud
.syncadapter
;
3 import java
.io
.FileInputStream
;
4 import java
.io
.FileNotFoundException
;
5 import java
.io
.IOException
;
7 import android
.accounts
.AccountManager
;
8 import org
.apache
.http
.HttpResponse
;
9 import org
.apache
.http
.client
.methods
.HttpPut
;
10 import org
.apache
.http
.entity
.ByteArrayEntity
;
12 import eu
.alefzero
.owncloud
.authenticator
.AccountAuthenticator
;
13 import eu
.alefzero
.webdav
.HttpPropFind
;
15 import android
.accounts
.Account
;
16 import android
.accounts
.AuthenticatorException
;
17 import android
.accounts
.OperationCanceledException
;
18 import android
.content
.ContentProviderClient
;
19 import android
.content
.Context
;
20 import android
.content
.SyncResult
;
21 import android
.content
.res
.AssetFileDescriptor
;
22 import android
.database
.Cursor
;
23 import android
.net
.Uri
;
24 import android
.os
.Bundle
;
25 import android
.provider
.ContactsContract
;
26 import android
.util
.Log
;
28 public class ContactSyncAdapter
extends AbstractOwnCloudSyncAdapter
{
30 private static final String TAG
= "ContactSyncAdapter";
32 public ContactSyncAdapter(Context context
, boolean autoInitialize
) {
33 super(context
, autoInitialize
);
37 public synchronized void onPerformSync(
41 ContentProviderClient provider
,
42 SyncResult syncResult
) {
44 this.setAccount(account
);
45 this.setContentProvider(provider
);
47 // TODO find all contacts on ownCloud that not synced or the sync date is behind than the last sync date
48 Cursor cursor
= getContacts();
49 if (cursor
!= null
&& cursor
.getCount() > 0) {
50 while (cursor
.moveToNext()) {
51 String id
= cursor
.getString(
52 cursor
.getColumnIndex(ContactsContract
.Contacts
._ID
));
53 String lookup
= cursor
.getString(
54 cursor
.getColumnIndex(ContactsContract
.Contacts
.LOOKUP_KEY
));
57 FileInputStream fis
= getContactVcard(lookup
);
59 HttpPut query
= new HttpPut(
62 getAccount().name
.split("@")[0]+
67 byte[] b
= new byte[fis
.available()];
69 query
.setEntity(new ByteArrayEntity(b
));
70 HttpResponse response
= fireRawRequest(query
);
71 if(201 != response
.getStatusLine().getStatusCode()) {
72 syncResult
.stats
.numIoExceptions
++;
74 // TODO make a webdav request based on the stream
75 // TODO send request to the ownCloud server
76 // TODO mark the current contact as synced - where to store?
78 } catch (IOException e
) {
79 syncResult
.stats
.numIoExceptions
++;
80 } catch (OperationCanceledException e
) {
81 //TODO maybe to a better break here
83 } catch (AuthenticatorException e
) {
84 syncResult
.stats
.numAuthExceptions
++;
90 protected Uri
getUri() {
91 Uri uri
= Uri
.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator
.KEY_CONTACT_URL
));
96 * Returns the vCard based on the LookupKey for Contact as Stream
100 * @throws IOException
102 private FileInputStream
getContactVcard(String lookupKey
) throws IOException
{
103 Uri uri
= Uri
.withAppendedPath(ContactsContract
.Contacts
.CONTENT_VCARD_URI
, lookupKey
);
104 AssetFileDescriptor fd
= getContext().getContentResolver().openAssetFileDescriptor(uri
, "r");
105 return fd
.createInputStream();
109 * Obtains the contact list.
111 * @return A cursor for for accessing the contact list.
113 private Cursor
getContacts()
116 Uri uri
= ContactsContract
.Contacts
.CONTENT_URI
;
117 String
[] projection
= new String
[] {
118 ContactsContract
.Contacts
._ID
,
119 ContactsContract
.Contacts
.LOOKUP_KEY
122 boolean showInvisible
= false
;
123 String selection
= ContactsContract
.Contacts
.IN_VISIBLE_GROUP
+ " = '" +
124 (showInvisible ?
"0" : "1") + "'";
125 String
[] selectionArgs
= null
;
126 String sortOrder
= ContactsContract
.Contacts
._ID
+ " DESC";
128 return getContext().getContentResolver().query(uri
, projection
, selection
, selectionArgs
, sortOrder
);