package com.android.contacts;
import com.android.contacts.ContactsLiveFolders.StarredContacts;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Color;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.Toast;
/**
* This activity can show, edit and set group info
*/
public class ContactsGroupActivity extends ListActivity implements OnCreateContextMenuListener{
private boolean isEnableDeleteGroup = false;
private static final int SYSTEM_GROUP_COUNT = 4;
static final Uri DIVIDED_GROUP_URI=Uri.parse("content://"+ContactsContract.AUTHORITY+"/divided_group");
private static final String TAG = "ContactsGroupActivity";
private static final int ADD = 1;
private static final int DELETE = 2;
SimpleCursorAdapter cursorAdapter;
int mCurrentRecordCount = 0;
private Cursor mCursor = null;
private static final int GROUP_NAME_STUDENT = 0;
private static final int GROUP_NAME_FRIEND = 1;
private static final int GROUP_NAME_FAMILY = 2;
private static final int GROUP_NAME_COLLEAGUE = 3;
// the item for edit group info menu
private static final int MENU_ITEM_EDIT_GROUP = 1;
private static final int MENU_ITEM_BULK_SMS = 2;
private static final int MENU_ITEM_BULK_EMAIL = 3;
private final static int MODE_BULK_SMS = 0;
private final static int MODE_BULK_MAIL = 1;
private static final int MODE_PICK = 0;
private static final int GROUP_PHONE = 1;
private static final int MODE_BATH_EMAIL_CONTACTS_PICK = 12;
// the flag of system group like student, friend...
private boolean isSystemGroup = false;
// the flag of has show ringtone pick activity
private boolean isRingtonePickShowing = false;
// show ringtone info title
private TextView mGroupRingtoneTitle;
/** the launch code when picking a ringtone */
private static final int RINGTONE_PICKED = 3023;
/**
* uri for a custom ringtone associated with the contact. If null or
* missing,the default ringtone will be used.
*/
private String mGroupRingtoneUri;
/** this key for raw_contacts table */
private final static String CUSTOM_GROUP_RINGTONE = "custom_group_ringtone";
private final static String DIVIDED_NAME = "divided_name";
private final static String DIVIDED_RINGTONE = "divided_ringtone";
/** project both RawContacts._ID and CUSTOM_GROUP_RINGTONE */
private final String[] mGroupRingtoneProject = new String[] {
RawContacts._ID, CUSTOM_GROUP_RINGTONE
};
/** the id of one group */
private int mGroupId = -1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "oncreate");
setTitle(R.string.group_manager); //yeezone:jinwei CR:00104343 2011-8-22
setContentView(R.layout.group_manage);
getListView().setOnCreateContextMenuListener(this);
this.getContentResolver().registerContentObserver(DIVIDED_GROUP_URI, true, observer);
fillData();
}
private ContentObserver observer = new ContentObserver(new Handler()) {
public void onChange(boolean selfChange) {
fillData();
};
};
private void fillData(){
Log.v(TAG, "fillData()");
if(mCursor != null){
mCursor.close();
mCursor = null;
}
mCursor = this.getContentResolver().query(DIVIDED_GROUP_URI,
null, null, null, null);
Log.i(TAG, "cursor.getCount" + mCursor.getCount());
String displayGroupName = "";
while(mCursor.moveToNext()){
int groupNameId = mCursor.getInt(mCursor.getColumnIndexOrThrow(BaseColumns._ID));
Log.i(TAG, "groupNameId = " + groupNameId);
String groupName = mCursor.getString(mCursor.getColumnIndexOrThrow("divided_name"));
ContentValues values = new ContentValues();
switch(groupNameId){
case GROUP_NAME_STUDENT:
displayGroupName = getString(R.string.group_name_student);
values.put("divided_name", displayGroupName);
break;
case GROUP_NAME_FRIEND:
displayGroupName = getString(R.string.group_name_friend);
values.put("divided_name", displayGroupName);
break;
case GROUP_NAME_FAMILY:
displayGroupName = getString(R.string.group_name_family);
values.put("divided_name", displayGroupName);
break;
case GROUP_NAME_COLLEAGUE:
displayGroupName = getString(R.string.group_name_colleague);
values.put("divided_name", displayGroupName);
break;
default:
displayGroupName = groupName;
break;
}
if(!displayGroupName.equals(groupName)){
this.getContentResolver().update(DIVIDED_GROUP_URI, values, "_id=" + groupNameId, null);
}
}
//startManagingCursor(cursor);
mCurrentRecordCount = mCursor.getCount();
cursorAdapter = new SimpleCursorAdapter(this, R.layout.group_manage_item,
mCursor, new String[]{"divided_name"}, new int[]{R.id.group_item});
setListAdapter(cursorAdapter);
Log.i(TAG, "groupCursor.getCount() = " + mCursor.getCount());
isSystemGroupEnabled();
}
@Override
protected void onResume() {
super.onResume();
isRingtonePickShowing = false;
isSystemGroupEnabled();
}
@Override
protected void onDestroy() {
super.onDestroy();
this.getContentResolver().unregisterContentObserver(observer);
if(mCursor != null){
mCursor.close();
mCursor = null;
}
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Cursor cursor = (Cursor) l.getItemAtPosition(position);
int groupNameId = cursor.getInt(cursor.getColumnIndexOrThrow(BaseColumns._ID));
String groupName = cursor.getString(cursor.getColumnIndexOrThrow(DIVIDED_NAME));
String groupRingtone = cursor.getString(cursor.getColumnIndexOrThrow(DIVIDED_RINGTONE));
Log.v(TAG, "groupNameId: " + groupNameId + ", " + "groupName: " + groupName
+ ", groupRingtone: " + groupRingtone);
Intent intent = new Intent(this,ContactsListActivity.class);
intent.putExtra("mContactsGroupNameId", groupNameId);
intent.putExtra("mContactsGroupName", groupName);
intent.putExtra("mContactsGroupRingtone", groupRingtone);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, ADD, 1, R.string.add_group);
menu.add(0, DELETE, 2, R.string.delete_group);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.findItem(DELETE).setEnabled(isEnableDeleteGroup);
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case ADD:
editContactsGroup(false, null);
break;
case DELETE:
if(mCurrentRecordCount > 0){
deleteContactsGroupName();
}else{
Toast.makeText(this, R.string.noGroupInfo, Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
private void deleteContactsGroupName() {
startActivity(new Intent(this, DeleteContactsGroupNameActivity.class));
}
/**
* pick a ringtone for group
*/
private void pickGroupRingtone() {
if (isRingtonePickShowing) {
Log.d(TAG, "ringtone pick has show");
return;
}
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
// Allow user to pick 'Default'
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
// Show only ringtones
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
// Don't show 'Silent'
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
Uri ringtoneUri;
if (mGroupRingtoneUri != null) {
ringtoneUri = Uri.parse(mGroupRingtoneUri);
} else {
// Otherwise pick default ringtone Uri so that something is
ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
}
// Put checkmark next to the current ringtone for this contact
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, ringtoneUri);
// Launch!
startActivityForResult(intent, RINGTONE_PICKED);
isRingtonePickShowing = true;
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}
switch (requestCode) {
case RINGTONE_PICKED: {
Uri pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (pickedUri == null || RingtoneManager.isDefault(pickedUri)) {
mGroupRingtoneUri = null;
} else {
mGroupRingtoneUri = pickedUri.toString();
}
isRingtonePickShowing = false;
// update UI about ringtone view
updateGroupRingtoneView();
break;
}
}
}
/**
* update group edit view when ringtone has changed
*/
private void updateGroupRingtoneView() {
if (mGroupRingtoneUri == null || mGroupRingtoneUri.trim().length() <= 0) {
mGroupRingtoneTitle.setText(getString(R.string.default_ringtone));
} else {
Uri ringtoneUri = Uri.parse(mGroupRingtoneUri);
Ringtone ringtone = RingtoneManager.getRingtone(this, ringtoneUri);
if (ringtone == null) {
Log.w(TAG, "ringtone's URI doesn't resolve to a Ringtone");
return;
}
mGroupRingtoneTitle.setText(ringtone.getTitle(this));
}
}
/**
* update group ringtone for raw_contacts
*/
private void updateGroupRingtone() {
String selection = null;
if (mGroupId != -1) {
selection = "divided_group_name_id=" + mGroupId;
// reset mGroupId
mGroupId = -1;
}
if (null != selection) {
Cursor cursor = getContentResolver().query(RawContacts.CONTENT_URI,
mGroupRingtoneProject, selection, null, null);
try {
while (cursor.moveToNext()) {
String currentUri = cursor.getString(1);// only have
// CUSTOM_GROUP_RINGTONE
if (TextUtils.equals(currentUri, mGroupRingtoneUri)) {
continue;
} else {
long id = cursor.getLong(0);
currentUri = mGroupRingtoneUri;
ContentValues values = new ContentValues(2);
values.put(CUSTOM_GROUP_RINGTONE, currentUri);
final String where = RawContacts._ID + "=" + id;
getContentResolver().update(RawContacts.CONTENT_URI, values, where,
null);
}
}
} catch (Exception e) {
final String msg = e.getMessage();
if (null != msg) {
Log.e(TAG, msg);
} else {
e.printStackTrace();
}
} finally {
if (null != cursor) {
cursor.close();
}
}
}
}
private String queryGroupRingtoneUriByGroupName(String name) {
String[] projects = new String[] {BaseColumns._ID, DIVIDED_RINGTONE};
String selection = DIVIDED_NAME + "=?";
String[] selectionArgs = new String[] {name};
Cursor cursor = getContentResolver().query(DIVIDED_GROUP_URI, projects, selection, selectionArgs, null);
String ringtoneUri = null;
try {
if (null != cursor && cursor.moveToFirst()) {
mGroupId = cursor.getInt(0);
ringtoneUri = cursor.getString(1);
}
} catch (Exception e) {
final String msg = e.getMessage();
if (null != msg) {
Log.e(TAG, msg);
} else {
e.printStackTrace();
}
} finally {
if (null != cursor) {
cursor.close();
}
}
return ringtoneUri;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return;
}
Log.d(TAG, "info.position ======= " + info.position);
menu.add(0, MENU_ITEM_EDIT_GROUP, 1, R.string.edit_group_info);
menu.add(0, MENU_ITEM_BULK_SMS, 1, R.string.bulk_sms);
menu.add(0, MENU_ITEM_BULK_EMAIL, 1, R.string.bulk_email);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
int id = item.getItemId();
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
Log.e(TAG, "bad menuInfo", e);
return false;
}
Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
final String groupName = cursor.getString(cursor
.getColumnIndexOrThrow(DIVIDED_NAME));
final int groupNameId =
cursor.getInt(cursor.getColumnIndexOrThrow(BaseColumns._ID));
switch (id) {
case MENU_ITEM_EDIT_GROUP:
if (info.position == GROUP_NAME_STUDENT || info.position == GROUP_NAME_FRIEND
|| info.position == GROUP_NAME_FAMILY
|| info.position == GROUP_NAME_COLLEAGUE) {
isSystemGroup = true;
}
editContactsGroup(true, groupName);
break;
case MENU_ITEM_BULK_SMS:
startBulkIntent(groupNameId, MODE_BULK_SMS);
break;
case MENU_ITEM_BULK_EMAIL:
startBulkIntent(groupNameId, MODE_BULK_MAIL);
break;
default:
break;
}
return super.onContextItemSelected(item);
}
private void startBulkIntent(final int groupNameId, final int bulkAction) {
Intent intent = new Intent("com.android.contacts.MULTIOPERATELIST");
if (groupNameId != -1) {
intent.putExtra("groupNameId", groupNameId);
}
intent.putExtra("group", MODE_PICK);
intent.putExtra("bulkaction", bulkAction);
startActivity(intent);
}
/**
* save group with edit status and oldName
* @param isEdit
* @param oldName
*/
private void editContactsGroup(final boolean isEdit, final String oldName) {
int dialogTitleRes = isEdit ? R.string.edit_group_info : R.string.group_new;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(dialogTitleRes);
LayoutInflater li = LayoutInflater.from(this);
final View view = li.inflate(R.layout.promt, null);
// add code for group ringtone
View ringtoneLayout = view.findViewById(R.id.ringtone);
final EditText groupNameEditText = (EditText) view.findViewById(R.id.group_name);
groupNameEditText.setEnabled(true);
TextView label = (TextView) ringtoneLayout.findViewById(R.id.label);
label.setText(getString(R.string.label_ringtone));
mGroupRingtoneTitle = (TextView) ringtoneLayout.findViewById(R.id.data);
if (isEdit) {
groupNameEditText.setText(oldName);
if (isSystemGroup) {
groupNameEditText.setEnabled(false);
isSystemGroup = false;
}
mGroupRingtoneUri = queryGroupRingtoneUriByGroupName(oldName);
} else {
mGroupRingtoneUri = null;
}
updateGroupRingtoneView();
ringtoneLayout.setFocusable(true);
ringtoneLayout.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
pickGroupRingtone();
}
});
builder.setView(view);
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (DialogInterface.BUTTON1 == which) {
// check groupName is empty or not
String groupName = groupNameEditText.getText().toString();
if (null != groupName) {
groupName = groupName.trim();
}
if (TextUtils.isEmpty(groupName)) {
Toast.makeText(ContactsGroupActivity.this,
getString(R.string.group_name_cannot_empty), Toast.LENGTH_SHORT)
.show();
return;
}
// check repeat name
ContentValues values = new ContentValues();
ContentResolver contentResolver = ContactsGroupActivity.this
.getContentResolver();
boolean isRepeat = false;
boolean isNeedCheck = true;
if (isEdit) {
if (oldName.equals(groupName)) {
isNeedCheck = false;
}
}
if (isNeedCheck) {
Cursor cursor = contentResolver.query(DIVIDED_GROUP_URI, null,
" divided_name=?", new String[] {
groupName
}, null);
if (null != cursor /* && cursor.moveToNext() */) {
if (cursor.getCount() > 0) {
isRepeat = true;
}
cursor.close();
}
}
if (isRepeat) {
new AlertDialog.Builder(ContactsGroupActivity.this)
.setTitle(R.string.contacts_group)
.setMessage(R.string.contacts_group_name_exist)
.setPositiveButton(R.string.sure, null).show();
} else {
values.put(DIVIDED_NAME, groupName);
values.put(DIVIDED_RINGTONE, mGroupRingtoneUri);
if (isEdit) {
// update table divided group
contentResolver = ContactsGroupActivity.this.getContentResolver();
int id = contentResolver.update(DIVIDED_GROUP_URI, values,
" divided_name=?", new String[] {
oldName
});
fillData();
// update table row contacts
updateGroupRingtone();
} else {
contentResolver.insert(DIVIDED_GROUP_URI, values);
}
}
}
}
};
builder.setPositiveButton(R.string.save, listener);
builder.setNegativeButton(R.string.cancel, listener);
AlertDialog dialog = builder.create();
dialog.show();
dialog.show();
}
private void isSystemGroupEnabled() {
if(null != mCursor && mCursor.getCount() > SYSTEM_GROUP_COUNT){
isEnableDeleteGroup = true;
}else{
isEnableDeleteGroup = false;
}
}
}