package com.google.mcommerce.sample.android.chapter07.contentProvider;
import java.util.ArrayList;
import android.app.ListActivity;
import android.app.LoaderManager;
import android.content.ContentProviderOperation;
import android.content.ContentValues;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.OperationApplicationException;
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.QuickContactBadge;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
import com.google.mcommerce.sample.android.R;
public class ContactsActivity extends ListActivity implements OnClickListener,
LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "ContactsActivity";
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
Contacts._ID, // 0
Contacts.DISPLAY_NAME, // 1
Contacts.STARRED, // 2
Contacts.TIMES_CONTACTED, // 3
Contacts.CONTACT_PRESENCE, // 4
Contacts.PHOTO_ID, // 5
Contacts.LOOKUP_KEY, // 6
Contacts.HAS_PHONE_NUMBER, // 7
};
static final int SUMMARY_ID_COLUMN_INDEX = 0;
static final int SUMMARY_NAME_COLUMN_INDEX = 1;
static final int SUMMARY_STARRED_COLUMN_INDEX = 2;
static final int SUMMARY_TIMES_CONTACTED_COLUMN_INDEX = 3;
static final int SUMMARY_PRESENCE_STATUS_COLUMN_INDEX = 4;
static final int SUMMARY_PHOTO_ID_COLUMN_INDEX = 5;
static final int SUMMARY_LOOKUP_KEY = 6;
static final int SUMMARY_HAS_PHONE_COLUMN_INDEX = 7;
private Button insertButton;
private Button deleteButton;
private ContactListItemAdapter adapter;
private Button updateButton;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.c07_quick_contact);
insertButton = (Button) findViewById(R.id.button_insert);
insertButton.setOnClickListener(this);
deleteButton = (Button) findViewById(R.id.button_delete);
deleteButton.setOnClickListener(this);
updateButton = (Button) findViewById(R.id.button_update);
updateButton.setOnClickListener(this);
adapter = new ContactListItemAdapter(this,
R.layout.c07_quick_contact_item, null);
setListAdapter(adapter);
getLoaderManager().initLoader(0, null, this);
}
private final class ContactListItemAdapter extends ResourceCursorAdapter {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
return super.getView(position, convertView, parent);
}
public ContactListItemAdapter(Context context, int layout, Cursor c) {
super(context, layout, c);
}
// 记录被选择的联系人
ArrayList<Long> state = new ArrayList<Long>();
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ContactListItemCache cache = (ContactListItemCache) view
.getTag();
// Set the name
cursor.copyStringToBuffer(SUMMARY_NAME_COLUMN_INDEX,
cache.nameBuffer);
int size = cache.nameBuffer.sizeCopied;
final Long id = cursor.getLong(SUMMARY_ID_COLUMN_INDEX);
cache.selected
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
log("checkedid" + id);
state.add(id);
} else {
log("ucheckedid" + id);
state.remove(id);
}
}
});
if (state.contains(id)) {
cache.selected.setChecked(true);
} else {
cache.selected.setChecked(false);
}
cache.nameView.setText(cache.nameBuffer.data, 0, size);
// 获得联系人的ID
final long contactId = cursor.getLong(SUMMARY_ID_COLUMN_INDEX);
// 获得联系人的lookup_key
final String lookupKey = cursor.getString(SUMMARY_LOOKUP_KEY);
// 将当前联系人与QuickContactBadge控件关联
cache.photoView.assignContactUri(Contacts.getLookupUri(contactId,
lookupKey));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = super.newView(context, cursor, parent);
ContactListItemCache cache = new ContactListItemCache();
cache.nameView = (TextView) view.findViewById(R.id.name);
cache.photoView = (QuickContactBadge) view.findViewById(R.id.badge);
cache.selected = (CheckBox) view.findViewById(R.id.selected);
view.setTag(cache);
return view;
}
}
/**
* 首先向RawContacts.CONTENT_URI执行一个插入操作,目的是获取系统返回的rawContactId
* 这是后面插入data表的数据,只有执行空值插入,才能使插入的联系人在通讯录里可见
*/
public void insertContact() {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int rawContactInsertIndex = ops.size();
// 首先向RawContacts.CONTENT_URI执行一个插入,目的是获取系统返回的rawContactId
ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
.withValue(RawContacts.ACCOUNT_TYPE, "google.com")
.withValue(RawContacts.ACCOUNT_NAME, "leeivan2008@google.com")
.build());
// 往data表写入姓名数据
ops.add(ContentProviderOperation
.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
.withValue(StructuredName.DISPLAY_NAME, "Tom").build());
// 往data表写入电话数据
ops.add(ContentProviderOperation
.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, "12345678901")
.withValue(Phone.TYPE, Phone.TYPE_MOBILE).build());
// 往data表写入Email数据
ops.add(ContentProviderOperation
.newInsert(Data.CONTENT_URI)
.withValueBackReference(Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
.withValue(Email.DATA, "tom@gmail.com")
.withValue(Email.TYPE, Email.TYPE_WORK).build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
final static class ContactListItemCache {
public TextView nameView;
public QuickContactBadge photoView;
public CheckBox selected;
public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.button_insert:
insertContact();
break;
case R.id.button_delete:
deleteContact();
break;
case R.id.button_update:
updateContact();
break;
}
}
private void updateContact() {
// TODO Auto-generated method stub
ContentValues values = new ContentValues();
values.put(StructuredName.DISPLAY_NAME, "Rose");
this.getBaseContext()
.getContentResolver()
.update(Data.CONTENT_URI, values,
StructuredName.DISPLAY_NAME + "=?",
new String[] { "Tom" });
}
private void deleteContact() {
// TODO Auto-generated method stub
String where = RawContacts.CONTACT_ID + " = ? ";
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
for (int i = 0; i < adapter.state.size(); i++) {
log("delete" + adapter.state.get(i));
ops.add(ContentProviderOperation
.newDelete(RawContacts.CONTENT_URI)
.withSelection(where,
new String[] { adapter.state.get(i).toString() })
.build());
}
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
// 清空state中的ID
adapter.state.clear();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO Auto-generated method stub
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri;
// if (mCurFilter != null) {
// baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
// Uri.encode(mCurFilter));
// } else {
baseUri = Contacts.CONTENT_URI;
// }
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
+ Contacts.HAS_PHONE_NUMBER + "=1) AND ("
+ Contacts.DISPLAY_NAME + " != '' ))";
// 根据本地的语言特征对字符串进行升序排序,意思是说对联系人名称进行升序排序
String orderString = Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
return new CursorLoader(this, baseUri, CONTACTS_SUMMARY_PROJECTION,
select, null, orderString);
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
// TODO Auto-generated method stub
adapter.swapCursor(arg1);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
// TODO Auto-generated method stub
adapter.swapCursor(null);
}
private void log(String msg) {
Log.d(TAG, msg);
}
}