diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..609aa00 --- /dev/null +++ b/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..1869c40 --- /dev/null +++ b/.project @@ -0,0 +1,33 @@ + + + MultiSmsSender + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..f10cd78 --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/default.properties b/default.properties new file mode 100644 index 0000000..4513a1e --- /dev/null +++ b/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-3 diff --git a/res/drawable/ic_launcher_contacts.png b/res/drawable/ic_launcher_contacts.png new file mode 100644 index 0000000..826656f Binary files /dev/null and b/res/drawable/ic_launcher_contacts.png differ diff --git a/res/drawable/multisms.png b/res/drawable/multisms.png new file mode 100644 index 0000000..13eab04 Binary files /dev/null and b/res/drawable/multisms.png differ diff --git a/res/layout/edit_group_list.xml b/res/layout/edit_group_list.xml new file mode 100644 index 0000000..ecdccd4 --- /dev/null +++ b/res/layout/edit_group_list.xml @@ -0,0 +1,16 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/layout/group_list.xml b/res/layout/group_list.xml new file mode 100644 index 0000000..98add62 --- /dev/null +++ b/res/layout/group_list.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/res/layout/group_row.xml b/res/layout/group_row.xml new file mode 100644 index 0000000..3dae5da --- /dev/null +++ b/res/layout/group_row.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/res/layout/main.xml b/res/layout/main.xml new file mode 100644 index 0000000..f18ffaf --- /dev/null +++ b/res/layout/main.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + diff --git a/res/layout/number_list.xml b/res/layout/number_list.xml new file mode 100644 index 0000000..c508f4d --- /dev/null +++ b/res/layout/number_list.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/res/layout/number_row.xml b/res/layout/number_row.xml new file mode 100644 index 0000000..05831b5 --- /dev/null +++ b/res/layout/number_row.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/res/values-en/strings.xml b/res/values-en/strings.xml new file mode 100644 index 0000000..d8515d3 --- /dev/null +++ b/res/values-en/strings.xml @@ -0,0 +1,24 @@ + + + Multi Sms + Send + Add + Contacts + Ok + No Contacts!! + No Groups!! + Sending message... + Please wait while sending... + Enter your message + Enter Group Name + To + Add from group + Create a new group + Remove this group + Edit this group + no Name + Select all + Deselect all + Message(s) sent + Enter a phone number or use the contact icon + diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml new file mode 100644 index 0000000..235ae42 --- /dev/null +++ b/res/values-fr/strings.xml @@ -0,0 +1,24 @@ + + + Multi Sms + Envoyer + Ajouter + Contacts + Ok + Pas de contacts!! + Pas de groupes!! + Envoie d'un message... + Veuillez patienter pendant l'envoie... + Saisissez votre message + Nom du groupe + À + Ajouter un groupe + Créer un group + Supprimer ce groupe + Editer ce groupe + noName + Selectionner tout + DeSelectionner tout + Message(s) envoyé(s) + Entrez un numero ou utilisez l'icone de contact + diff --git a/src/com/openwide/android/ContactRow.java b/src/com/openwide/android/ContactRow.java new file mode 100644 index 0000000..34e9696 --- /dev/null +++ b/src/com/openwide/android/ContactRow.java @@ -0,0 +1,61 @@ +package com.openwide.android; + +import android.content.Context; +import android.widget.CheckBox; +import android.widget.LinearLayout; +import android.widget.TextView; + +public class ContactRow extends LinearLayout { + + CheckBox mSelectedCheckBox; + TextView mNameTextView; + TextView mNumberView; + LinearLayout mInfoLayout; + Long mId; + + public ContactRow(Context context) { + super(context); + + mSelectedCheckBox = new CheckBox(context); + mInfoLayout = new LinearLayout(context); + + mNameTextView = new TextView(context); + mNumberView = new TextView(context); + + mNameTextView.setTextSize(30,0); + mNumberView.setTextSize(18,0); + + + mSelectedCheckBox.setText(""); + + + this.addView(mSelectedCheckBox, new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.FILL_PARENT)); + mInfoLayout.setOrientation(LinearLayout.VERTICAL); + mInfoLayout.addView(mNameTextView, new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.WRAP_CONTENT)); + mInfoLayout.addView(mNumberView, new LayoutParams(LayoutParams.FILL_PARENT, + LayoutParams.WRAP_CONTENT)); + + this.addView(mInfoLayout, new LayoutParams(LayoutParams.WRAP_CONTENT, + LayoutParams.FILL_PARENT)); + + + + + } + + + public void display(String name, String number, boolean isSelected) { + mNameTextView.setText(name); + mNumberView.setText(number); + mSelectedCheckBox.setChecked(isSelected); + } + + public void display(String name, String number, boolean isSelected, long id) { + display( name, number, isSelected); + mId = id; + } + + +} diff --git a/src/com/openwide/android/GroupEditActivity.java b/src/com/openwide/android/GroupEditActivity.java new file mode 100644 index 0000000..2a39b7b --- /dev/null +++ b/src/com/openwide/android/GroupEditActivity.java @@ -0,0 +1,168 @@ +package com.openwide.android; + +import java.util.HashSet; + +import android.app.ListActivity; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.provider.Contacts.Phones; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.SimpleCursorAdapter; + +public class GroupEditActivity extends ListActivity { + + GroupDataListAdapter mAdpater; + GroupsDbAdapter mDb; + EditText mGroupNameText; + Long mGid; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.edit_group_list); + mGroupNameText = (EditText) findViewById(R.id.groupName); + + Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, Phones.NAME); + startManagingCursor(c); + + String[] mSelected = {}; + + mDb = new GroupsDbAdapter(this); + mDb.open(); + + Long groupId; + Bundle extras = getIntent().getExtras(); + groupId = extras != null ? extras.getLong(SelectGroupActivity.PARAM_GROUP_ID): null; + + if (groupId != null) { + Cursor groupNameCursor = mDb.fetchGroup(groupId); + String groupName = groupNameCursor.getString(groupNameCursor.getColumnIndex(GroupsDbAdapter.KEY_GROUP_NAME)); + mGroupNameText.setText(groupName); + Cursor numbers = mDb.fetchPhonesFromGroup(groupId); + numbers.moveToFirst(); + int phoneNumIdx = numbers.getColumnIndex(Phones.NUMBER); + mSelected = new String[numbers.getCount()]; + for(int i = 0; i < numbers.getCount(); i++) { + mSelected[i] = numbers.getString(phoneNumIdx); + numbers.moveToNext(); + } + + mGid = groupId; + } + + + mAdpater = new GroupDataListAdapter(this, R.layout.number_row, c, new String[] { + Phones.NAME, Phones.NUMBER + }, new int[] {R.id.name, R.id.phone}, mSelected); + setListAdapter(mAdpater); + + Button ok = (Button) findViewById(R.id.okGroups); + ok.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + createGroup(); + reNameGroup(); + Intent i = new Intent(); + setResult(RESULT_OK, i); + finish(); + + } + }); + } + + private void createGroup() { + if (mGid == null) { + String name = mGroupNameText.getText().toString(); + if(name.equals("")) { + name = getResources().getString(R.string.noName); + } + mGid = mDb.createGroup(name); + } + } + + private void reNameGroup() { + if (mGid != null) { + String name = mGroupNameText.getText().toString(); + if(name.equals("")) { + name = getResources().getString(R.string.noName); + } + mDb.updateGroup(mGid, name); + } + } + + public class GroupDataListAdapter extends SimpleCursorAdapter{ + + public HashSet selected; + int nameidx; + int numberidx; + int idIdx; + Context mContext; + + public GroupDataListAdapter(Context context, int layout, Cursor c, + String[] from, int[] to, String[] rawSelected) { + super(context, layout, c, from, to); + nameidx = c.getColumnIndex(Phones.NAME); + numberidx = c.getColumnIndex(Phones.NUMBER); + idIdx = c.getColumnIndex(Phones._ID); + mContext = context; + selected = new HashSet(); + for (int i = 0; i < rawSelected.length; i++) { + selected.add(rawSelected[i].trim()); + } + } + + public View getView(int position, View convertView, ViewGroup parent) { + Cursor c = getCursor(); + c.moveToPosition(position); + String name = c.getString(nameidx); + String number = c.getString(numberidx); + long id = c.getLong(idIdx); + ContactRow contact; + if (convertView == null) { + contact = new ContactRow(mContext); + }else { + contact = (ContactRow) convertView; + } + contact.display(name, number, selected.contains(number), id); + contact.mSelectedCheckBox.setOnClickListener(new addNumberToGroupClickListener(contact)); + + return contact; + } + + } + + private class addNumberToGroupClickListener implements OnClickListener{ + + ContactRow mContact; + + + public addNumberToGroupClickListener(ContactRow mContact) { + super(); + this.mContact = mContact; + } + + + @Override + public void onClick(View v) { + CheckBox cBox = (CheckBox)v; + createGroup(); + long phoneId = mContact.mId; + if(cBox.isChecked()) { + mDb.addPhoneToGroup(mGid, phoneId); + }else { + mDb.removePhoneToGroup(mGid, phoneId); + } + + } + + } + +} diff --git a/src/com/openwide/android/GroupsDbAdapter.java b/src/com/openwide/android/GroupsDbAdapter.java new file mode 100755 index 0000000..ba3bbab --- /dev/null +++ b/src/com/openwide/android/GroupsDbAdapter.java @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2008 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.openwide.android; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.provider.Contacts.Phones; +import android.util.Log; + +/** + * Simple groups database access helper class. Defines the basic CRUD operations + * for the grouppad example, and gives the ability to list all groups as well as + * retrieve or modify a specific group. + * + * This has been improved from the first version of this tutorial through the + * addition of better error handling and also using returning a Cursor instead + * of using a collection of inner classes (which is less scalable and not + * recommended). + */ +public class GroupsDbAdapter { + + + public static final String KEY_GROUP_NAME = "name"; + public static final String KEY_GROUP_ROWID = "_id"; + + public static final String KEY_GROUP_TO_PHONE_ROWID = "_id"; + public static final String KEY_GROUP_TO_PHONE_GROUPID = "gid"; + public static final String KEY_GROUP_TO_PHONE_PHONEID = "pid"; + + private static final String TAG = "groupsDbAdapter"; + private DatabaseHelper mDbHelper; + private SQLiteDatabase mDb; + + /** + * Database creation sql statement + */ + private static final String DATABASE_GROUP_CREATE = + "create table groups (_id integer primary key autoincrement, " + + "name text not null);"; + + private static final String DATABASE_GROUP_TO_PHONE_CREATE = + "create table group_TO_PHONE (_id integer primary key autoincrement, " + + "gid integer not null, pid integer not null);"; + + private static final String DATABASE_NAME = "data"; + private static final String DATABASE_GROUP_TABLE = "groups"; + private static final String DATABASE_GROUP_TO_PHONE_TABLE = "group_TO_PHONE"; + private static final int DATABASE_VERSION = 2; + + private final Context mCtx; + + private static class DatabaseHelper extends SQLiteOpenHelper { + + DatabaseHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + + db.execSQL(DATABASE_GROUP_CREATE); + db.execSQL(DATABASE_GROUP_TO_PHONE_CREATE); + } + + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + + newVersion + ", which will destroy all old data"); + db.execSQL("DROP TABLE IF EXISTS groups"); + db.execSQL("DROP TABLE IF EXISTS group_TO_PHONE"); + onCreate(db); + } + } + + /** + * Constructor - takes the context to allow the database to be + * opened/created + * + * @param ctx the Context within which to work + */ + public GroupsDbAdapter(Context ctx) { + this.mCtx = ctx; + } + + /** + * Open the groups database. If it cannot be opened, try to create a new + * instance of the database. If it cannot be created, throw an exception to + * signal the failure + * + * @return this (self reference, allowing this to be chained in an + * initialization call) + * @throws SQLException if the database could be neither opened or created + */ + public GroupsDbAdapter open() throws SQLException { + mDbHelper = new DatabaseHelper(mCtx); + mDb = mDbHelper.getWritableDatabase(); + return this; + } + + public void close() { + mDbHelper.close(); + } + + + /** + * Create a new group using the name provided. If the group is + * successfully created return the new rowId for that group, otherwise return + * a -1 to indicate failure. + * + * @param name the name of the group + */ + public long createGroup(String name) { + ContentValues initialValues = new ContentValues(); + initialValues.put(KEY_GROUP_NAME, name); + + return mDb.insert(DATABASE_GROUP_TABLE, null, initialValues); + } + + /** + * Delete the group with the given rowId + * + * @param rowId id of group to delete + * @return true if deleted, false otherwise + */ + public boolean deleteGroup(long rowId) { + + return mDb.delete(DATABASE_GROUP_TABLE, KEY_GROUP_ROWID + "=" + rowId, null) > 0 && mDb.delete(DATABASE_GROUP_TO_PHONE_TABLE, KEY_GROUP_TO_PHONE_GROUPID + "=" + rowId, null) > 0; + + } + + /** + * Return a Cursor over the list of all groups in the database + * + * @return Cursor over all groups + */ + public Cursor fetchAllGroups() { + + return mDb.query(DATABASE_GROUP_TABLE, new String[] {KEY_GROUP_ROWID, KEY_GROUP_NAME}, null, null, null, null, KEY_GROUP_NAME); + } + + /** + * Return a Cursor positioned at the group that matches the given rowId + * + * @param rowId id of group to retrieve + * @return Cursor positioned to matching group, if found + * @throws SQLException if group could not be found/retrieved + */ + public Cursor fetchGroup(long rowId) throws SQLException { + + Cursor mCursor = + + mDb.query(true, DATABASE_GROUP_TABLE, new String[] {KEY_GROUP_ROWID, KEY_GROUP_NAME}, KEY_GROUP_ROWID + "=" + rowId, null, + null, null, null, null); + if (mCursor != null) { + mCursor.moveToFirst(); + } + return mCursor; + + } + + /** + * @param rowId id of group to update + * @param name value to set group name to + */ + public boolean updateGroup(long rowId, String name) { + ContentValues args = new ContentValues(); + args.put(KEY_GROUP_NAME, name); + + return mDb.update(DATABASE_GROUP_TABLE, args, KEY_GROUP_ROWID + "=" + rowId, null) > 0; + } + + + public Cursor fetchPhonesFromGroup(long groupId) { + Cursor mCursor = mDb.query(true, DATABASE_GROUP_TO_PHONE_TABLE, new String[] {KEY_GROUP_TO_PHONE_PHONEID}, KEY_GROUP_TO_PHONE_GROUPID + "=" + groupId, null, null, null, null, null); + Cursor userCursor = null; + int phoneIdIdx = mCursor.getColumnIndex(KEY_GROUP_TO_PHONE_PHONEID); + if(mCursor != null) { + userCursor = mCtx.getContentResolver().query(Phones.CONTENT_URI, null, "Phones."+ Phones._ID +" IN "+ cursorToStringList(mCursor, phoneIdIdx), null, Phones.NAME); + } + return userCursor; + } + + public long addPhoneToGroup(long groupId, long phoneId ) { + ContentValues initialValues = new ContentValues(); + initialValues.put(KEY_GROUP_TO_PHONE_GROUPID, groupId); + initialValues.put(KEY_GROUP_TO_PHONE_PHONEID, phoneId); + + return mDb.insert(DATABASE_GROUP_TO_PHONE_TABLE, null, initialValues); + } + + public boolean removePhoneToGroup(long groupId, long phoneId) { + return mDb.delete(DATABASE_GROUP_TO_PHONE_TABLE, KEY_GROUP_TO_PHONE_GROUPID + "=" + groupId+ " AND "+ KEY_GROUP_TO_PHONE_PHONEID + "=" + phoneId, null) > 0; + } + + public String cursorToStringList(Cursor cursor, int columnIdx) { + cursor.moveToFirst(); + String list = "( "; + while(!cursor.isAfterLast()) { + list += cursor.getString(columnIdx); + if(!cursor.isLast()) { + list += " , "; + } + cursor.moveToNext(); + } + list +=" )"; + return list; + } +} diff --git a/src/com/openwide/android/MultiSmsSender.java b/src/com/openwide/android/MultiSmsSender.java new file mode 100644 index 0000000..72b8f8a --- /dev/null +++ b/src/com/openwide/android/MultiSmsSender.java @@ -0,0 +1,189 @@ +package com.openwide.android; + +import java.util.HashSet; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.telephony.gsm.SmsManager; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.inputmethod.EditorInfo; +import android.widget.Button; +import android.widget.TextView; + +public class MultiSmsSender extends Activity { + private Button mAddButton; + private Button mSend; + private TextView mContacts; + private TextView mEditor; + + private ProgressDialog mSendingDialog; + + public static final int ACTIVITY_EDIT = 0; + public static final int ACTIVITY_ADD_GROUP = 1; + private static final int SENDING_DIALOG_KEY = 0; + private static final int INSERT_ID = Menu.FIRST; + + public static final String PARAM_NUMBERS_LIST = "param number list"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + + mAddButton = (Button) findViewById(R.id.contacts); + mSend = (Button) findViewById(R.id.send); + mContacts = (TextView) findViewById(R.id.numbers); + mEditor = (TextView) findViewById(R.id.editor); + + mContacts.setImeOptions(EditorInfo.IME_ACTION_NEXT); + mEditor.setImeOptions(EditorInfo.IME_ACTION_DONE); + + mAddButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + selectNumbers(); + } + }); + + mSend.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + sendMessage(); + + } + }); + } + + public void selectNumbers() { + Intent i = new Intent(this, PhoneNumberSelection.class); + String rawNumbers = mContacts.getText().toString(); + String[] numbers = rawNumbers.split(","); + i.putExtra(PARAM_NUMBERS_LIST, numbers); + startActivityForResult(i, ACTIVITY_EDIT); + } + + public void sendMessage() { + SmsManager manager = SmsManager.getDefault(); + String message = mEditor.getText().toString(); + String[] numbers = mContacts.getText().toString().split(","); + HashSet allreadySend = new HashSet(); + int size = numbers.length; + showDialog(SENDING_DIALOG_KEY); + if(numbers.length != 0) { + for (int i = 0; i < numbers.length; i++) { + String newN = numbers[i].trim(); + mSendingDialog.setMax(size); + if (!newN.equals("")) { + mSendingDialog.setProgress(i / size); + if (!allreadySend.contains(newN)) { + allreadySend.add(newN); + manager.sendMultipartTextMessage(newN, null, manager.divideMessage(message), null, null); + + } + } + } + mSendingDialog.dismiss(); + new AlertDialog.Builder(this).setPositiveButton(getResources().getString(R.string.ok), + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + } + }).setMessage( getResources().getString(R.string.message_sent)).show(); + }else { + new AlertDialog.Builder(this).setPositiveButton(getResources().getString(R.string.ok), + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + + } + }).setMessage(getResources().getString(R.string.enter_number)).show(); + } + + } + + @Override + protected Dialog onCreateDialog(int id) { + switch (id) { + case SENDING_DIALOG_KEY: { + mSendingDialog = new ProgressDialog(this); + mSendingDialog.setTitle(R.string.sending); + mSendingDialog.setMessage(getResources().getString(R.string.wait)); + mSendingDialog.setIndeterminate(true); + mSendingDialog.setCancelable(true); + return mSendingDialog; + } + } + return null; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, + Intent intent) { + super.onActivityResult(requestCode, resultCode, intent); + if (intent != null) { + String[] numbers = intent.getExtras().getStringArray( + PARAM_NUMBERS_LIST); + String string = ""; + HashSet res = new HashSet(); + for (int i = 0; i < numbers.length; i++) { + String newN = numbers[i].trim(); + if (!newN.equals("")) { + res.add(newN); + } + } + String oldContactsString = mContacts.getText().toString(); + String[] oldContacts = oldContactsString.split(","); + for (int i = 0; i < oldContacts.length; i++) { + String newN = oldContacts[i].trim(); + if (!newN.equals("")) { + res.add(newN); + } + } + + for (String number : res) { + string += number + ", "; + } + + mContacts.setText(string); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(0, INSERT_ID,0, R.string.add_group); + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + switch(item.getItemId()) { + case INSERT_ID: + display_group_list(); + return true; + } + return super.onMenuItemSelected(featureId, item); + } + + + public void display_group_list(){ + + Intent i = new Intent(this, SelectGroupActivity.class); + startActivityForResult(i, ACTIVITY_ADD_GROUP); + } +} \ No newline at end of file diff --git a/src/com/openwide/android/PhoneNumberSelection.java b/src/com/openwide/android/PhoneNumberSelection.java new file mode 100644 index 0000000..2730b93 --- /dev/null +++ b/src/com/openwide/android/PhoneNumberSelection.java @@ -0,0 +1,208 @@ +package com.openwide.android; + +import java.util.HashSet; + +import android.app.ListActivity; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.provider.Contacts.Phones; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ListView; +import android.widget.SimpleCursorAdapter; + + +public class PhoneNumberSelection extends ListActivity +{ + PhoneDataListAdapter mAdpater; + String[] mSelected; + HashSet mSelectedSet; + private static final int INSERT_ID = Menu.FIRST; + private static final int SELECT_ALL_ID = Menu.FIRST + 1; + private static final int DESELECT_ALL_ID = Menu.FIRST + 2; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.number_list); + + + + mSelected = savedInstanceState != null ? savedInstanceState.getStringArray(MultiSmsSender.PARAM_NUMBERS_LIST ) : null; + + if (mSelected == null) { + Bundle extras = getIntent().getExtras(); + mSelected = extras != null ? extras.getStringArray(MultiSmsSender.PARAM_NUMBERS_LIST ) : null; + } + + mSelectedSet = new HashSet(); + for (int i = 0; i < mSelected.length; i++) { + mSelectedSet.add(mSelected[i].trim()); + } + fillData(); + + Button ok = (Button) findViewById(R.id.okContacts); + ok.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + Intent i = new Intent(); + String [] numbers = new String[mAdpater.selected.size()]; + mAdpater.selected.toArray(numbers); + Bundle bundle = new Bundle(); + + bundle.putStringArray(MultiSmsSender.PARAM_NUMBERS_LIST, numbers); + i.putExtras(bundle); + setResult(RESULT_OK, i); + finish(); + + } + }); + + + } + + private void fillData() { + Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, Phones.NAME); + startManagingCursor(c); + mAdpater = new PhoneDataListAdapter(this, R.layout.number_row, c, new String[] { + Phones.NAME, Phones.NUMBER + }, new int[] {R.id.name, R.id.phone}, mSelectedSet); + setListAdapter(mAdpater); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(0, INSERT_ID,0, R.string.add_group); + menu.add(0, SELECT_ALL_ID, 0, R.string.select_all); + menu.add(0, DESELECT_ALL_ID, 0, R.string.deselect_all); + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + switch(item.getItemId()) { + case INSERT_ID: + display_group_list(); + return true; + case SELECT_ALL_ID: + Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, Phones.NAME); + int numberIdx = c.getColumnIndex(Phones.NUMBER); + c.moveToFirst(); + for (int i = 0; i < c.getCount(); i++) { + mSelectedSet.add(c.getString(numberIdx)); + c.moveToNext(); + } + fillData(); + return true; + case DESELECT_ALL_ID: + mSelectedSet = new HashSet(); + fillData(); + return true; + } + return super.onMenuItemSelected(featureId, item); + } + + + public void display_group_list(){ + + Intent i = new Intent(this, SelectGroupActivity.class); + startActivityForResult(i, MultiSmsSender.ACTIVITY_ADD_GROUP); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + super.onListItemClick(l, v, position, id); + l.getItemAtPosition(position); + } + + /*@Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putStringArray(MultiSmsSender.PARAM_NUMBERS_LIST, (String[] )mAdpater.selected.toArray()); + } + + @Override + protected void onPause() { + super.onPause(); + }*/ + + public class PhoneDataListAdapter extends SimpleCursorAdapter{ + + public HashSet selected; + int nameidx; + int numberidx; + Context mContext; + + public PhoneDataListAdapter(Context context, int layout, Cursor c, + String[] from, int[] to, HashSet selected) { + super(context, layout, c, from, to); + nameidx = c.getColumnIndex(Phones.NAME); + numberidx = c.getColumnIndex(Phones.NUMBER); + mContext = context; + this.selected = selected; + + } + + public View getView(int position, View convertView, ViewGroup parent) { + Cursor c = getCursor(); + c.moveToPosition(position); + String name = c.getString(nameidx); + String number = c.getString(numberidx); + ContactRow contact; + if (convertView == null) { + contact = new ContactRow(mContext); + }else { + contact = (ContactRow) convertView; + } + contact.display(name, number, selected.contains(number)); + contact.mSelectedCheckBox.setOnClickListener(new addNumberToSelectedClickListener(contact)); + + return contact; + } + + } + + private class addNumberToSelectedClickListener implements OnClickListener{ + + ContactRow contact; + + public addNumberToSelectedClickListener(ContactRow contact) { + this.contact = contact; + } + + public void onClick(View v) { + CheckBox checkBox = (CheckBox)v; + if(checkBox.isChecked()) { + mSelectedSet.add(contact.mNumberView.getText().toString()); + }else { + mSelectedSet.remove(contact.mNumberView.getText().toString()); + } + + } + + } + + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + super.onActivityResult(requestCode, resultCode, intent); + if(intent != null) { + String [] numbers = intent.getExtras().getStringArray(MultiSmsSender.PARAM_NUMBERS_LIST); + + HashSet mSelectedGlobal = new HashSet(); + for (int i = 0; i < numbers.length; i++) { + mSelectedSet.add(numbers[i]); + } + mSelected = new String[mSelectedSet.size()]; + mSelectedGlobal.toArray(mSelected); + fillData(); + } + } +} diff --git a/src/com/openwide/android/SelectGroupActivity.java b/src/com/openwide/android/SelectGroupActivity.java new file mode 100644 index 0000000..bce8cb8 --- /dev/null +++ b/src/com/openwide/android/SelectGroupActivity.java @@ -0,0 +1,129 @@ +package com.openwide.android; + + + +import android.app.ListActivity; +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.provider.Contacts.Phones; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ContextMenu.ContextMenuInfo; +import android.widget.ListView; +import android.widget.SimpleCursorAdapter; +import android.widget.AdapterView.AdapterContextMenuInfo; + + +public class SelectGroupActivity extends ListActivity{ + + GroupsDbAdapter mDbHelper; + public static final int DELETE_ID = Menu.FIRST; + public static final int EDIT_ID = Menu.FIRST + 1; + public static final int CREATE_ID = Menu.FIRST + 2; + + public static final String PARAM_GROUP_ID = "gid"; + + public static final int ACTIVITY_EDIT_GROUP = 0; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.group_list); + mDbHelper = new GroupsDbAdapter(this); + mDbHelper.open(); + fillData(); + registerForContextMenu(getListView()); + } + + + + public void fillData() { + Cursor groupsCursor = mDbHelper.fetchAllGroups(); + + startManagingCursor(groupsCursor); + + String[] from = new String[]{GroupsDbAdapter.KEY_GROUP_NAME}; + + int[] to = new int[]{R.id.groupNameTextView}; + + SimpleCursorAdapter notes = + new SimpleCursorAdapter(this, R.layout.group_row, groupsCursor, from, to); + setListAdapter(notes); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(0, CREATE_ID,0, R.string.create_group); + return true; + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, + ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + menu.add(0, DELETE_ID, 0, R.string.remove_group); + menu.add(0, EDIT_ID, 0, R.string.edit_group); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + super.onListItemClick(l, v, position, id); + Cursor phonesListCursor = mDbHelper.fetchPhonesFromGroup(id); + int phoneNumberIdx = phonesListCursor.getColumnIndex(Phones.NUMBER); + String[] res = new String[phonesListCursor.getCount()]; + phonesListCursor.moveToFirst(); + for (int i = 0; i < res.length; i++) { + res[i] = phonesListCursor.getString(phoneNumberIdx); + phonesListCursor.moveToNext(); + + } + + Intent i = new Intent(); + Bundle bundle = new Bundle(); + + bundle.putStringArray(MultiSmsSender.PARAM_NUMBERS_LIST, res); + i.putExtras(bundle); + setResult(RESULT_OK, i); + finish(); + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + switch(item.getItemId()) { + case DELETE_ID: + AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); + mDbHelper.deleteGroup(info.id); + fillData(); + return true; + case EDIT_ID: + AdapterContextMenuInfo infoEdit = (AdapterContextMenuInfo) item.getMenuInfo(); + editGroup(infoEdit.id); + return true; + } + return super.onContextItemSelected(item); + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + switch(item.getItemId()) { + case CREATE_ID: + editGroup(null); + return true; + } + return super.onMenuItemSelected(featureId, item); + } + + public void editGroup(Long gid) { + Intent i = new Intent(this, GroupEditActivity.class); + + if (gid != null) { + i.putExtra(PARAM_GROUP_ID, gid); + } + + startActivityForResult(i, ACTIVITY_EDIT_GROUP); + } +}