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
));
55 Log
.d(TAG
, "Found Contact id: " + id
+ " with lookupkey: "+lookup
);
58 FileInputStream fis
= getContactVcard(lookup
);
60 HttpPut query
= new HttpPut(
63 getAccount().name
.split("@")[0]+
69 byte[] b
= new byte[fis
.available()];
71 query
.setEntity(new ByteArrayEntity(b
));
72 HttpResponse response
= fireRawRequest(query
);
74 if(201 != response
.getStatusLine().getStatusCode()) {
75 syncResult
.stats
.numIoExceptions
++;
77 // TODO make a webdav request based on the stream
78 // TODO send request to the ownCloud server
79 // TODO mark the current contact as synced - where to store?
81 } catch (IOException e
) {
82 syncResult
.stats
.numIoExceptions
++;
83 } catch (OperationCanceledException e
) {
84 //TODO maybe to a better break here
86 } catch (AuthenticatorException e
) {
87 syncResult
.stats
.numAuthExceptions
++;
94 protected Uri
getUri() {
95 Uri uri
= Uri
.parse(this.getAccountManager().getUserData(getAccount(), AccountAuthenticator
.KEY_CONTACT_URL
));
100 * Returns the vCard based on the LookupKey for Contact as Stream
104 * @throws IOException
106 private FileInputStream
getContactVcard(String lookupKey
) throws IOException
{
107 Uri uri
= Uri
.withAppendedPath(ContactsContract
.Contacts
.CONTENT_VCARD_URI
, lookupKey
);
108 AssetFileDescriptor fd
= getContext().getContentResolver().openAssetFileDescriptor(uri
, "r");
109 return fd
.createInputStream();
113 * Obtains the contact list.
115 * @return A cursor for for accessing the contact list.
117 private Cursor
getContacts()
120 Uri uri
= ContactsContract
.Contacts
.CONTENT_URI
;
121 String
[] projection
= new String
[] {
122 ContactsContract
.Contacts
._ID
,
123 ContactsContract
.Contacts
.LOOKUP_KEY
126 boolean showInvisible
= false
;
127 String selection
= ContactsContract
.Contacts
.IN_VISIBLE_GROUP
+ " = '" +
128 (showInvisible ?
"0" : "1") + "'";
129 String
[] selectionArgs
= null
;
130 String sortOrder
= ContactsContract
.Contacts
._ID
+ " DESC";
132 return getContext().getContentResolver().query(uri
, projection
, selection
, selectionArgs
, sortOrder
);