联系人助手 3.功能的实现

  一. 分析 : java文件以及要实现的功能 

1 .主界面------MainActivity.java

  各个功能的跳转 

MainActivity  --------->ExportExcel.java (导出联系人)

                   ---------->ImportExcel.java (导入联系人)

两个分支里面都 有文件浏览功能 

                ------------>FileSerach.java (文件浏览)

2. 导出联系人界面 --------ExportExcel.java

功能有:

 (1) 通过  ContentProvider 查询所有的联系人数据到  Cursor中。

(2) 将Cursor中的数据遍历并保存在  Map中,因为Cursor存在 的时间很短,我们无法保证 在很短的时间内完成所有 数据 的写入工作。

(3)遍历Map数据 并写入到Excel中。

3.  导入联系人 -----------ImportExcel.java

功能与导出相仿,主要 工作:

遍历Excel文件,将数据逐一写入到联系人数据库中。  

4. 实现 文件的浏览功能模块---------FileSerach.java

    用于浏览手机中所有 的文件,以方便用户选择要导入 or导出的路径。 


二、先重点实现导出联系人界面的所功能 

  1. 整体设计 

initView() --------------->initXLs()   ---------------> add()

public class ExportExcel extends Activity{
	public String FILE_PATH ="";
	public String FILE_NAME="";
	public static final String END_TAG="导出完毕,可以退出程序";
	WritableWorkbook wwb ;
	WritableSheet ws;
	ContentResolver resolver ;
	TextView tv;
	TextView tips ;
	EditText fileNameEdit;
	EditText filePathEdit;
	Button searchBtn;
	Button exportBtn;
	ProgressBar bar;
	Handler handler ;   //Handler用于处理消息,改变 UI
	HashMap <String ,String >map = new HashMap<String ,String >();//保存联系人信息
	HashMap<String ,String >new_map= new HashMap<String ,String >();
	//保存已经导出的联系人数据

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.export);
		initView();
		
		handler = new Handler (){
			public void handleMessage(Message msg) {
				String content =(String) msg.obj;
				int added= msg.arg1;
				tv.setText(content);                       //显示正在导出的人名
				bar.setProgress(added);                //进度
				if(content.equals(END_TAG)){
					bar.setVisibility(View.INVISIBLE);
					tips.setVisibility(View.INVISIBLE);
					tv.append("\n本次导出记录 :"+String.valueOf(added)+"条");
					
				}
				super.handleMessage(msg);
			}
			
		};
	}

	private void initView() {
		// TODO Auto-generated method stub
		
	}

}

     在安卓 中,所有界面的更新都要在主线程中,如果我们希望在不同的线程中更新UI,可以使用Handler ,在安卓 中,Handler常常用来接收其它线程发送的消息,并适时进行界面的更新。

    Handler是一个用于线程间通信的类,最常用于做下载条,

    我们重写  handleMessage方法,并在这个 方法中进行界面的更新,在其它的线程中使用 

Handler.sendMessage ()

方法就可以触发这个 回调方法。


2. initView的实现 

private void initView() {
		// TODO Auto-generated method stub
		tv = (TextView)findViewById(R.id.tv);
		tips=(TextView)findViewById(R.id.tips);
		fileNameEdit=(EditText)findViewById(R.id.fileNameEdit);
		filePathEdit=(EditText)findViewById(R.id.filePathEdit);
		searchBtn =(Button)findViewById(R.id.search);
		exportBtn =(Button)findViewById(R.id.exportBtn);
		bar =(ProgressBar )findViewById(R.id.bar);
		
		tips.setVisibility(View.INVISIBLE);   //先不可见
		bar.setVisibility(View.INVISIBLE);
		tv.setVisibility(View.INVISIBLE);
		
		searchBtn.setOnClickListener(new OnClickListener(){
			public void onClick(View arg0) {
				Intent i = new Intent (getBaseContext() , FileSearch.class);
				startActivityForResult(i ,0);  //requestCode
			}
		});
		
		exportBtn.setOnClickListener(new OnClickListener(){
			public void onClick(View v) {
				// TODO Auto-generated method stub
				map.clear();
				new_map.clear();
				FILE_NAME=fileNameEdit.getText().toString();  //得到文件名
				FILE_PATH=filePathEdit.getText().toString();  //文件路径 
				if (initXLs()){                   //初始化jxl,使之可用,如果成功,则开始添加 
					bar.setMax(map.size());  //这是 用map,而不是new_map
					tips.setVisibility(View.VISIBLE);
					bar.setVisibility(View.VISIBLE);
					tv.setVisibility(View.VISIBLE);
					Thread th = new Thread(new Runnable(){
						public void run() {
							// TODO Auto-generated method stub
							add();    //使用单独的线程完成 将联系人添加 到excel的工作
						}
					});
					th.start();
				}
			}
		});
	}

3. initXLs的实现 

    功能 :实现 了可写 的workbook和sheet的创建 ,同时 完成 了数据 源了组成 ,也就是将联系人列表读入HashMap中。

private boolean initXLs() {
		// TODO Auto-generated method stub
		if(FILE_PATH.trim().equals("")){
			FILE_PATH= Environment.getExternalStorageDirectory().getAbsolutePath();
		}
		if (!FILE_NAME.endsWith(".xls")&&!FILE_NAME.contains(".")){
			FILE_NAME=FILE_NAME+".xls";
		}
		String path = FILE_PATH+"/"+FILE_NAME.trim();
		try{
			File file = new File(path);
			if(!file.exists()){
				file.createNewFile();
			}
			wwb=Workbook.createWorkbook(file);
			ws = wwb.createSheet("联系人列表",0);
			//得到ContentResolver对象 
			resolver=getContentResolver();
			Cursor cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
					null, null, null, null);
			cursor.moveToFirst();
			while (!cursor.isAfterLast()){
				String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); //得到姓名
				String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
				map.put(name, number);
				cursor.moveToNext();
			}
			return true;
		}catch(FileNotFoundException e){
			e.printStackTrace();
		}catch(IOException e1){
			Toast.makeText(getBaseContext(), "文件路径错误", Toast.LENGTH_SHORT).show();
			e1.printStackTrace();
		}
		return false;
	}

注意,里面用到了IO相关的类,要给一定的权限 ,要不然会出现 IOException.

  <uses-permission android:name="android.permission.READ_CONTACTS"/>

    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

如果在Workbook创建 时,出现 了找不到Class的错误 ,应该是jxl 库导入的问题,可以直接复制 到libs文件下。

注意里面的联系人信息的取得 :

联系人列表 URI:   

ContactsContract.CommonDataKinds.Phone.CONTENT_URI

联系人姓名:

ContactsContract.Contacts.DISPLAY_NAME

联系人电话:

ContactsContract.CommonDataKinds.Phone.NUMBER


4. add的实现 

由于 add()方法执行在不同的线程中,所以我们不能直接 在这个 线程中进行UI的修改,这就要用来 我们讲到的 

Handler.sendMessage()方法。

private void add() {
		// TODO Auto-generated method stub
		try {
			Iterator <Entry<String ,String >>iter = map.entrySet().iterator();
			Label labelC0= new Label (0 ,0 ,"name");
			Label labelC1 = new Label (1,0,"number");
			ws.addCell(labelC0);
			ws.addCell(labelC1);
			int row =1;
			while (iter!=null&&iter.hasNext()){     //遍历Map
				Entry <String ,String >entry = iter.next();
				String name = entry.getKey();
				String number =entry.getValue();
				//判断 是否有重复的
				if(map_new.containsKey(number)){
					continue;
				}else {
					map_new.put(number, "");
				}
				//将姓名 和号码写入到单元 格并加入 到表中,同时 能和 handler此时 正在 导出的内容 
				if(name!=""&&number!=""){
					Label labelName = new Label (0,row, name);
					Label labelNumber = new Label (1,row ,number );
					ws.addCell(labelName);
					ws.addCell(labelNumber);
					Message msg = new Message ();
					msg.obj= name+":"+number ;
					msg.arg1= row;
					handler.sendMessage(msg);  //消息发送到handler 中
					row++;
					
				}
			}
			wwb.write();  //写入到wwb中
			wwb.close();
			
			Message msg = new Message ();   //发送结束标志
			msg.obj=END_TAG;
			msg.arg1=row-1;
			handler.sendMessage(msg);
		}catch(Exception e ){
			e.printStackTrace();
		}
	}

为了加入延时的效果,我们在row++代码 后面加入 线程延时600ms

try {
	                    Thread.currentThread().sleep(600);
	                } catch (InterruptedException e) {
	                    e.printStackTrace();
	                }

5. 实现 onActivityResult()方法

由于在整体设计 中,我们用到了startActivityForResult (),所以有这个。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		switch(resultCode){
			case RESULT_OK:
				Bundle bundle = data.getExtras();
				String filePath = bundle.getString("filePath");
				filePathEdit.setText(filePath);
				break;
			default :
					break;
		}
	}


你可能感兴趣的:(联系人助手 3.功能的实现)