研究生期间就没写过Java代码了,这几天由于想做一个统计网页词频的工具,但是使用C++不是很方便,于是又用Java做了一个小工具。翻开电脑中以前的文件,发现之前还做过一个android中批量添加联系人的工具,瞬间感觉好亲切,也感叹时间过得好快,一眨眼研究生就快要过完了。
记得当初做这个批量添加联系人的工具是刚来读研时,一大堆新同学的手机号码需要添加,班长整理出来同学们的通讯录后就得一个一个输入联系人和号码到手机中,想想这罪可有的受,于是就想能不能让手机直接读取xls格式(Excel格式)的文件到通讯录中,在网上查了下发现一般管理类的软件都没有这个小工具,想想可能是由于这个工具对excel文件的格式有限制吧。于是想干脆自己做一个算了,这个逻辑也不是很复杂,那个时候还懂一点android开发的东西。而且这个东西对android中的特性也不是很高,所以就做了一个批量添加联系人的小工具。现在两年没碰java,好多java的api和特性都忘记了,前两天做哪个网页词频统计的工具都是跌跌撞撞写出来的,android的东西就忘的几乎差不多了,只记得实现这个工具的大致思路。
一时玩心大起,便想看看当初做的这个东西。可惜电脑换系统了以前android开发的sdk也没了,不过好歹软件的apk文件还在,于是就借了同学的三星的手机将它安装到手机上,发现还能正常运行!!!简直太欣慰了,说明当初编写的代码鲁棒性还是蛮不错的,而且代码中注释也不少,现在看了下代码也能明白大概的思路,要是再花点时间看看Android开发的api可能就很快能上手了。于是在这里整理下。个人觉得这个东西实用性还是蛮强的,虽然没多少技术含量^ ^。
下面是实现这个工具的基本结构:
实现往通讯录中添加联系人需要上面基本的三个步骤,但是由于最开始就是为自己和班级同学制作的,所有默认显示的就是我们班同学的通讯录,软件运行的初始化界面如下:
软件开始运行后会有个提示框,提示软件的操作方法,点击确定后就可以操作,最上面有两个按钮,一个“一键添加”和“选择文件添加”按钮,下面每一行代表一个联系人的信息,从左到右依次是联系人姓名,电话号码,以及是否选择(是否选择添加到通讯录中,默认是全部选择)。
将不需要添加的联系人的右边的多选框中的勾去掉,然后点击“一键添加”按钮,就可以将选中的联系人全部倒入通讯录中。
如果要添加自己的通讯录,可以将通讯录存在的excel文件中(excel文件中第一列为联系人姓名,第二列为电话号码),然后点击上面的“选中文件添加”按钮,此时会弹出文件选择对话框,选中需要添加的通讯录对应的xls文件,此时下面的列表中就会显示你选中的通讯录中的联系人和号码,然后点击“添加”就可以将选中的联系人添加到通讯录中了。
上面就是程序的基本设计思路,具体的实现代码如下,我现在也只能根据注释看出那些函数式是什么的,以及程序的逻辑结构是怎么组织的,至于编程的细节都忘得长不多了。
真是囧啊。
存放联系人信息的类:
package com.example.bean;
public class PhoneRecord {
private int id;
private String name;
private String number;
private boolean isChecked;
public PhoneRecord() {
super();
}
public PhoneRecord(String name, String number) {
super();
this.name = name;
this.number = number;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean isChecked) {
this.isChecked = isChecked;
}
}
package com.example.activity;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import jxl.Sheet;
import jxl.Workbook;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentProviderOperation;
import android.content.OperationApplicationException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import com.example.bean.PhoneRecord;
import com.example.contract.R;
/**
*
* @author xiaxiongfeng
* @date 2013/9/1
* @version 1.0
*/
public class MainActivity extends Activity {
//保存从excel文件中读取进来的数据
private List<PhoneRecord> lists;
//保存去除掉某些用户后的联系人数据
private List<PhoneRecord> records;
//用来显示excel中联系人和联系电话的控件
private ListView listView;
//将数据映射到listView的适配器
private SimpleAdapter adapter;
//映射到控件中的数据
private List<Map<String, Object>> maps;
//当用户点击“选择添加文件”按钮后弹出的对话框
private ProgressDialog mpDialog;
//保存选择的xls文件的路径
private String filepath;
//对话框的标示
static private int openfileDialogId = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView) findViewById(R.id.list);
lists=readExcel();
mapViewList();
enterDialog();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
@Deprecated
protected Dialog onCreateDialog(int id) {
// TODO Auto-generated method stub
if(id==openfileDialogId){
Map<String, Integer> xlsFiles = new HashMap<String, Integer>();
// 下面几句设置各文件类型的图标, 需要你先把图标添加到资源文件夹
xlsFiles.put(OpenFileDialog.sRoot, R.drawable.filedialog_root); // 根目录图标
xlsFiles.put(OpenFileDialog.sParent, R.drawable.filedialog_folder_up); //返回上一层的图标
xlsFiles.put(OpenFileDialog.sFolder, R.drawable.filedialog_folder); //文件夹图标
xlsFiles.put("xls", R.drawable.filedialog_wavfile); //wav文件图标
xlsFiles.put(OpenFileDialog.sEmpty, R.drawable.filedialog_root);
Dialog dialog = OpenFileDialog.createDialog(id, this, "注意只能选择xls格式的文件", new CallbackBundle() {
@Override
public void callback(Bundle bundle) {
//选择文件后会进入这个函数,首先将文件路径保存在全局变量中
filepath = bundle.getString("path");
// setTitle(filepath); // 把文件路径显示在标题上
//读取excel文件,此时由于filepath不为空,readExcel会从filepath指定的路径中读取数据而不会使用默认的数据
lists=readExcel();
//将读取到的数据使用适配器映射到ListView控件中
mapViewList();
//将“一键添加”按钮隐藏
((Button)findViewById(R.id.defaultBtnID)).setVisibility(View.INVISIBLE);
//将“添加”按钮显示
((Button)findViewById(R.id.realAddBtn)).setVisibility(View.VISIBLE);
//让“选择文件添加”按钮失去焦点
((Button)findViewById(R.id.otherBtnID)).setFocusable(false);
}
},
".xls;",
xlsFiles);
return dialog;
}
return null;
}
/**
* 将从excel中读取到的数据转化到map中,然后将其显示到控件中
*/
public void mapViewList(){
maps=new ArrayList<Map<String,Object>>();
Iterator<PhoneRecord> iter=lists.iterator();
while(iter.hasNext()){
PhoneRecord record=iter.next();
Map<String,Object> map=new HashMap<String, Object>();
map.put("name", record.getName());
map.put("number", record.getNumber());
map.put("isChecked", record.isChecked());
maps.add(map);
}
adapter=new SimpleAdapter(this, maps, R.layout.activity_main_item,
new String[]{"name","number"}, new int[]{R.id.name,R.id.number}){
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
// TODO Auto-generated method stub
View view=super.getView(position, convertView, parent);
final HashMap<String,Object> hash=(HashMap<String, Object>) this.getItem(position);
CheckBox cb=(CheckBox) view.findViewById(R.id.checked);
cb.setChecked((Boolean) hash.get("isChecked"));
cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
hash.put("isChecked", ((CheckBox)v).isChecked());
}
});
return view;
}
};
listView.setAdapter(adapter);
}
//从excel中读取数据保存到PhoneRecord类中
public List<PhoneRecord> readExcel(){
List<PhoneRecord> lists=new ArrayList<PhoneRecord>();
try {
// InputStream is = new FileInputStream("mnt/sdcard/test.xls");
InputStream is=getAssets().open("contact.xls");
//只有弹出选择文件对话框并且选择了文件后才会进入这个选择分支,否则默认添加的是系统自带的通讯录
if (filepath!=null) {
is=new FileInputStream(filepath);
}
Workbook book = Workbook.getWorkbook(is);
book.getNumberOfSheets();
// 获得第一个工作表对象
Sheet sheet = book.getSheet(0);
int Rows = sheet.getRows();
for (int i = 0; i < Rows; i++) {
PhoneRecord record=new PhoneRecord();
String name=sheet.getCell(0,i).getContents();
String number=sheet.getCell(1,i).getContents();
if (name==null||name.equals("")||number==null||number.equals("")) {
continue;
}
record.setName(name);
record.setNumber(number);
record.setChecked(true);
lists.add(record);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return lists;
}
/**
* 将数据保存到通讯录中的方法
* @param list
*/
public void CopyPhoneRecords(List<PhoneRecord> list){
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
int rawContactInsertIndex;
if (list==null||list.size()==0) {
return ;
}
for (int i = 0; i < list.size(); i++) {
rawContactInsertIndex = ops.size();
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.withYieldAllowed(true)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,
rawContactInsertIndex)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,list.get(i).getName())
.withYieldAllowed(true)
.build());
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactInsertIndex)
.withValue(ContactsContract.Data.MIMETYPE,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, list.get(i).getNumber())
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, Phone.TYPE_MOBILE)
.withYieldAllowed(true)
.build());
}
try {
//这里才调用的批量添加
this.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//这个handler只有一个作用,接受到消息后关闭提示进度框
Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
mpDialog.dismiss();
};
};
Handler toastHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
Toast.makeText(getApplicationContext(), "批量添加完成!", Toast.LENGTH_LONG).show();
break;
case 2:
Toast.makeText(getApplicationContext(), "请选择联系人!", Toast.LENGTH_LONG).show();
break;
default:
break;
}
};
};
/**
* "一键添加"按钮的响应事件
* @param view
*/
public void defaultAdds(View view){
//默认的添加通讯录得事件
adds();
}
/**
* "选择文件添加"按钮的响应事件
* @param view
*/
public void otherAdds(View view){
// showDialog(openfileDialogId);
//当点击了“选择文件添加”后将“一键添加”按钮设为不可获得焦点
// Button bt=(Button)findViewById(R.id.defaultBtnID);
// bt.setFocusable(false);
//弹出文件选择对话框
showDialog(openfileDialogId);
}
/**
* "添加"按钮的响应事件
* @param view
*/
public void realAdd(View view){
//添加数据
adds();
//将“一键添加”按钮隐藏
((Button)findViewById(R.id.defaultBtnID)).setVisibility(View.INVISIBLE);
//将“选择文件添加按钮”可以获得焦点
((Button)findViewById(R.id.otherBtnID)).setFocusable(true);
}
/**
* 真实的添加过程
* 首先需要遍历从excel中读取的数据,判断他们的isChecked属性是否为真
* 默认情况下是为真,但是如果用户点击了ListView中的复选框,将某个用户去除的话这个属性会为假
*/
public void adds(){
int size=maps.size();
records=new ArrayList<PhoneRecord>();
int i=0;
for (; i < size; i++) {
PhoneRecord record=new PhoneRecord();
Map<String,Object> tmp=maps.get(i);
record.setName((String) tmp.get("name"));
record.setNumber((String) tmp.get("number"));
if((Boolean) tmp.get("isChecked")){
records.add(record);
}
}
//弹出提示进度框
mpDialog=ProgressDialog.show(this, "提示", "添加通讯录中,请等待...");
//开启一个新线程
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Message msg=new Message();
//在新的线程执行添加操作
if (records!=null&&records.size()!=0) {
CopyPhoneRecords(records);
//弹出一句话,提示批量操作完成
msg.what=1;
toastHandler.sendMessage(msg);
//当添加操作完成后,给提示进度框发送一个消息,让进度框关闭
handler.sendEmptyMessage(0);
}else{
msg.what=2;
toastHandler.sendMessage(msg);
handler.sendEmptyMessage(0);
}
}
}).start();
}
//最开始启动时的提示界面
public void enterDialog(){
final Dialog dialog=new Dialog(this,R.style.popupDialog);
dialog.setContentView(R.layout.verify_dialog);
dialog.setCancelable(false);
TextView message=(TextView) dialog.getWindow().findViewById(R.id.messageTxt);
message.setText(this.getString(R.string.defaultTxt));
Button okBtn=(Button) dialog.getWindow().findViewById(R.id.messageBtn);
okBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(dialog!=null && dialog.isShowing())
{
dialog.dismiss();
}
}
});
if(dialog!=null && !dialog.isShowing())
{
dialog.show();
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u012501459/article/details/47758091