Merge "updating the SampleSyncAdapter sample to add stream item and photo code" into ics-mr1
This commit is contained in:
@@ -45,8 +45,12 @@
|
|||||||
android:name="android.permission.READ_SYNC_SETTINGS" />
|
android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
android:name="android.permission.WRITE_SYNC_SETTINGS" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.READ_SOCIAL_STREAM" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.WRITE_SOCIAL_STREAM" />
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14"/>
|
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/icon"
|
||||||
|
|||||||
BIN
samples/SampleSyncAdapter/res/raw/img1.jpg
Normal file
BIN
samples/SampleSyncAdapter/res/raw/img1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -26,6 +26,7 @@ import android.provider.ContactsContract;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles execution of batch mOperations on Contacts provider.
|
* This class handles execution of batch mOperations on Contacts provider.
|
||||||
@@ -52,24 +53,27 @@ final public class BatchOperation {
|
|||||||
mOperations.add(cpo);
|
mOperations.add(cpo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri execute() {
|
public List<Uri> execute() {
|
||||||
Uri result = null;
|
List<Uri> resultUris = new ArrayList<Uri>();
|
||||||
|
|
||||||
if (mOperations.size() == 0) {
|
if (mOperations.size() == 0) {
|
||||||
return result;
|
return resultUris;
|
||||||
}
|
}
|
||||||
// Apply the mOperations to the content provider
|
// Apply the mOperations to the content provider
|
||||||
try {
|
try {
|
||||||
ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY,
|
ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY,
|
||||||
mOperations);
|
mOperations);
|
||||||
if ((results != null) && (results.length > 0))
|
if ((results != null) && (results.length > 0)){
|
||||||
result = results[0].uri;
|
for (int i = 0; i < results.length; i++){
|
||||||
|
resultUris.add(results[i].uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (final OperationApplicationException e1) {
|
} catch (final OperationApplicationException e1) {
|
||||||
Log.e(TAG, "storing contact data failed", e1);
|
Log.e(TAG, "storing contact data failed", e1);
|
||||||
} catch (final RemoteException e2) {
|
} catch (final RemoteException e2) {
|
||||||
Log.e(TAG, "storing contact data failed", e2);
|
Log.e(TAG, "storing contact data failed", e2);
|
||||||
}
|
}
|
||||||
mOperations.clear();
|
mOperations.clear();
|
||||||
return result;
|
return resultUris;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import android.content.ContentResolver;
|
|||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Email;
|
import android.provider.ContactsContract.CommonDataKinds.Email;
|
||||||
@@ -38,8 +41,14 @@ import android.provider.ContactsContract.Groups;
|
|||||||
import android.provider.ContactsContract.RawContacts;
|
import android.provider.ContactsContract.RawContacts;
|
||||||
import android.provider.ContactsContract.Settings;
|
import android.provider.ContactsContract.Settings;
|
||||||
import android.provider.ContactsContract.StatusUpdates;
|
import android.provider.ContactsContract.StatusUpdates;
|
||||||
|
import android.provider.ContactsContract.StreamItemPhotos;
|
||||||
|
import android.provider.ContactsContract.StreamItems;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -234,6 +243,43 @@ public class ContactManager {
|
|||||||
batchOperation.execute();
|
batchOperation.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrate how to add stream items and stream item photos to a raw
|
||||||
|
* contact. This just adds items for all of the contacts for this sync
|
||||||
|
* adapter with some locally created text and an image. You should check
|
||||||
|
* for stream items on the server that you are syncing with and use the
|
||||||
|
* text and photo data from there instead.
|
||||||
|
*
|
||||||
|
* @param context The context of Authenticator Activity
|
||||||
|
* @param rawContacts The list of users we want to update
|
||||||
|
*/
|
||||||
|
public static void addStreamItems(Context context, List<RawContact> rawContacts,
|
||||||
|
String accountName, String accountType) {
|
||||||
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
|
final BatchOperation batchOperation = new BatchOperation(context, resolver);
|
||||||
|
String text = "This is a test stream item!";
|
||||||
|
String message = "via SampleSyncAdapter";
|
||||||
|
for (RawContact rawContact : rawContacts) {
|
||||||
|
addContactStreamItem(context, lookupRawContact(resolver,
|
||||||
|
rawContact.getServerContactId()), accountName, accountType,
|
||||||
|
text, message, batchOperation );
|
||||||
|
}
|
||||||
|
List<Uri> streamItemUris = batchOperation.execute();
|
||||||
|
|
||||||
|
// Stream item photos are added after the stream items that they are
|
||||||
|
// associated with, using the stream item's ID as a reference.
|
||||||
|
|
||||||
|
for (Uri uri : streamItemUris){
|
||||||
|
// All you need is the ID of the stream item, which is the last index
|
||||||
|
// path segment returned by getPathSegments().
|
||||||
|
long streamItemId = Long.parseLong(uri.getPathSegments().get(
|
||||||
|
uri.getPathSegments().size()-1));
|
||||||
|
addStreamItemPhoto(context, resolver, streamItemId, accountName,
|
||||||
|
accountType, batchOperation);
|
||||||
|
}
|
||||||
|
batchOperation.execute();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* After we've finished up a sync operation, we want to clean up the sync-state
|
* After we've finished up a sync operation, we want to clean up the sync-state
|
||||||
* so that we're ready for the next time. This involves clearing out the 'dirty'
|
* so that we're ready for the next time. This involves clearing out the 'dirty'
|
||||||
@@ -518,7 +564,7 @@ public class ContactManager {
|
|||||||
* But it's a useful demo to see how it's done.
|
* But it's a useful demo to see how it's done.
|
||||||
*
|
*
|
||||||
* @param context the Authenticator Activity context
|
* @param context the Authenticator Activity context
|
||||||
* @param rawContact the contact who's status we should update
|
* @param rawContact the contact whose status we should update
|
||||||
* @param batchOperation allow us to batch together multiple operations
|
* @param batchOperation allow us to batch together multiple operations
|
||||||
*/
|
*/
|
||||||
private static void updateContactStatus(Context context, RawContact rawContact,
|
private static void updateContactStatus(Context context, RawContact rawContact,
|
||||||
@@ -549,6 +595,59 @@ public class ContactManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a stream item to a raw contact. The stream item is usually obtained
|
||||||
|
* from the server you are syncing with, but we create it here locally as an
|
||||||
|
* example.
|
||||||
|
*
|
||||||
|
* @param context the Authenticator Activity context
|
||||||
|
* @param rawContactId the raw contact ID that the stream item is associated with
|
||||||
|
* @param accountName the account name of the sync adapter
|
||||||
|
* @param accountType the account type of the sync adapter
|
||||||
|
* @param text the text of the stream item
|
||||||
|
* @param comments the comments for the stream item, such as where the stream item came from
|
||||||
|
* @param batchOperation allow us to batch together multiple operations
|
||||||
|
*/
|
||||||
|
private static void addContactStreamItem(Context context, long rawContactId,
|
||||||
|
String accountName, String accountType, String text, String comments,
|
||||||
|
BatchOperation batchOperation) {
|
||||||
|
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
final ContentResolver resolver = context.getContentResolver();
|
||||||
|
if (rawContactId > 0){
|
||||||
|
values.put(StreamItems.RAW_CONTACT_ID, rawContactId);
|
||||||
|
values.put(StreamItems.TEXT, text);
|
||||||
|
values.put(StreamItems.TIMESTAMP, System.currentTimeMillis());
|
||||||
|
values.put(StreamItems.COMMENTS, comments);
|
||||||
|
values.put(StreamItems.ACCOUNT_NAME, accountName);
|
||||||
|
values.put(StreamItems.ACCOUNT_TYPE, accountType);
|
||||||
|
|
||||||
|
batchOperation.add(ContactOperations.newInsertCpo(
|
||||||
|
StreamItems.CONTENT_URI, false, true).withValues(values).build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addStreamItemPhoto(Context context, ContentResolver
|
||||||
|
resolver, long streamItemId, String accountName, String accountType,
|
||||||
|
BatchOperation batchOperation){
|
||||||
|
|
||||||
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
|
||||||
|
R.raw.img1);
|
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 30, stream);
|
||||||
|
byte[] photoData = stream.toByteArray();
|
||||||
|
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
values.put(StreamItemPhotos.STREAM_ITEM_ID, streamItemId);
|
||||||
|
values.put(StreamItemPhotos.SORT_INDEX, 1);
|
||||||
|
values.put(StreamItemPhotos.PHOTO, photoData);
|
||||||
|
values.put(StreamItems.ACCOUNT_NAME, accountName);
|
||||||
|
values.put(StreamItems.ACCOUNT_TYPE, accountType);
|
||||||
|
|
||||||
|
batchOperation.add(ContactOperations.newInsertCpo(
|
||||||
|
StreamItems.CONTENT_PHOTO_URI, false, true).withValues(values).build());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the local system 'dirty' flag for a contact.
|
* Clear the local system 'dirty' flag for a contact.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import android.content.AbstractThreadedSyncAdapter;
|
|||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SyncResult;
|
import android.content.SyncResult;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -115,8 +116,21 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
// 2-way contact sync providers - it's more likely that one-way
|
// 2-way contact sync providers - it's more likely that one-way
|
||||||
// sync providers (IM clients, social networking apps, etc) would
|
// sync providers (IM clients, social networking apps, etc) would
|
||||||
// use this feature.
|
// use this feature.
|
||||||
|
|
||||||
ContactManager.updateStatusMessages(mContext, updatedContacts);
|
ContactManager.updateStatusMessages(mContext, updatedContacts);
|
||||||
|
|
||||||
|
// This is a demo of how you can add stream items for contacts on
|
||||||
|
// the client. This probably won't apply to
|
||||||
|
// 2-way contact sync providers - it's more likely that one-way
|
||||||
|
// sync providers (IM clients, social networking apps, etc) would
|
||||||
|
// use this feature. This is only supported in ICS MR1 or above.
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >=
|
||||||
|
Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||||
|
ContactManager.addStreamItems(mContext, updatedContacts,
|
||||||
|
account.name, account.type);
|
||||||
|
}
|
||||||
|
|
||||||
// Save off the new sync marker. On our next sync, we only want to receive
|
// Save off the new sync marker. On our next sync, we only want to receive
|
||||||
// contacts that have changed since this sync...
|
// contacts that have changed since this sync...
|
||||||
setServerSyncMarker(account, newSyncState);
|
setServerSyncMarker(account, newSyncState);
|
||||||
@@ -168,3 +182,4 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
mAccountManager.setUserData(account, SYNC_MARKER_KEY, Long.toString(marker));
|
mAccountManager.setUserData(account, SYNC_MARKER_KEY, Long.toString(marker));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user