Reputation: 1564
I am working on an app that works similar to the default text messaging app on all Android phones. My problem is selecting more than one user to send an SMS message to. What I have done so far is stored my contacts as listview items with check boxes. Now I just need to get the phone numbers from the selected contacts.
So what I am having trouble on doing. 1) Pulling a phone number from the contacts displayed in my listview 2)displaying that number in a textview in a new activity
Sorry if my code is difficult to understand, please ask if you need clerification.
This is the XML in which the listview is shown, called contact_manager.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/contactList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/showInvisible"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/showInvisible" />
</LinearLayout>
This is my Activity that calls everything together.
public final class ContactManager extends Activity {
public static final String TAG = "ContactManager";
private ListView mContactList;
private boolean mShowInvisible;
private Button mShowInvisibleControl;
/**
* Called when the activity is first created. Responsible for initializing
* the UI.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "Activity State: onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.contact_manager);
// Obtain handles to UI objects
mContactList = (ListView) findViewById(R.id.contactList);
mShowInvisibleControl = (Button) findViewById(R.id.showInvisible);
// Initialize class properties
mShowInvisible = false;
// mShowInvisibleControl.setChecked(mShowInvisible);
mShowInvisibleControl.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
}
});
populateContactList();
}
/**
* Populate the contact list based on account currently selected in the
* account spinner.
*/
private void populateContactList() {
// Build adapter with contact entries
Cursor cursor = getContacts();
String[] fields = new String[] { ContactsContract.Data.DISPLAY_NAME };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.contact_entry, cursor, fields,
new int[] { R.id.contactEntryText });
mContactList.setAdapter(adapter);
}
/**
* Obtains the contact list for the currently selected account.
*
* @return A cursor for for accessing the contact list.
*/
private Cursor getContacts() {
// Run query
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] { ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME };
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '"
+ (mShowInvisible ? "0" : "1") + "'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
+ " COLLATE LOCALIZED ASC";
return managedQuery(uri, projection, selection, selectionArgs,
sortOrder);
}
contact_entry.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<CheckBox
android:id="@+id/contactEntryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@+id/contactEntryText" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/contactList"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="@+id/showInvisible"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/showInvisible" />
</LinearLayout>
This is my invite_text.xml This is actually the text view i want to input the numbers into so i can send a mass text message.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/contacts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:gravity="center"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp"
android:text="@string/contacts"
android:textAppearance="?android:attr/textAppearanceLarge" />
<!-- android:textColor="#fff" android:background="@drawable/header" for header background -->
<Button
android:id="@+id/contactsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="@string/contacts" />
</RelativeLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/enter_contact"
android:textAppearance="?android:attr/textAppearanceMedium" />
<AutoCompleteTextView
android:id="@+id/contactnumber"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/to" >
<requestFocus />
</AutoCompleteTextView>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/message_to_send"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/invite_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/message_join" />
<Button
android:id="@+id/sendtxt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="doLaunchContactPicker"
android:text="@string/send_txt" />
</LinearLayout>
</ScrollView>
If you need me to post any more information, please ask.
Upvotes: 4
Views: 4191
Reputation: 24031
I have not looked at your code but here is the mechanism which worked for me:
1. Put setOnCheckedChangeListener
to your checkbox.
2. If Checkbox
is Checked
then add that contact to arraylist
.
3. If CheckBox
is unchecked
then remove that contact from arraylist
.
4. Start your contact list activity with startActivityForResult()
and override onActivityResult()
.
5. Before leaving contact activity
set your selected contacts in intent
.
6. Receive the selected contacts in your activity.
7. Now you have selected contacts which you can show in TextView
.
Note: You need to use custom list adapter for this:
Custom List Adapter:
public class YourAdapterName extends BaseAdapter{
private Context mContext;
private ArrayList<string> mValuestoShow;
/**
* Constructor to be called to initialize adapter with values.
* @param context
* @param vector
*/
public YourAdapterName(Context context, ArrayList<string> contacts){
mContext = context;
mValuestoShow = contacts;
}
public int getCount() {
if(null != mValuestoShow){
return mValuestoShow.size();
}
return 0;
}
public Object getItem(int position) {
if(position < mValuestoShow.size())
return mValuestoShow.get(position);
else
return null;
}
public long getItemId(int position) {
return 0;
}
/**
* This method can be override to enable/disable particular list row.
*/
@Override
public boolean isEnabled(int position) {
//Write your code here......
return super.isEnabled(position);
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater li =(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.contact_list_layout, null);
holder = new ViewHolder();
holder.name = (TextView)convertView.findViewById(R.id.name);
holder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.name.setText(text goes here ....);
holder.checkbox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if ( isChecked )
//Add contact...
else
//Remove contact.
}
});
return convertView;
}
class ViewHolder {
TextView name;
CheckBox checkbox;
}
}
your_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="50dp"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@android:color/black" />
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>
Upvotes: 2
Reputation: 452
I think the below code will give the results as what you expected... Your main class will lokk like the below...
import java.util.ArrayList;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
public class GetSelectedContacts extends Activity{
int CONTACTS_REQUEST_CODE =1;
Activity thisActivity;
ArrayList<String> selectedConatcts;
LinearLayout contactdisp;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
thisActivity = this;
Button btn = (Button)findViewById(R.id.btn_selectContact);
contactdisp = (LinearLayout)findViewById(R.id.lnr_contactshow);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(thisActivity,ListActivitySampleActivity.class);
startActivityForResult(intent, CONTACTS_REQUEST_CODE);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(data!=null){
Bundle bundle = data.getExtras();
if(requestCode ==1){
selectedConatcts = bundle.getStringArrayList("sel_contacts");
Log.v("", "Selected contacts-->"+selectedConatcts);
if(selectedConatcts.size()<0){
}else{
for(int i =0;i<selectedConatcts.size();i++){
LinearLayout lnr_inflate = (LinearLayout)View.inflate(thisActivity, R.layout.contacts_inflate, null);
EditText edt = (EditText)lnr_inflate.findViewById(R.id.edt_contact);
edt.setText(selectedConatcts.get(i));
contactdisp.addView(lnr_inflate);
}
}
}
}
}
}
The contacts selection class like
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
public class ListActivitySampleActivity extends Activity {
static ContentResolver cr;
String[] phone_nos;
ArrayList<String> selectedContacts = new ArrayList<String>();
Activity thisActivity;
Button btn;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
thisActivity = this;
final ListView lst = (ListView)findViewById(R.id.listView1);
populateContact();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(thisActivity, android.R.layout.simple_list_item_multiple_choice, phone_nos);
lst.setAdapter(adapter);
lst.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
lst.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {
}
});
final int len = lst.getCount();
final SparseBooleanArray checked = lst.getCheckedItemPositions();
btn = (Button)findViewById(R.id.btn_send);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
for (int i = 0; i < len; i++)
if (checked.get(i)) {
selectedContacts.add(phone_nos[i]);
//you can you this array list to next activity
/* do whatever you want with the checked item */
}
Bundle bundle = new Bundle();
bundle.putStringArrayList("sel_contacts", selectedContacts);
Intent contactIntent = new Intent();
contactIntent.putExtras(bundle);
setResult(1, contactIntent);
thisActivity.finish();
// Log.v("", "selected-->"+selectedContacts);
}
});
}
private void populateContact(){
Uri myContacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI ;
Cursor mqCur = managedQuery(myContacts, null, null, null, null);
phone_nos = new String[mqCur.getCount()];
int i =0;
if(mqCur.moveToFirst())
{
do
{
String phone_no = mqCur.getString(mqCur
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
phone_nos[i] = phone_no;
i++;
}
while(mqCur.moveToNext());
}
}
}
Upvotes: 0
Reputation: 9590
There is no stort ans to your question. You have to write your own adapter and have support for multi selection. I had replied on SO to similar problem (If this helps OK else let me know and I can explain in detail):
Android listview toggle button
android : checkboxes in a ListView ( strange behaviour of selected element)
Upvotes: 1
Reputation: 1215
I suggest you to look at the tutorial that I have written last month at this link to manage the selection of the checkbox in the list (it helps you to keep states and retrieves items by ids).
I think that it's better if you manage your list by id but displaying to user the contact name. After that you can pass your ids and send them with the mechanisms that jeet has told you.
Upvotes: 0
Reputation: 29199
Please follow below steps to make it working:
->Have a boolean array, of size equal to cursor. This array will represent checked state of contact. ->In xml make checkbox unclickable and unfocusable. ->setOnItemClickListener on ListVIew and in onItemClick method toggle boolean array's value on position, item selected. ->Set OnClickListener on Button, and onClick method of listener fetch numbers from cursor by follosing:
ArrayList<String> numbers=new ArrayList<String>();
cursor.moveToFirst();
for(int i=0;i<cursor.getCount;i++)
{
cursor.moveToNext();
if(selected[i])
{
//fetch contact from cursor
//add number to numbers
}
}
//Use ArrayList numbers to send Contact, it doesnot seems that you can append multiple numbers to same message, in the case send messages to numbers by a loop, see following thread: Sending sms to multiple people in android amd Unable to send sms using SMSManager in Android
Upvotes: 1
Reputation: 943
I'm just going to post a strategy answer. Use hashmap for the list adapter. Use a key that is not displayed to store the phone number to call. Allow multiple selection in the listview. Use the stored phone numbers from the selected entries.
Upvotes: 0