Android Open Source - seagull Contacts Sync Adapter Service






From Project

Back to project page seagull.

License

The source code is released under:

GNU General Public License

If you think the Android project seagull listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*******************************************************************************
 * Copyright 2010 Sam Steele /*from w  ww  . ja va 2s  .com*/
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package ru.perm.trubnikov.seagull;

import android.accounts.Account;
import android.accounts.OperationCanceledException;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.database.Cursor;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.util.Log;

/**
 * @author sam
 * 
 */
public class ContactsSyncAdapterService extends Service {
  
  //private static final String TAG = "ContactsSyncAdapterService";
  private static SyncAdapterImpl sSyncAdapter = null;
  //private static ContentResolver mContentResolver = null;
  //private static String UsernameColumn = ContactsContract.RawContacts.SYNC1;
  //private static String PhotoTimestampColumn = ContactsContract.RawContacts.SYNC2;

  public ContactsSyncAdapterService() {
    super();
  }

  private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {
    private Context mContext;

    public SyncAdapterImpl(Context context) {
      super(context, true);
      mContext = context;
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
      try {
        ContactsSyncAdapterService.performSync(mContext, account, extras, authority, provider, syncResult);
      } catch (OperationCanceledException e) {
      }
    }
  }

  @Override
  public IBinder onBind(Intent intent) {
    IBinder ret = null;
    ret = getSyncAdapter().getSyncAdapterBinder();
    return ret;
  }

  private SyncAdapterImpl getSyncAdapter() {
    if (sSyncAdapter == null)
      sSyncAdapter = new SyncAdapterImpl(this);
    return sSyncAdapter;
  }
/*
  private static void addContact(Account account, String name, String username) {
    Log.i(TAG, "Adding contact: " + name);
    ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();

    ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
    builder.withValue(RawContacts.ACCOUNT_NAME, account.name);
    builder.withValue(RawContacts.ACCOUNT_TYPE, account.type);
    builder.withValue(RawContacts.SYNC1, username);
    operationList.add(builder.build());

    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
    builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0);
    builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
    builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
    operationList.add(builder.build());

    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
    builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
    builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.ru.perm.trubnikov.seagull.profile");
    builder.withValue(ContactsContract.Data.DATA1, username);
    builder.withValue(ContactsContract.Data.DATA2, "SyncProviderDemo Profile");
    builder.withValue(ContactsContract.Data.DATA3, "View profile");
    operationList.add(builder.build());

    try {
      mContentResolver.applyBatch(ContactsContract.AUTHORITY, operationList);
    } catch (Exception e) {
      
      e.printStackTrace();
    }
  }

  private static void updateContactStatus(ArrayList<ContentProviderOperation> operationList, long rawContactId, String status) {
    Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId);
    Uri entityUri = Uri.withAppendedPath(rawContactUri, Entity.CONTENT_DIRECTORY);
    Cursor c = mContentResolver.query(entityUri, new String[] { RawContacts.SOURCE_ID, Entity.DATA_ID, Entity.MIMETYPE, Entity.DATA1 }, null, null, null);
    try {
      while (c.moveToNext()) {
        if (!c.isNull(1)) {
          String mimeType = c.getString(2);

          if (mimeType.equals("vnd.android.cursor.item/vnd.ru.perm.trubnikov.seagull.profile")) {
            ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.StatusUpdates.CONTENT_URI);
            builder.withValue(ContactsContract.StatusUpdates.DATA_ID, c.getLong(1));
            builder.withValue(ContactsContract.StatusUpdates.STATUS, status);
            builder.withValue(ContactsContract.StatusUpdates.STATUS_RES_PACKAGE, "ru.perm.trubnikov.seagull");
            builder.withValue(ContactsContract.StatusUpdates.STATUS_LABEL, R.string.app_name);
            builder.withValue(ContactsContract.StatusUpdates.STATUS_ICON, R.drawable.ic_launcher);
            builder.withValue(ContactsContract.StatusUpdates.STATUS_TIMESTAMP, System.currentTimeMillis());
            operationList.add(builder.build());

            //Only change the text of our custom entry to the status message pre-Honeycomb, as the newer contacts app shows
            //statuses elsewhere
            if(Integer.decode(Build.VERSION.SDK) < 11) {
              builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
              builder.withSelection(BaseColumns._ID + " = '" + c.getLong(1) + "'", null);
              builder.withValue(ContactsContract.Data.DATA3, status);
              operationList.add(builder.build());
            }
          }
        }
      }
    } finally {
      c.close();
    }
  }
  
  private static void updateContactPhoto(ArrayList<ContentProviderOperation> operationList, long rawContactId, byte[] photo) {
    ContentProviderOperation.Builder builder = ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI);
    builder.withSelection(ContactsContract.Data.RAW_CONTACT_ID + " = '" + rawContactId 
        + "' AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'", null);
    operationList.add(builder.build());

    try {
      if(photo != null) {
        builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
        builder.withValue(ContactsContract.CommonDataKinds.Photo.RAW_CONTACT_ID, rawContactId);
        builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
        builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, photo);
        operationList.add(builder.build());

        builder = ContentProviderOperation.newUpdate(ContactsContract.RawContacts.CONTENT_URI);
        builder.withSelection(ContactsContract.RawContacts.CONTACT_ID + " = '" + rawContactId + "'", null);
        builder.withValue(PhotoTimestampColumn, String.valueOf(System.currentTimeMillis()));
        operationList.add(builder.build());
      }
    } catch (Exception e) {
      
      e.printStackTrace();
    }
  }*/
  /*
  private static class SyncEntry {
    public Long raw_id = 0L;
    public Long photo_timestamp = null;
  }*/

  
  private static void performSync(Context context, Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult)
      throws OperationCanceledException {
    
    DBHelper dbHelper;
    dbHelper = new DBHelper(context);
    
    try {
      
      Log.d("seagull", "sync: start");

          long startFromId = dbHelper.getSettingsParamInt("syncfrom");
      
          Log.d("seagull", "sync: startFromId = " + startFromId);
        
          // ?????????? ???????? ??? ????
          long last_cid = -1;
          Cursor c = context.getContentResolver().query(
              Data.CONTENT_URI, 
              null, 
              Data.HAS_PHONE_NUMBER + " != 0 AND " + Data.MIMETYPE + "=? AND " + Data.CONTACT_ID + " > " + startFromId, 
              new String[]{Phone.CONTENT_ITEM_TYPE},
              Data.CONTACT_ID);
     
      while (c.moveToNext()) {

          if (last_cid != c.getLong(c.getColumnIndex(Data.CONTACT_ID))) {
            
            Log.d("seagull", "sync: c_id = " + c.getLong(c.getColumnIndex(Data.CONTACT_ID)) +", raw_id = " +c.getLong(c.getColumnIndex(Data.RAW_CONTACT_ID))+ ", name = " + c.getString(c.getColumnIndex(Data.DISPLAY_NAME)));
            ContactsManager.addSeagullContact(context, account, c.getString(c.getColumnIndex(Data.DISPLAY_NAME)), c.getLong(c.getColumnIndex(Data.RAW_CONTACT_ID)));
            last_cid  = c.getLong(c.getColumnIndex(Data.CONTACT_ID));
          }
      }
        
      if (last_cid > 0) {
        dbHelper.setSettingsParamInt("syncfrom", last_cid);
      }
    
    }
        catch (Exception e) {
         Log.d("seagull", "sync: EXCEPTION! " + e.toString() +" Message:" +e.getMessage());
       }
    finally {
      dbHelper.close();
    }
    
    Log.d("seagull", "sync: finish");
    
    
    
    
    
    
    
    //Log.d("seagull", "performSync: " + account.toString());
    //ContactsManager.addSeagullContact(context, account, "ChaykaLogin", "chaykauser", 154);
/*
     long last_cid = -1;
     Cursor c = context.getContentResolver().query(
              Data.CONTENT_URI, 
              null, 
              Data.HAS_PHONE_NUMBER + " != 0 AND " + Data.MIMETYPE + "=? ", 
              new String[]{Phone.CONTENT_ITEM_TYPE},
              Data.CONTACT_ID);
     
      while (c.moveToNext()) {
          //long id = c.getLong(c.getColumnIndex(Data.CONTACT_ID));
          //long raw_id = c.getLong(c.getColumnIndex(Data.RAW_CONTACT_ID));
          //String name = c.getString(c.getColumnIndex(Data.DISPLAY_NAME_PRIMARY));
          //String data1 = c.getString(c.getColumnIndex(Data.DATA1));

          //System.out.println(id + ", name=" + name + ", data1=" + data1);
          if (last_cid != c.getLong(c.getColumnIndex(Data.CONTACT_ID))) {
            
            Log.d("seagull", "c_id = " + c.getLong(c.getColumnIndex(Data.CONTACT_ID)) +", raw_id = " +c.getLong(c.getColumnIndex(Data.RAW_CONTACT_ID))+ ", name = " + c.getString(c.getColumnIndex(Data.DISPLAY_NAME_PRIMARY)));
            ContactsManager.addSeagullContact(context, account, c.getString(c.getColumnIndex(Data.DISPLAY_NAME_PRIMARY)), c.getLong(c.getColumnIndex(Data.RAW_CONTACT_ID)));
            last_cid  = c.getLong(c.getColumnIndex(Data.CONTACT_ID));
          }
      }
    */
    
    
    
/*
    // Load the local contacts
    Uri rawContactUri = RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(RawContacts.ACCOUNT_NAME, account.name).appendQueryParameter(
        RawContacts.ACCOUNT_TYPE, account.type).build();
    Cursor c1 = mContentResolver.query(rawContactUri, new String[] { BaseColumns._ID, UsernameColumn, PhotoTimestampColumn }, null, null, null);
    while (c1.moveToNext()) {
      SyncEntry entry = new SyncEntry();
      entry.raw_id = c1.getLong(c1.getColumnIndex(BaseColumns._ID));
      entry.photo_timestamp = c1.getLong(c1.getColumnIndex(PhotoTimestampColumn));
      localContacts.put(c1.getString(1), entry);
    }

    ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
    try {
      // If we don't have any contacts, create one. Otherwise, set a
      // status message
      if (localContacts.get("efudd1") == null) {
        addContact(account, "Chayka Contact", "efudd1");
      } else {
        if (localContacts.get("efudd1").photo_timestamp == null || System.currentTimeMillis() > (localContacts.get("efudd1").photo_timestamp + 604800000L)) {
          //You would probably download an image file and just pass the bytes, but this sample doesn't use network so we'll decode and re-compress the icon resource to get the bytes
          ByteArrayOutputStream stream = new ByteArrayOutputStream();
          Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);
          icon.compress(CompressFormat.PNG, 0, stream);
          updateContactPhoto(operationList, localContacts.get("efudd1").raw_id, stream.toByteArray());
        }
        updateContactStatus(operationList, localContacts.get("efudd1").raw_id, "hunting wabbits");
      }
      if (operationList.size() > 0)
        mContentResolver.applyBatch(ContactsContract.AUTHORITY, operationList);
    } catch (Exception e1) {
      
      e1.printStackTrace();
    }*/
  }
}




Java Source Code List

ru.perm.trubnikov.seagull.AccountAuthenticatorService.java
ru.perm.trubnikov.seagull.ContactsManager.java
ru.perm.trubnikov.seagull.ContactsSyncAdapterService.java
ru.perm.trubnikov.seagull.DbHelper.java
ru.perm.trubnikov.seagull.LoginActivity.java
ru.perm.trubnikov.seagull.MainActivity.java
ru.perm.trubnikov.seagull.ProfileActivity.java
ru.perm.trubnikov.seagull.SelectOperatorActivity.java