觀察者模式之android 通訊錄撥打的歷程記錄

在做android 通訊錄的歷史記錄,因爲需求的繁瑣,且變態,又整天被老闆催着趕項目。本人又是菜鳥,所以項目代碼寫的哪個繁瑣啊,垃圾。

先吐槽下,開始正題。

 複習下觀察者模式

 對象:觀察者,被觀察者。

我們可以理解爲被觀察者就是我門需要的數據源,觀察者就是我們數據源更改變化之後,我們需要變化的界面啊,類啊。什麼東東的。

 想想android的adapter中的notifyDataSetChanged。它底層實現必須是用了觀察者模式。

直接上代碼

被觀察者要繼承java中的Observable。實現了Observable 就可以使用add方法添加觀察者。romve 方式溢出觀察者。

對了被觀察者通知觀察者數據源發生變化是通過setChanged();  notifyObservers();來通知的。其實和android中的 adapter.notifyDataSetChanged();一樣的。

下面是被觀察者的代碼

 

package bsn.report.person;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Observable;




import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Contacts;
/**
 *通訊錄歷史記錄 的數據源
 *我把他當做被觀察者
 * @author Administrator
 *
 */

public class ContactsHistoryObserver extends Observable {
	private ListQueryHandler mQueryHandler;
    private  PhoneContact phoneContact;
    private MyApplication application;
    private int sdkVersion = 4; 
    private static List<PhoneContact>phoneContacts= new ArrayList<PhoneContact>();
    private String mColumnName = null,mColumnNumber=null,mColumnType=null,mColumnDate=null; 
	private ContactsHistoryObserver historyObserver;
	public static boolean  FINDBL=false;
    ContactsHistoryObserver(Context context){
    	historyObserver=new ContactsHistoryObserver();
    	application=(MyApplication) context.getApplicationContext();
        mQueryHandler=new ListQueryHandler(context.getContentResolver());
        queryList(mQueryHandler);  
    }
    ContactsHistoryObserver(){
    	
    }
    public void setData(boolean findbl){
    	FINDBL=findbl;


    }
    public void setHistoryContact( List<PhoneContact>phoneContacts){
    	this.phoneContacts=phoneContacts;
    	setChanged();
    	notifyObservers();
    }
	public void queryList(AsyncQueryHandler async) {
		if (async != null) {
			try {
				sdkVersion = Integer.parseInt(android.os.Build.VERSION.SDK.trim());
			} catch (Exception e) {
				sdkVersion = 3;
			}
			
	        Uri personUri = null;
	        if(sdkVersion > 4){//2.x,sdk版本
	        personUri = Uri.parse("content://call_log/calls");
	        mColumnName = "name";
	        mColumnNumber="number";
	        mColumnType="type";
	        mColumnDate="date";
	        
	    }else{//1.6以下SDK
	        personUri = Contacts.People.CONTENT_URI;
	        mColumnName = Contacts.People.NAME;
	    }
	    //開始異步查詢
			async.startQuery(0, null, personUri, null, null, null, null);
		}
	}
	
	public static List<PhoneContact> getAllData(){
		return phoneContacts;
	}
 class ListQueryHandler extends AsyncQueryHandler {  
	  
    public ListQueryHandler(ContentResolver cr) {  
          super(cr);  
	       }  
	 
     /** 
      * 異步查詢結束時 
       */  
     public void onQueryComplete(int token, Object cookie, Cursor cursor) {  
  	   String name = null, number = null;
  	   int type=0;
          if (cursor != null) {  	
             try {
             int nameIndex = cursor.getColumnIndex(mColumnName);
   			 int numberIndex = cursor.getColumnIndex(mColumnNumber);
   			 int typeIndex = cursor.getColumnIndex(mColumnType);
   			 int dateIndex = cursor.getColumnIndex(mColumnDate);
   			cursor.moveToFirst();
   			while (cursor.moveToNext()) {
   				phoneContact=new PhoneContact();
  		 		number = cursor.getString(numberIndex);
  				name = cursor.getString(nameIndex);
  				type = cursor.getInt(typeIndex);
  				phoneContact.setName(name);
  				phoneContact.setPhone_type(type);
  				phoneContact.setPhone_time(Long.parseLong(cursor.getString(dateIndex)));
  			    phoneContacts.add(phoneContact);
  			}
   			
   			setHistoryContact(phoneContacts);
//   			this.ContactsHistoryObserver.addObserver(allConacts);
  			cursor.close();
  			//在這裏爲所有通話記錄 和未接電話加入監聽。
  			AllConacts allConacts=new AllConacts();
  			MissContacts missContacts=new MissContacts();
   		    historyObserver.addObserver(allConacts);
   		    historyObserver.addObserver(missContacts);
   		    historyObserver.setData(true);
   		    historyObserver.setHistoryContact(phoneContacts);
  			Collections.sort(phoneContacts, new Comparator<PhoneContact>() {
  				@Override
  				public int compare(PhoneContact object1, PhoneContact object2) {
  					int  compareName=String.valueOf(object2.getPhone_time()).compareTo(object1.getPhone_time()+"");
  					return compareName;
  				}
  			});
  		    
			} catch (Exception e) {
				// TODO: handle exception
			}
        }
     }
	    } 

}


 

tab代碼 。這裏主要是記下其中的模式,沒完善tab


   

package bsn.report.person;


import android.app.TabActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TabHost;
import android.widget.RadioGroup.OnCheckedChangeListener;

public class WeiCall_CallTabUI extends TabActivity implements
OnCheckedChangeListener{
	private RadioGroup mainTab;
	private RadioButton rbPhoneContact;
	private RadioButton rbFriend;
	private TabHost mTabHost;
	// 內容Intent
	private Intent mChatIntent;
	private Intent mContactsIntent;
	private MyApplication application;
	private final static String TAB_TAG_CURRENT_CHAT = "tab_tag_chat";
	private final static String TAB_TAG_CONTACTS = "tab_tag_contacts";
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.weicall_call_menu);
		mainTab = (RadioGroup) findViewById(R.id.main_tab);
		mainTab.setOnCheckedChangeListener(this);
		application=(MyApplication) getApplication();
		rbFriend = (RadioButton) findViewById(R.id.radio_button1);
		rbPhoneContact = (RadioButton) findViewById(R.id.radio_button2);
		prepareIntent();
		setupIntent();
	}

	/**
	 * 準備tab的內容Intent
	 */
	private void prepareIntent() {
		mChatIntent = new Intent(this, AllConacts.class);
		mContactsIntent = new Intent(this, MissContacts.class);
	}
	
	/**
	 * 
	 */
	private void setupIntent() {
		this.mTabHost = getTabHost();
		TabHost localTabHost = this.mTabHost;
		localTabHost.addTab(buildTabSpec(TAB_TAG_CURRENT_CHAT,
				"所有電話", R.drawable.icon,
				mChatIntent));
		localTabHost.addTab(buildTabSpec(TAB_TAG_CONTACTS,
				"未接電話", R.drawable.icon,
				mContactsIntent));
	}
	
	/**
	 * 構建TabHost的Tab頁
	 * 
	 * @param tag
	 *            標記
	 * @param resLabel
	 *            標籤
	 * @param resIcon
	 *            圖標
	 * @param content
	 *            該tab展示的內容
	 * @return 一個tab
	 */
	private TabHost.TabSpec buildTabSpec(String tag, String lable, int resIcon,
			final Intent content) {
		return this.mTabHost.newTabSpec(tag)
				.setIndicator(lable, getResources().getDrawable(resIcon))
				.setContent(content);
	}
	
	@Override
	public void onCheckedChanged(RadioGroup group, int checkedId) {
		switch (checkedId) {
		case R.id.radio_button1:
			rbFriend.setTextColor(Color.WHITE);
			rbPhoneContact.setTextColor(Color.GRAY);
			this.mTabHost.setCurrentTabByTag(TAB_TAG_CURRENT_CHAT);
		    
			break;
		case R.id.radio_button2:
			rbFriend.setTextColor(Color.GRAY);
			rbPhoneContact.setTextColor(Color.WHITE);
			this.mTabHost.setCurrentTabByTag(TAB_TAG_CONTACTS);
			break;

		}
	}
	

}

 

接下是觀察者之一的所有撥打電話記錄 這裏重點看其中的update方法

package bsn.report.person;

import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.widget.Adapter;
/**
 * 撥打聯繫人歷史記錄
 * 觀察者 
 * @author Administrator
 *
 */
public class AllConacts extends Activity implements Observer{
    private List<PhoneContact>phoneContacts= new ArrayList<PhoneContact>();
    private ProgressDialog dialog;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.allcontact);
		dialog=new ProgressDialog(this);
		ContactsHistoryObserver observer=new ContactsHistoryObserver(this);
	}

	@Override
	public void update(Observable observable, Object data) {
          ContactsHistoryObserver observer=(ContactsHistoryObserver) observable;
          System.out.println(  "  observer.FINDBL;"+observer.FINDBL);
      	if (observer.FINDBL==false) {
			if (dialog!=null) {
				dialog.show();
			}
		}else{
			//請注意這裏就得到了我們應該得到的數據。。。直接在adapter中顯示出來就行。
			ContactsHistoryObserver.getAllData();
			dialog.cancel();
		}
       
		
	}

}

觀察者2:未接電話

package bsn.report.person;

import java.util.Observable;
import java.util.Observer;

import android.app.Activity;
import android.os.Bundle;
/**
 * 未接電話的類
 * 觀察者之1
 * 這裏可以仿照AllConacts
 * 只是一個測試所以沒有寫出來
 * @author Administrator
 *
 */
public class MissContacts  extends Activity implements Observer{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.misscontact);
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		// TODO Auto-generated method stub
		
	}
	

}

 

最好把domain的類也放進來吧


package bsn.report.person;


public class PhoneContact {
	private String name;
	private long id;
	private long phone_time;
	private int phone_type; 
	
	/////////////////////////////////////
	

	private String lookupKey;

	public long getPhone_time() {
		return phone_time;
	}

	public void setPhone_time(long phone_time) {
		this.phone_time = phone_time;
	}

	public int getPhone_type() {
		return phone_type;
	}

	public void setPhone_type(int phone_type) {
		this.phone_type = phone_type;
	}

	public String getLookupKey() {
		return lookupKey;
	}

	public void setLookupKey(String lookupKey) {
		this.lookupKey = lookupKey;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
    

	//增加一個比較兩個對象的整數值
    private int temp=2;
    
	public int getTemp() {
		return temp;
	}

	public void setTemp(int temp) {
		this.temp = temp;
	}


	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PhoneContact other = (PhoneContact) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}




	 
}


 

package bsn.report.person;


public class PhoneContact {
	private String name;
	private long id;
	private long phone_time;
	private int phone_type; 
	
	/////////////////////////////////////
	

	private String lookupKey;

	public long getPhone_time() {
		return phone_time;
	}

	public void setPhone_time(long phone_time) {
		this.phone_time = phone_time;
	}

	public int getPhone_type() {
		return phone_type;
	}

	public void setPhone_type(int phone_type) {
		this.phone_type = phone_type;
	}

	public String getLookupKey() {
		return lookupKey;
	}

	public void setLookupKey(String lookupKey) {
		this.lookupKey = lookupKey;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}
    

	//增加一個比較兩個對象的整數值
    private int temp=2;
    
	public int getTemp() {
		return temp;
	}

	public void setTemp(int temp) {
		this.temp = temp;
	}


	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		PhoneContact other = (PhoneContact) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}




	 
}


 

 

 好了到這裏觀察者模式在android中的應用寫完了。大神勿噴。

寫這些文章的目的是給自己學習記錄,如果能對你起到幫助那是我的榮幸,如果你覺得文章寫的不正確,請回復。。。。

如果文章看着讓你不爽了請直接alt+F4。。。如果你覺得還不錯請收藏。以後的文章會寫到其他設計模式。

 


 

 


 

 

 

 


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章