您的位置:首页 > 理论基础 > 数据结构算法

利用ListActivity,CursorAdapter获取用户输入(短信群发器的地址输入实现)总结

2012-05-19 03:01 495 查看
    这两天在做一个短信群发器,在用ListActivity和CursorAdapter罗列联系人并记录用户输入时遇到了一些麻烦,解决过程颇为繁琐,深深感到Android API之广、杂的同时也让自己能静下心来谨慎编码仔细调试广泛查阅,现将最终成果和各种问题以及相应解决方法一一罗列,作为这两日的工作总结的同时,希望能给各位带来一些帮助。

    先说明下这个模块要实现的功能吧,此模块主要为群发短信的地址输入模块,用户可以在EditText中直接输入地址,也可以从联系人中pick多个电话号码。

    遇到的主要问题有:

    1.为了实现两种输入方式(直接EditText输入和联系人选择输入),创建了一个从联系人选择电话号码的ListActivity,为了能在地址编辑Activity和ListActivity之间切换而不丢失已经编辑了的电话号码,就得创建一种数据结构来保存这些电话号码,我这里使用的是一个LinkedList(具体结构后面再阐述),但是怎么样才能保证每次切换都能正确保存地址数据而且EditText内容与地址数据结构保持一致呢?!解决方法是在每次Activity切换时都先进行一次解析或提取过程:从EditText切换到ListActivity之前读取EditText的字符串内容并分析获得地址数据保存到LinkedList中,从ListActivity切换到Activity之前解析LinkedList内容获取要在EditText中显示的字符串内容。

    2.有些联系人的号码不止一个,那么应该如何对待?这里我选择的方式和我的Android 2.3系统自带的短信发送器不一样,系统自带的在从联系人获取号码时,如果联系人的号码多于1个,会弹出一个对话框让用户选择一个号码,而我选择的时对话框让用户选择多个号码。

    3.对话框与主Activity之间的通信问题,如何让对话框保存用户选择给Activity使用?这里我的解决方式是用静态变量和final变量,从内部类中调用这些变量。

    4.用户从对话框选择号码后,如何更新ListActivity的显示内容?我的解决方法是用Handler,对话框给Handler发送消息,Handler使ListActivity更新界面,更新方法为调用Cursor的requery方法。

    还有几个比较小的问题,比如联系人数据库的内容,ListActivity中CheckBox的绘制等,就不一一列举了。

    现附上我的代码(代码上还有很多清晰的改动以及调试痕迹,呵呵):

a.短信编辑Activity

/*
* this Activity is created for sending message
* users would edit sms message body in the EditText message , and destinations in the EditText receivers
* there can be more than one destinations , and they are arranged at a strict layout
* the phone number of every destination would be a String of digits , and they are separated by ','
* and the spaces in the string are all ignored
* a valid destinations description is like this : 1234 ,1254,1 3 52,6528,
*
*/
package com.tobacco.activity;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import com.tobacco.pro.R;
import com.tobacco.sms.SMSSender;

public class EditMessAct extends Activity implements OnClickListener{
private Button findContacts;
private Button send;
private EditText receivers;
private EditText message;
private ArrayList<String> dest;
private static final char SEPARATE=',';
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editmessage);
init();
}
private void init(){
findContacts=(Button)findViewById(R.id.contacts);
send=(Button)findViewById(R.id.send);
receivers=(EditText)findViewById(R.id.receivers);
message=(EditText)findViewById(R.id.messagetext);
findContacts.setOnClickListener(this);
send.setOnClickListener(this);
dest=new ArrayList<String>();
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i;
if(v==findContacts){
refreshDest();
i=new Intent(this,ListContactAct.class);
this.startActivityForResult(i,1);
}
else if(v==send){
refreshDest();
String t=message.getText().toString();
new SMSSender(t,dest).send();
}

}

@Override
protected void onActivityResult(int request,int result,Intent intent){
super.onActivityResult(request,result,intent);
int t=ListContactAct.selectedReceiver.size();
int i=0;
int k=0;
int p,j;
boolean mark;
//String str="";
for(i=0;i<t;i++){
//str=str+ListContactAct.selectedReceiver.get(i).phoneNumber+";";
p=ListContactAct.selectedReceiver.get(i).phoneNumber.size();
for(k=0;k<p;k++){
mark=true;
for(j=0;j<dest.size();j++){
if(ListContactAct.selectedReceiver.get(i).phoneNumber.get(k).equals(dest.get(j))){
mark=false;
}
}
if(mark){
dest.add(ListContactAct.selectedReceiver.get(i).phoneNumber.get(k));
}
}
}
refreshText();
//receivers.setText(str+receivers.getText().toString());
}
//refresh the EditText receivers by the ArrayList dest
private void refreshText(){
String t="";
int k=dest.size();
int i;
for(i=0;i<k;i++){
t+=dest.get(i);
t+=SEPARATE;
}
receivers.setText(t);
}
//refresh the ArrayList dest by the EditText receivers and return information of the analyze result
private int refreshDest(){
ArrayList<String> tempDest=new ArrayList<String>();
String f=receivers.getText().toString();
int k=f.length();
String number="";
for(int i=0;i<k;i++){
if(f.charAt(i)==SEPARATE){
if(number.length()>0){
boolean tempMark=true;
for(int m=0;m<tempDest.size();m++){
if(tempDest.get(m).equals(number)){
tempMark=false;
break;
}
}
if(tempMark){
tempDest.add(number);
}

}
number="";
}
else if(f.charAt(i)>='0'&&f.charAt(i)<='9'){
number+=f.charAt(i);
}
}
if(number.length()>0){
boolean tempMark=true;
for(int m=0;m<tempDest.size();m++){
if(tempDest.get(m).equals(number)){
tempMark=false;
break;
}
}
if(tempMark){
tempDest.add(number);
}

}
dest=tempDest;
return 0;
}

}


从联系人pick号码的ListActivity:

package com.tobacco.activity;

//import java.util.ArrayList;
import java.util.ArrayList;
import java.util.LinkedList;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.provider.Contacts.People.Phones;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ListView;

import com.tobacco.adapter.ListContactsAdapter;
import com.tobacco.pro.R;
import com.tobacco.types.Receiver;

@SuppressWarnings("deprecation")
public class ListContactAct extends ListActivity{
private Cursor cursor;
public static LinkedList<Receiver> selectedReceiver;
public static LinkedList<Integer> selectedPos;
private int idColumn;
private int displayNameColumn;
public static Handler hand;
//private Cursor phones=null;
//private ArrayList<String> pNumber;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//pNumber=new ArrayList<String>();
selectedReceiver =new LinkedList<Receiver>();
selectedPos=new LinkedList<Integer>();
//cursor=getContentResolver().query(People.CONTENT_URI,null,null,null,null);
//the cursor get by the above command has no column of has_phone_number
cursor= managedQuery(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
debugColumnInfo();
startManagingCursor(cursor);
idColumn=cursor.getColumnIndex(ContactsContract.Contacts._ID);
displayNameColumn=cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);
ListContactsAdapter adapter = new ListContactsAdapter(
this,
R.layout.listcontact,
cursor,
new String[] {Phones.DISPLAY_NAME},
new int[] {R.id.people});
this.setListAdapter(adapter);
hand=new Handler(){
@Override
public void handleMessage(Message msg){
Bundle bundle=msg.getData();
int pos=bundle.getInt("position");
if(pos!=-1){
cursor.requery();
}
}
};
}
@Override
protected void onPause(){
super.onPause();
Intent intent=new Intent();
intent.putExtra("date",1);
setResult(1,intent);
finish();
}
@Override
protected void onListItemClick (ListView l, View v, int position, long id){
//Toast.makeText(this,""+position+"+"+id,Toast.LENGTH_SHORT).show();
CheckBox cbx = (CheckBox) v.findViewById(R.id.check);
String contactId=null;
String displayName=null;
int hasPhone;
final int phoneCount;
int t=0;
int q=0;
int i;

cursor.moveToPosition(position);
contactId=cursor.getString(idColumn);
displayName = cursor.getString(displayNameColumn);
while(q<selectedReceiver.size()&&!selectedReceiver.get(q).id.equals(contactId)){
q++;
}
Integer intg=new Integer(position);
while(t<selectedPos.size()&&!selectedPos.get(t).equals(intg)){
t++;
}

if(t<selectedPos.size()){
if(cbx.isChecked()){
cbx.setChecked(false);
}
selectedReceiver.remove(q);
selectedPos.remove(t);
//the people has been added to the send list already
/*phoneCount=cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if(phoneCount>1){
a
}*/
}
else{
//the people has not been added to the send list yet
hasPhone=Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));
//note:the variable hasPhone ,as the number stored in column has_phone_number is not represent the count of
//phone numbers the people has,but the mark that if the people has at least one phone number ,1 has or 0 not
//Toast.makeText(this,"phoneCount:"+phoneCount,Toast.LENGTH_SHORT).show();

if(hasPhone>0){
final Cursor phones = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
+ " = " + contactId, null, null);
//Toast.makeText(this,"phoneCount22:"+phones.getCount(),Toast.LENGTH_SHORT).show();
phoneCount=phones.getCount();
final String[] pNums=new String[phoneCount];
//pNumber=new ArrayList<String>();
if (phones.moveToFirst()){
i=0;
do{
//pNumber.add(phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
//pNumber is a ArrayList instance to record the phone numbers of the people that was clicked
pNums[i]=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
i++;
}while (i<phoneCount&&phones.moveToNext());
}
//Toast.makeText(this,""+pNumber.get(0),Toast.LENGTH_SHORT).show();

if(phoneCount==1){
if(!cbx.isChecked()){
cbx.setChecked(true);
}
selectedReceiver.add(new Receiver(contactId,displayName,pNums[0]));
Integer in=new Integer(position);
selectedPos.add(in);
}
else if(phoneCount>1){
final boolean[] mark=new boolean[phoneCount];
final String name=displayName;
final int p=position;
final String conId=contactId;
for(int w=0;w<phoneCount;w++){
mark[w]=false;
}
AlertDialog ad=new AlertDialog.Builder(this)
.setTitle("select phone number")
.setMultiChoiceItems(pNums,mark,new DialogInterface.OnMultiChoiceClickListener(){
public void onClick(DialogInterface dialog,int which,boolean isChecked){

}
})
.setPositiveButton("okay",new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
ArrayList<String> a=new ArrayList<String>();
for(int u=0;u<mark.length;u++){
if(mark[u]){
a.add(pNums[u]);
}
}
ListContactAct.selectedReceiver.add(new Receiver(conId,name,a));
Integer in=new Integer(p);
ListContactAct.selectedPos.add(in);
Bundle bundle=new Bundle();
bundle.putInt("position",p);
Message msg=Message.obtain();
msg.setData(bundle);
ListContactAct.hand.sendMessage(msg);
}
}).setNegativeButton("cancel",null).create();
ad.show();
}

}
}

super.onListItemClick(l, v, position, id);

}

private void debugColumnInfo(){
int count=cursor.getColumnCount();
int t=0;
String tag="DebugColumn";
for(;t<count;t++){
Log.d(tag,cursor.getColumnName(t));
}
}

}


自定义Adapter:

package com.tobacco.adapter;

import com.tobacco.activity.ListContactAct;
import com.tobacco.pro.R;

import android.content.Context;
import android.database.Cursor;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.SimpleCursorAdapter;

public class ListContactsAdapter extends SimpleCursorAdapter{

public ListContactsAdapter(Context context, int layout, Cursor c,String[] from, int[] to) {
super(context, layout, c, from, to);
}

@Override
public View getView(int position, View convertView, ViewGroup parent){
View rowView=super.getView(position,convertView,parent);
int t=0;
Integer in=new Integer(position);
while(ListContactAct.selectedPos.size()>t&&!ListContactAct.selectedPos.get(t).equals(in)){
t++;
}
CheckBox cbx=(CheckBox)(rowView.findViewById(R.id.check));
if(t<ListContactAct.selectedPos.size()){
cbx.setChecked(true);
}
else
{
cbx.setChecked(false);
}
return rowView;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐