package vandy.mooc.presenter.ContactsOpsImplLoaderManager;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import vandy.mooc.common.Command;
import vandy.mooc.common.GenericAsyncTask;
import vandy.mooc.common.GenericAsyncTaskOps;
import vandy.mooc.common.Utils;
import vandy.mooc.presenter.ContactsOpsImpl;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
/**
* Insert all designated contacts in a background thread.
*/
public class InsertContactsCommand
implements GenericAsyncTaskOps<Iterator<String>, Void, Integer>,
Command<Iterator<String>> {
/**
* Store a reference to the ContactsOpsImpl object.
*/
private ContactsOpsImpl mOps;
/**
* Store a reference to the Application context's ContentResolver.
*/
private ContentResolver mContentResolver;
/**
* Constructor initializes the field.
*/
public InsertContactsCommand(ContactsOpsImpl ops) {
// Store the ContactOps and the ContentResolver from the
// Application context.
mOps = ops;
mContentResolver =
ops.getApplicationContext().getContentResolver();
}
/**
* Run the command.
*/
@SuppressWarnings("unchecked")
@Override
public void execute(Iterator<String> contactsIter) {
// Create a GenericAsyncTask to insert the contacts off the UI
// Thread.
final GenericAsyncTask<Iterator<String>,
Void,
Integer,
InsertContactsCommand> asyncTask =
new GenericAsyncTask<>(this);
// Execute the GenericAsyncTask.
asyncTask.execute(contactsIter);
}
/**
* Run in a background Thread to avoid blocking the UI Thread.
*/
@SuppressWarnings("unchecked")
@Override
public Integer doInBackground(Iterator<String>... contactsIter) {
// Insert all the contacts designated by the Iterator.
return insertAllContacts(contactsIter[0]);
}
/**
* A count of the number of results in the query are displayed in
* the UI Thread.
*/
@Override
public void onPostExecute(Integer count) {
Utils.showToast(mOps.getActivityContext(),
count
+ " contact(s) inserted");
}
/**
* Synchronously insert all contacts designated by the Iterator.
*/
private Integer insertAllContacts(Iterator<String> contactsIter) {
// Set up a batch operation on ContactsContentProvider.
final ArrayList<ContentProviderOperation> batchOperation =
new ArrayList<ContentProviderOperation>();
// Add each contact in the Iterator into the Contacts
// ContentProvider.
while (contactsIter.hasNext())
addContact(contactsIter.next(),
batchOperation);
try {
// Apply all the batched operations synchronously.
ContentProviderResult[] results =
mContentResolver.applyBatch(ContactsContract.AUTHORITY,
batchOperation);
// Divide by 2 since each insert required two operations.
return results.length / 2;
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
return 0;
}
/**
* Synchronously insert a contact with the designated @name into
* the ContactsContentProvider. This code is explained at
* http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html.
*/
private void addContact(String name,
List<ContentProviderOperation> cpops) {
final int position = cpops.size();
// First part of operation.
cpops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE,
mOps.getAccountType())
.withValue(RawContacts.ACCOUNT_NAME,
mOps.getAccountName())
.withValue(Contacts.STARRED,
1)
.build());
// Second part of operation.
cpops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,
position)
.withValue(Data.MIMETYPE,
StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME,
name)
.build());
}
}