package org.texteasy;
import java.util.ArrayList;
import java.util.HashSet;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Contacts.Groups;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;
public class BulkMessenger extends ListActivity implements DialogInterface.OnClickListener{
private static final String TAG = "BulkMessenger";
private final static int NEW_MESSAGE_ID = Menu.FIRST;
private final static int DISPLAY_GROUP_ID = Menu.FIRST + 1;
private final static int SELECT_ALL_ID = Menu.FIRST + 2;
private final static int UNSELECT_ALL_ID = Menu.FIRST + 3;
private final static int EDIT_SETTINGS = Menu.FIRST + 4;
//private String[] projection = new String[] {People._ID,People.NAME, People.TYPE, People.NUMBER};
private String[] groupsProjection = new String[]{Groups._ID, Groups.SYSTEM_ID, Groups.NAME};
//private Uri contacts = People.CONTENT_URI;
private HashSet<String> selectedIds = new HashSet<String>();
private long selectedGroupId = -1;
private static final String SELECTED_GROUP_ID_PREFERENCE = "SelectedGroupId";
private int selectedGroupIndex;
private ArrayList<Long> displayGroupIds;
private TextEasyDBAdapter dbAdaptor;
private AlertDialog groupDialog;
static final int ID_COLUMN_INDEX = 1;
static final int NAME_COLUMN_INDEX = 2;
static final int TYPE_COLUMN_INDEX = 3;
static final int NUMBER_COLUMN_INDEX = 4;
public static final int GROUPS_COLUMN_INDEX_ID = 0;
public static final int GROUPS_COLUMN_INDEX_SYSTEM_ID = 1;
public static final int GROUPS_COLUMN_INDEX_NAME = 2;
public static final int GROUPS_COLUMN_GROUP_VISIBLE = 3;
private static final int DISPLAY_GROUPS_ALL_CONTACTS = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.dbAdaptor = new TextEasyDBAdapter(this);
this.dbAdaptor.open();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
selectedGroupId = prefs.getLong(SELECTED_GROUP_ID_PREFERENCE, -1);
boolean storeSelections = prefs.getBoolean(getString(R.string.REMEMBER_SELECTIONS), false);
if(!storeSelections){
if(getLastNonConfigurationInstance() != null){
this.selectedIds = (HashSet<String>)getLastNonConfigurationInstance();
}
}
ListView listView = getListView();
listView.setItemsCanFocus(false);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setTextFilterEnabled(true);
queryContacts();
}
/**
* Utility method for displaying querying contacts and displaying them
* @param nameClause
*/
private void queryContacts(){
Cursor managedCursor = ContactsAccessor.getInstance().queryContacts(getContentResolver(),
null, selectedGroupId);
ResourceCursorAdapter contactsAdaptor = new ContactItemListAdapter(this,
R.layout.contacts_row,managedCursor);
setListAdapter(contactsAdaptor);
}
@Override
protected void onPause() {
super.onPause();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean storeSelections = prefs.getBoolean(getString(R.string.REMEMBER_SELECTIONS), false);
if(storeSelections){
HashSet<String> selectedIds = this.selectedIds;
if(selectedIds != null && !selectedIds.isEmpty()){
this.dbAdaptor.persistSelectedIds(selectedIds);
}
}
this.dbAdaptor.close();
if(groupDialog != null && groupDialog.isShowing()){
groupDialog.dismiss();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(this.dbAdaptor.isOpen()){
this.dbAdaptor.close();
}
}
@Override
protected void onResume() {
super.onResume();
this.dbAdaptor.open();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean storeSelections = prefs.getBoolean(getString(R.string.REMEMBER_SELECTIONS), false);
if(storeSelections){
this.selectedIds = this.dbAdaptor.getSelectedIdsAndClear();
}
}
@Override
public Object onRetainNonConfigurationInstance() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean storeSelections = prefs.getBoolean(getString(R.string.REMEMBER_SELECTIONS), false);
if(!storeSelections){
return this.selectedIds;
}else{
return null;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, NEW_MESSAGE_ID, 0, R.string.NEW_MESSAGE);
menu.add(Menu.NONE, DISPLAY_GROUP_ID, 1, R.string.DISPLAY_GROUPS);
menu.add(Menu.NONE, SELECT_ALL_ID, 2, R.string.SELECT_ALL);
menu.add(Menu.NONE, UNSELECT_ALL_ID, 3, R.string.UNSELECT_ALL);
menu.add(Menu.NONE, EDIT_SETTINGS, 3, R.string.SETTINGS);
return true;
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Cursor cursor = (Cursor)getListView().getItemAtPosition(position);
long contactId = cursor.getLong(ID_COLUMN_INDEX);
int phoneType = -1;
if (!cursor.isNull(TYPE_COLUMN_INDEX)) {
phoneType = cursor.getInt(TYPE_COLUMN_INDEX);
}
String clickedContact = contactId + "|" + phoneType;
HashSet<String> selectedIds = this.selectedIds;
if(selectedIds.contains(clickedContact)){
selectedIds.remove(clickedContact);
}else{
selectedIds.add(clickedContact);
}
}
Cursor doFilter(String filter) {
final ContentResolver resolver = getContentResolver();
return ContactsAccessor.getInstance().queryContacts(resolver, filter,selectedGroupId);
}
public void onClick(DialogInterface dialogInterface, int which){
if (which == DialogInterface.BUTTON1) {
if(selectedGroupIndex == DISPLAY_GROUPS_ALL_CONTACTS){
selectedGroupId = -1l;
}else{
selectedGroupId = this.displayGroupIds.get(selectedGroupIndex);
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.edit().putLong(SELECTED_GROUP_ID_PREFERENCE, selectedGroupId).commit();
this.selectedIds = new HashSet<String>();
getListView().setFilterText("A");
getListView().clearTextFilter();
}else{
//user just selected an option
selectedGroupIndex = which;
}
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case NEW_MESSAGE_ID:
createNewMessage();
break;
case DISPLAY_GROUP_ID:
createGroupAlertDialog();
break;
case SELECT_ALL_ID:
selectAll();
break;
case EDIT_SETTINGS:
startActivity(new Intent(this, TextEasyPreferences.class));
return(true);
case UNSELECT_ALL_ID:
this.selectedIds = new HashSet<String>();
getListView().setFilterText("A");
getListView().clearTextFilter();
break;
}
return super.onMenuItemSelected(featureId, item);
}
private void selectAll(){
//Log.e(TAG, "selectAll start");
Cursor managedCursor = ContactsAccessor.getInstance().queryContacts(getContentResolver(),
null,selectedGroupId);
//Log.e(TAG, "selectAll after query");
HashSet<String> selectedIds = this.selectedIds;
while(managedCursor.moveToNext()){
Long id = managedCursor.getLong(ID_COLUMN_INDEX);
Integer type = managedCursor.getInt(TYPE_COLUMN_INDEX);
//if(!selectedIds.contains(id)){
selectedIds.add(id + "|" + type);
//}
}
//Log.e(TAG, "selectAll after selection");
getListView().setFilterText("A");
getListView().clearTextFilter();
//Log.e(TAG, "after textFilter update");
}
/*private void createSignatureDialog(){
LayoutInflater factory = LayoutInflater.from(this);
final View textEntryView = factory.inflate(R.layout.signature_dialog_entry, null);
signatureDialog = new AlertDialog.Builder(this)
.setTitle(R.string.ADD_SIGNATURE_TITLE)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, null).
setView(textEntryView).create();
signatureDialog.show();
}*/
private void createGroupAlertDialog(){
if(ContactsAccessor.isEclairOrAbove()){
startActivity(new Intent(this, DisplayGroupsActivity.class));
}else{
Cursor cursor = ContactsAccessor.getInstance().queryGroups(getContentResolver());
ArrayList<CharSequence> groups = new ArrayList<CharSequence>();
ArrayList<Long> groupIds = new ArrayList<Long>();
groups.add(DISPLAY_GROUPS_ALL_CONTACTS,getString(R.string.ALL_CONTACTS_WITH_PHONES));
groupIds.add(DISPLAY_GROUPS_ALL_CONTACTS,-1l);
int selectedIndex = 0;
int i=1;
while(cursor.moveToNext()){
String systemId = cursor.getString(GROUPS_COLUMN_INDEX_SYSTEM_ID);
String name = cursor.getString(GROUPS_COLUMN_INDEX_NAME);
Long groupId = cursor.getLong(GROUPS_COLUMN_INDEX_ID);
//Log.e("BulkMessenger", "groupId: " + groupId + " selectedGroupId: " + selectedGroupId);
if (cursor.isNull(GROUPS_COLUMN_INDEX_SYSTEM_ID) &&
!Groups.GROUP_MY_CONTACTS.equals(systemId)) {
groups.add(name);
}else{
//found the "My Contacts" this displays weird (System Group: My Contacts)
//so gave it a different name
groups.add(getString(R.string.GROUP_NAME_MY_CONTACTS));
}
groupIds.add(groupId);
if(selectedGroupId == groupId){
selectedIndex = i;
}
i++;
}
this.displayGroupIds = groupIds;
CharSequence[] displayGroups = groups.toArray(new CharSequence[groups.size()]);
//Log.e("blah", selectedIndex + "");
groupDialog = new AlertDialog.Builder(this)
.setTitle(R.string.SELECT_GROUP_TITLE)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, null).
setSingleChoiceItems(displayGroups,
selectedIndex, this).create();
groupDialog.show();
}
}
private void createNewMessage(){
//Log.e(TAG, "start createNewMessage");
HashSet<String> selectedIds = this.selectedIds;
boolean contactSelected = false;
if(!selectedIds.isEmpty()){
contactSelected = true;
}
if(contactSelected){
HashSet<Long> onlyIds = new HashSet<Long>();
for(String selectedId: selectedIds){
String[] tokens = selectedId.split("\\|");
onlyIds.add(new Long(tokens[0]));
}
Cursor managedCursor = ContactsAccessor.getInstance().queryContactsForPhoneNumbers(
getContentResolver(), onlyIds);
//Log.e(TAG, "before iterating createNewMessage");
StringBuffer buffer = new StringBuffer();
if(managedCursor != null){
while(managedCursor.moveToNext()){
Long contactId = managedCursor.getLong(0);
Integer phoneType = managedCursor.getInt(2);
if(selectedIds.contains(contactId + "|" + phoneType)){
buffer.append(managedCursor.getString(
managedCursor.getColumnIndexOrThrow(
ContactsAccessor.getInstance().getPhoneColumnIndex()))).
append(";");
}
}
}
//Log.e(TAG, "after query createNewMessage");
String numbers = buffer.substring(0, buffer.length() - 1);
Intent i = new Intent();
i.setAction(Intent.ACTION_VIEW);
i.setType("vnd.android-dir/mms-sms");
i.putExtra("address", numbers);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String signature = prefs.getString(getString(R.string.ADD_SIGNATURE_TITLE), "");
if(signature != null && !signature.equals("")){
i.putExtra("sms_body", "\n" + signature);
}
//Log.e(TAG, "starting mms activity");
startActivity(i);
}
}
final static class ContactListItemCache {
public TextView nameView;
public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
public TextView labelView;
public CharArrayBuffer labelBuffer = new CharArrayBuffer(128);
public TextView numberView;
public CharArrayBuffer numberBuffer = new CharArrayBuffer(128);
public CheckBox checkBox;
public boolean checked;
}
private final class ContactItemListAdapter extends ResourceCursorAdapter{
private CharSequence[] mLocalizedLabels;
private CharSequence mUnknownNameText;
public ContactItemListAdapter(Context context, int resource, Cursor cursor){
super(context, resource, cursor);
final Resources resources = context.getResources();
mLocalizedLabels = resources.getStringArray(android.R.array.phoneTypes);
mUnknownNameText = context.getText(android.R.string.unknownName);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final View view = super.newView(context, cursor, parent);
final ContactListItemCache cache = new ContactListItemCache();
cache.nameView = (TextView) view.findViewById(R.id.name);
cache.labelView = (TextView) view.findViewById(R.id.label);
cache.labelView.setCompoundDrawablePadding(3);
cache.numberView = (TextView) view.findViewById(R.id.number);
cache.checkBox = (CheckBox)view.findViewById(R.id.selected);
view.setTag(cache);
return view;
}
@Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
return doFilter(constraint.toString());
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ContactListItemCache cache = (ContactListItemCache) view.getTag();
// Set the name
cursor.copyStringToBuffer(NAME_COLUMN_INDEX, cache.nameBuffer);
int size = cache.nameBuffer.sizeCopied;
if (size != 0) {
cache.nameView.setText(cache.nameBuffer.data, 0, size);
} else {
cache.nameView.setText(mUnknownNameText);
}
long contactId = cursor.getLong(ID_COLUMN_INDEX);
//Set the phone number
TextView numberView = cache.numberView;
ContactsAccessor.getInstance().setPhoneDetails(context.getContentResolver(),
cursor, cache.numberBuffer, contactId);
size = cache.numberBuffer.sizeCopied;
if (size != 0) {
numberView.setText(cache.numberBuffer.data, 0, size);
numberView.setVisibility(View.VISIBLE);
} else {
numberView.setVisibility(View.GONE);
}
// Set the label
int type = -1;
TextView labelView = cache.labelView;
if (!cursor.isNull(TYPE_COLUMN_INDEX)) {
type = cursor.getInt(TYPE_COLUMN_INDEX);
if (type != android.provider.ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM) {
try {
labelView.setText(mLocalizedLabels[type - 1]);
} catch (ArrayIndexOutOfBoundsException e) {
labelView.setText(mLocalizedLabels[android.provider.ContactsContract.CommonDataKinds.Phone.TYPE_HOME - 1]);
}
} else {
// Set the text to a length of 0
labelView.setText(cache.labelBuffer.data, 0, 0);
}
} else {
// Set the text to a length of 0
labelView.setText(cache.labelBuffer.data, 0, 0);
}
if(selectedIds.contains(contactId + "|" + type)){
cache.checkBox.setChecked(true);
}else{
cache.checkBox.setChecked(false);
}
}
}
}
|