1
1
package net .yuki24 .examples .AccountManager .core ;
2
2
3
+ import java .util .ArrayList ;
4
+ import java .util .HashMap ;
3
5
import android .accounts .Account ;
4
6
import android .accounts .OperationCanceledException ;
5
7
import android .app .Service ;
6
8
import android .content .AbstractThreadedSyncAdapter ;
7
9
import android .content .ContentProviderClient ;
10
+ import android .content .ContentProviderOperation ;
8
11
import android .content .ContentResolver ;
12
+ import android .content .ContentUris ;
9
13
import android .content .Context ;
10
14
import android .content .Intent ;
11
15
import android .content .SyncResult ;
16
+ import android .database .Cursor ;
17
+ import android .net .Uri ;
12
18
import android .os .Bundle ;
13
19
import android .os .IBinder ;
20
+ import android .provider .BaseColumns ;
21
+ import android .provider .ContactsContract ;
22
+ import android .provider .ContactsContract .CommonDataKinds .StructuredName ;
23
+ import android .provider .ContactsContract .Data ;
24
+ import android .provider .ContactsContract .RawContacts ;
25
+ import android .provider .ContactsContract .RawContacts .Entity ;
26
+ import android .provider .ContactsContract .CommonDataKinds .Phone ;
14
27
import android .util .Log ;
15
28
16
29
public class ContactsSyncAdapterService extends Service {
@@ -35,6 +48,8 @@ public void onPerformSync(Account account, Bundle extras, String authority, Cont
35
48
try {
36
49
ContactsSyncAdapterService .performSync (mContext , account , extras , authority , provider , syncResult );
37
50
} catch (OperationCanceledException e ) {
51
+ // TODO Auto-generated catch block
52
+ e .printStackTrace ();
38
53
}
39
54
}
40
55
}
@@ -51,10 +66,99 @@ private SyncAdapterImpl getSyncAdapter() {
51
66
return sSyncAdapter ;
52
67
}
53
68
54
- private static void performSync (Context context , Account account , Bundle extras , String authority , ContentProviderClient provider , SyncResult syncResult )
55
- throws OperationCanceledException {
69
+ private static void performSync (Context context , Account account , Bundle extras , String authority ,
70
+ ContentProviderClient provider , SyncResult syncResult ) throws OperationCanceledException {
56
71
mContentResolver = context .getContentResolver ();
57
72
Log .i (TAG , "performSync: " + account .toString ());
73
+
58
74
//This is where the magic will happen!
75
+ HashMap <String , Long > localContacts = new HashMap <String , Long >();
76
+ mContentResolver = context .getContentResolver ();
77
+
78
+ // Load the local example contacts
79
+ Uri rawContactUri = RawContacts .CONTENT_URI .buildUpon ()
80
+ .appendQueryParameter (RawContacts .ACCOUNT_NAME , account .name )
81
+ .appendQueryParameter (RawContacts .ACCOUNT_TYPE , account .type )
82
+ .build ();
83
+ Cursor c1 = mContentResolver .query (rawContactUri , new String []{BaseColumns ._ID , RawContacts .SYNC1 }, null , null , null );
84
+ while (c1 .moveToNext ()) { localContacts .put (c1 .getString (1 ), c1 .getLong (0 )); }
85
+
86
+ ArrayList <ContentProviderOperation > operationList = new ArrayList <ContentProviderOperation >();
87
+ try {
88
+ // Here comes the actual update of contacts
89
+ if (!localContacts .containsKey ("example" ))
90
+ addContact (account , "Account Example" , "example" );
91
+ else
92
+ updateContactStatus (operationList , localContacts .get ("example" ));
93
+
94
+ if (operationList .size () > 0 ) mContentResolver .applyBatch (ContactsContract .AUTHORITY , operationList );
95
+ } catch (Exception e ) {
96
+ // TODO Auto-generated catch block
97
+ e .printStackTrace ();
98
+ }
99
+ }
100
+
101
+ private static void addContact (Account account , String name , String username ) {
102
+ ArrayList <ContentProviderOperation > operationList = new ArrayList <ContentProviderOperation >();
103
+
104
+ // Create our RawContact
105
+ ContentProviderOperation .Builder builder = ContentProviderOperation .newInsert (RawContacts .CONTENT_URI );
106
+ builder .withValue (RawContacts .ACCOUNT_NAME , account .name );
107
+ builder .withValue (RawContacts .ACCOUNT_TYPE , account .type );
108
+ builder .withValue (RawContacts .SYNC1 , username );
109
+ operationList .add (builder .build ());
110
+
111
+ // Create a Data record of common type 'StructuredName' for our RawContact
112
+ builder = ContentProviderOperation .newInsert (Data .CONTENT_URI );
113
+ builder .withValueBackReference (StructuredName .RAW_CONTACT_ID , 0 );
114
+ builder .withValue (Data .MIMETYPE , StructuredName .CONTENT_ITEM_TYPE );
115
+ builder .withValue (StructuredName .DISPLAY_NAME , name );
116
+ operationList .add (builder .build ());
117
+
118
+ // Create a Data record of phone number
119
+ builder = ContentProviderOperation .newInsert (Data .CONTENT_URI );
120
+ builder .withValueBackReference (StructuredName .RAW_CONTACT_ID , 0 );
121
+ builder .withValue (Data .MIMETYPE , Phone .CONTENT_ITEM_TYPE );
122
+ builder .withValue (Phone .NUMBER , "819012345678" );
123
+ operationList .add (builder .build ());
124
+
125
+ // Create a Data record of custom type to display a link to the sample profile
126
+ builder = ContentProviderOperation .newInsert (Data .CONTENT_URI );
127
+ builder .withValueBackReference (Data .RAW_CONTACT_ID , 0 );
128
+ builder .withValue (Data .MIMETYPE , "vnd.android.cursor.item/vnd.net.yuki24.examples.profile" );
129
+ builder .withValue (Data .DATA2 , "Yuki24 example Profile" );
130
+ builder .withValue (Data .DATA3 , "View profile" );
131
+ builder .withValue (Data .DATA4 , username );
132
+ operationList .add (builder .build ());
133
+
134
+ try {
135
+ mContentResolver .applyBatch (ContactsContract .AUTHORITY , operationList );
136
+ } catch (Exception e ) {
137
+ e .printStackTrace ();
138
+ }
139
+ }
140
+
141
+ private static void updateContactStatus (ArrayList <ContentProviderOperation > operationList , long rawContactId ) {
142
+ Uri rawContactUri = ContentUris .withAppendedId (RawContacts .CONTENT_URI , rawContactId );
143
+ Uri entityUri = Uri .withAppendedPath (rawContactUri , Entity .CONTENT_DIRECTORY );
144
+ Cursor c = mContentResolver .query (entityUri , new String []{RawContacts .SOURCE_ID , Entity .DATA_ID , Entity .MIMETYPE , Entity .DATA1 }, null , null , null );
145
+
146
+ try {
147
+ while (c .moveToNext ()) {
148
+ if (!c .isNull (1 )) continue ;
149
+
150
+ String mimeType = c .getString (2 );
151
+ if (mimeType .equals (Phone .CONTENT_ITEM_TYPE )) {
152
+ ContentProviderOperation .Builder builder = ContentProviderOperation .newUpdate (Data .CONTENT_URI );
153
+ builder .withSelection (BaseColumns ._ID + " = ?" , new String []{c .getString (1 )});
154
+ builder .withValue (Phone .NUMBER , "819087654321" );
155
+ operationList .add (builder .build ());
156
+ } else if (mimeType .equals ("vnd.android.cursor.item/vnd.net.yuki24.examples.profile" )) {
157
+ // Log.i(TAG, "update own profile.");
158
+ }
159
+ }
160
+ } finally {
161
+ c .close ();
162
+ }
59
163
}
60
164
}
0 commit comments