FileDocCategorySizeDatePackage
GoogleContactsProvider.javaAPI DocAndroid 1.5 API8245Wed May 06 22:42:48 BST 2009com.android.providers.contacts

GoogleContactsProvider

public class GoogleContactsProvider extends ContactsProvider
A subclass of the platform contacts provider that adds the Google contacts sync adapter.

Fields Summary
private static final int
PURGE_CONTACTS_DELAY_IN_MS
private static final String
ACTION_PURGE_CONTACTS
private static final String
PURGE_UNSYNCED_CONTACTS_SQL
SQL query that deletes all contacts for a given account that are not a member of at least one group that has the "should_sync" column set to a non-zero value.
private android.content.SyncAdapter
mSyncAdapter
private android.app.AlarmManager
mAlarmService
Constructors Summary
Methods Summary
private voidensureAlarmService()

        if (mAlarmService == null) {
            mAlarmService = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
        }
    
public synchronized android.content.SyncAdaptergetSyncAdapter()

        if (mSyncAdapter != null) {
            return mSyncAdapter;
        }
        
        mSyncAdapter = new ContactsSyncAdapter(getContext(), this);
        return mSyncAdapter;
    
public booleanonCreate()


    
       
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (ACTION_PURGE_CONTACTS.equals(intent.getAction())) {
                    purgeContacts(intent.getStringExtra("account"));
                }
            }
        };
        getContext().registerReceiver(receiver, new IntentFilter(ACTION_PURGE_CONTACTS));
        return super.onCreate();
    
protected voidonLocalChangesForAccount(android.content.ContentResolver resolver, java.lang.String account, boolean groupsModified)

        ContactsSyncAdapter.updateSubscribedFeeds(resolver, account);
        if (groupsModified) {
            schedulePurge(account);
        }
    
public voidonSyncStop(android.content.SyncContext context, boolean success)

        super.onSyncStop(context, success);
        purgeContacts(getSyncingAccount());
    
private voidpurgeContacts(java.lang.String account)

        if (isTemporary()) {
            throw new IllegalStateException("this must not be called on temp providers");
        }
        SQLiteDatabase db = getDatabase();
        db.beginTransaction();
        try {
            final String value = Contacts.Settings.getSetting(getContext().getContentResolver(),
                    account, Contacts.Settings.SYNC_EVERYTHING);
            final boolean shouldSyncEverything = !TextUtils.isEmpty(value) && !"0".equals(value);
            if (!shouldSyncEverything) {
                db.execSQL(PURGE_UNSYNCED_CONTACTS_SQL, new String[]{account});
            }

            // remove any feeds in the SyncData that aren't in the current sync set.
            Set<String> feedsToSync = Sets.newHashSet();
            feedsToSync.add(ContactsSyncAdapter.getGroupsFeedForAccount(account));
            ContactsSyncAdapter.addContactsFeedsToSync(getContext().getContentResolver(), account,
                    feedsToSync);
            AbstractGDataSyncAdapter.GDataSyncData syncData = readSyncData(account);
            if (syncData != null) {
                Iterator<Map.Entry<String, AbstractGDataSyncAdapter.GDataSyncData.FeedData>> iter =
                        syncData.feedData.entrySet().iterator();
                boolean updatedSyncData = false;
                while (iter.hasNext()) {
                    Map.Entry<String, AbstractGDataSyncAdapter.GDataSyncData.FeedData> entry =
                            iter.next();
                    if (!feedsToSync.contains(entry.getKey())) {
                        iter.remove();
                        updatedSyncData = true;
                    }
                }
                if (updatedSyncData) {
                    writeSyncData(account, syncData);
                }
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
    
private AbstractGDataSyncAdapter.GDataSyncDatareadSyncData(java.lang.String account)

        if (!getDatabase().inTransaction()) {
            throw new IllegalStateException("you can only call this from within a transaction");
        }
        Cursor c = getDatabase().query("_sync_state", new String[]{"data"}, "_sync_account=?",
                new String[]{account}, null, null, null);
        try {
            byte[] data = null;
            if (c.moveToNext()) data = c.getBlob(0);
            return ContactsSyncAdapter.newGDataSyncDataFromBytes(data);
        } finally {
            c.close();
        }
    
private voidschedulePurge(java.lang.String account)
Delete any non-sync_dirty contacts associated with the given account that are not in any of the synced groups.

        if (isTemporary()) {
            throw new IllegalStateException("this must not be called on temp providers");
        }
        ensureAlarmService();
        final Intent intent = new Intent(ACTION_PURGE_CONTACTS);
        intent.putExtra("account", account);
        final PendingIntent pendingIntent = PendingIntent.getBroadcast(
                getContext(), 0 /* ignored */, intent, 0);
        mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                SystemClock.elapsedRealtime() + PURGE_CONTACTS_DELAY_IN_MS,
                pendingIntent);
    
private voidwriteSyncData(java.lang.String account, AbstractGDataSyncAdapter.GDataSyncData syncData)

        final SQLiteDatabase db = getDatabase();
        if (!db.inTransaction()) {
            throw new IllegalStateException("you can only call this from within a transaction");
        }
        db.delete("_sync_state", "_sync_account=?", new String[]{account});
        ContentValues values = new ContentValues();
        values.put("data", ContactsSyncAdapter.newBytesFromGDataSyncData(syncData));
        values.put("_sync_account", account);
        db.insert("_sync_state", "_sync_account", values);