• 常用工具类总结


    项目中常会遇到的工具类 总结留存

    首先Activity的抽象类 BaseActivity

    /**
     * Activity 基類
     * @author KrisLight
     *
     */
    public abstract class BaseActivity extends Activity {
    	
    	private static final String TAG = BaseActivity.class.getSimpleName(); 
    	/**
    	 * 消息類型默認Default
    	 */
    	public static int MSGTYPE_DEFAULT = 0;
    	/**
    	 * 消息類型為Info
    	 */
    	public static int MSGTYPE_INFO = 1;
    	/**
    	 * 消息類型為Warning
    	 */
    	public static int MSGTYPE_WARNING = 2;
    	/**
    	 * 消息類型為Error
    	 */
    	public static int MSGTYPE_ERROR = 3;
    	
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    	}
    	
    	/**初始化**/
    	protected abstract void init();
    	
    	/** 初始化監聽器**/
    	protected abstract void initListener();
    	
    	/**  得到字符串資源 **/
    	public String getResStr(int id)
    	{
    		return this.getResources().getString(id);
    	}
    
    	/** 短暂显示Toast提示(来自res) **/
    	protected void showShortToast(int resId) {
    		Toast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show();
    	}
    
    	/** 短暂显示Toast提示(来自String) **/
    	protected void showShortToast(String text) {
    		Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    	}
    
    	/** 长时间显示Toast提示(来自res) **/
    	protected void showLongToast(int resId) {
    		Toast.makeText(this, getString(resId), Toast.LENGTH_LONG).show();
    	}
    
    	/** 长时间显示Toast提示(来自String) **/
    	protected void showLongToast(String text) {
    		Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    	}
    
    	/** Debug输出Log日志 **/
    	protected void showLogDebug(String tag, String msg) {
    		Log.d(tag, msg);
    	}
    
    	/** Error输出Log日志 **/
    	protected void showLogError(String tag, String msg) {
    		Log.e(tag, msg);
    	}
    
    	/** 通过Class跳转界面 **/
    	protected void startActivity(Class<?> cls) {
    		startActivity(cls, null);
    	}
    
    	/** 含有Bundle通过Class跳转界面 **/
    	protected void startActivity(Class<?> cls, Bundle bundle) {
    		Intent intent = new Intent();
    		intent.setClass(this, cls);
    		if (bundle != null) {
    			intent.putExtras(bundle);
    		}
    		if(intent.resolveActivity(getPackageManager()) != null){
    	     	startActivity(intent);
    		}else{
    			showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
    		}
    		overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    	}
    
    	/** 通过Action跳转界面 **/
    	protected void startActivity(String action) {
    		Intent intent = new Intent();
    		intent.setAction(action);
    		if(intent.resolveActivity(getPackageManager()) != null){
    	     	startActivity(intent);
    		}else{
    			showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
    		}
    	}
    	
    	/**含有Date通过Action跳转界面**/
    	protected void startActivity(String action,Uri data) {
    		Intent intent = new Intent();
    		intent.setAction(action);
    		intent.setData(data);
    		if(intent.resolveActivity(getPackageManager()) != null){
    	     	startActivity(intent);
    		}else{
    			showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
    		}
    	}
    
    	/** 含有Bundle通过Action跳转界面 **/
    	protected void startActivity(String action, Bundle bundle) {
    		Intent intent = new Intent();
    		intent.setAction(action);
    		if (bundle != null) {
    			intent.putExtras(bundle);
    		}
    		if(intent.resolveActivity(getPackageManager()) != null){
    	     	startActivity(intent);
    		}else{
    			showLogError(TAG, "there is no activity can handle this intent: "+intent.getAction().toString());
    		}
    		overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    	}
    
    
    	/** 含有标题、内容、两个按钮的对话框 **/
    	protected void showAlertDialog(String title, String message,
    			String positiveText,
    			DialogInterface.OnClickListener onPositiveClickListener,
    			String negativeText,
    			DialogInterface.OnClickListener onNegativeClickListener) {
    		    AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(title)
    				.setMessage(message)
    				.setPositiveButton(positiveText, onPositiveClickListener)
    				.setNegativeButton(negativeText, onNegativeClickListener).create();
    		    alertDialog.show();
    	}
    
    	/** 含有标题、内容、图标、两个按钮的对话框 **/
    	protected void showAlertDialog(String title, String message,
    			int icon, String positiveText,
    			DialogInterface.OnClickListener onPositiveClickListener,
    			String negativeText,
    			DialogInterface.OnClickListener onNegativeClickListener) {
    		AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(title)
    				.setMessage(message).setIcon(icon)
    				.setPositiveButton(positiveText, onPositiveClickListener)
    				.setNegativeButton(negativeText, onNegativeClickListener).create();
    		alertDialog.show();
    	}
    	
    	
    	/**
    	 * 
    	 * @Function: com.light.mycal.base.BaseActivity
    	 * @Description:根據不同的信息類型彈出不同等級的對話框
    	 *
    	 * @param i  資源id
    	 * @param iMsgType 信息類型
    	 *
    	 * @version:v1.0
    	 * @author:KrisLight
    	 * @date:2013/9/4 下午4:56:39
    	 *
    	 * Modification History:
    	 * Date         Author      Version     Description
    	 * -----------------------------------------------------------------
    	 * 2013/9/4    KrisLight      v1.0.0         create
    	 */
    	public void ShowMsgResStr(int i, int iMsgType)
    	{
    		String sTitle = getResStr(R.string.app_name);
    		int iconId = 0;
    		if (iMsgType == MSGTYPE_INFO)
    		{
    			sTitle = getResStr(R.string.msgTypeInfo);
    			iconId = R.drawable.msgicon_info;
    		}
    		if (iMsgType == MSGTYPE_WARNING)
    		{
    			sTitle = getResStr(R.string.msgTypeWarning);
    			iconId = R.drawable.msgicon_warning;
    		}
    		if (iMsgType == MSGTYPE_ERROR)
    		{
    			sTitle = getResStr(R.string.msgTypeError);
    			iconId = R.drawable.msgicon_error;
    		}					
    		AlertDialog.Builder dlg = new AlertDialog.Builder(this);		
    		dlg.setMessage(getResStr(i));
    		dlg.setPositiveButton(getResStr(R.string.msgBoxButtonOk), null);		
    		dlg.setTitle(sTitle);		
    		dlg.setIcon(iconId);		
    		dlg.create();
    		dlg.show();
    	}
    
    	/** 带有右进右出动画的退出 **/
    	public void finish() {
    		super.finish();
    		overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
    	}
    
    	/** 默认退出 **/
    	protected void defaultFinish() {
    		super.finish();
    	}
    }
    


    配置文件工具Prefs

    public class Prefs {
    	
    	/** Friend+'s Preference file name */
    	public static final String PREF_FILE = "friends_plus_pref";
    	
    	/** Preference key[authToken] */
    	public static final String KEY_AUTH_TOKEN = "auth_token";
    	
    	/** Preference key[clientId] */
    	public static final String KEY_CLIENT_ID = "client_id";
    	
    	/** Preference key[login_email] */
    	public static final String KEY_LOGIN_EMAIL = "login_email";
    	
    	/** Preference key[login_IMId] */
    	public static final String KEY_LOGIN_IMID = "login_imid";
    	
    	/** Preference key[login_name] */
    	public static final String KEY_LOGIN_NAME = "login_name";
    	
    	/** Preference key[last_update_contact_list] */
    	public static final String KEY_LAST_UPDATE_CONTACT_LIST = "last_update_contact_list";
    	
    	public static final String KEY_REGISTRATION_STEP = "registration_step";
    	
    	public static final String REGISTRATION_STEP_AUTHENTICATE = "authenticate";
    	public static final String KEY_REGISTRATION_AUTHEN_CODE = "authen_code";
    	
    	/**
    	 * get the app's preference data
    	 * 
    	 * @param context
    	 * @param prefKey preference key
    	 * @return
    	 */
    	public static String getPreference(Context context, String prefKey) {
    		return getPreference(context, prefKey, "");
    	}
    	
    	/**
    	 * get the app's preference data
    	 * 
    	 * @param context
    	 * @param prefKey preference key
    	 * @param defVal default value
    	 * @return
    	 */
    	public static String getPreference(Context context, String prefKey, String defVal) {
    		if (TextUtils.isEmpty(prefKey))
    			return null;
    
    		SharedPreferences prefs = 
    				context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
    		return prefs.getString(prefKey, defVal);
    	}
    
    	/**
    	 * write data to app's preference
    	 * 
    	 * @param context
    	 * @param prefKey
    	 * @param prefValue
    	 */
    	public static void savePreference(Context context, String prefKey, String prefValue) {
    		if (TextUtils.isEmpty(prefKey))
    			return;
    		SharedPreferences.Editor editor = 
    				context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE).edit();
    		editor.putString(prefKey, prefValue).commit();
    	}
    	
    	/**
    	 * remove preference value from app's preference file
    	 * @param context
    	 * @param prefKey
    	 */
    	public static void removePreference(Context context, String prefKey){
    		if (TextUtils.isEmpty(prefKey))
    			return;
    		SharedPreferences.Editor editor =
    				context.getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE).edit();
    		editor.remove(prefKey).commit();
    	}
    	
    }
    


    DBHelper类

    /**
     * DB工具類
     * @author KrisLight
     *
     */
    public class DatabaseOpenHelper extends SQLiteOpenHelper
    {
    	
    	private static final String TAG = DatabaseOpenHelper.class.getSimpleName();
    	/** 數據庫操作結果 **/
    	public enum Result
    	{
    		/** 成功 **/
    		Success,
    		/**未知錯誤**/
    		errUnknown,
    		/**無法插入新數據**/
    		errCantInsertNewData, 
    		/**無法更新數據**/
    		errCantUpdateData, 
    		/**無法創建Table**/
    		errCantCreateTable, 
    		/**無法訪問數據庫**/
    		errNoDbAccess,
    		/**無法從表中獲取數據**/
    		errCantGetDataFromTable,	
    		/**無法查到數據**/
    		errCantFindData,
    		/**無法得到數據**/
    		errCantGetData,	
    		/**無法刪除數據**/
    		errCantDeleteData,
    		/**表不存在**/
    		errTableNotExists,
    		/**不能為該字段指定值**/
    		errCantSetValuesForDataRow,
    		/**不能從該字段得到值**/
    		errCantGetValuesFromDataRow,
    	};
    		
    	/** 表名 **/
    	public static final String TABLE_NAME = "appointments";
    	/** 臨時表名 **/
    	public static final String TEMP_TABLE_NAME = "tempDb";
      
    	/** 數據庫名 **/
    	private static final String DB_NAME = "MyCal.db";
    	private SQLiteDatabase db = null;
    	/** 版本号 **/
    	private static final int DB_VERSION = 1;
    	/**創建Table的結果**/
    	private Result resultDbTablesCreated = Result.errUnknown;	
    	
    	public DatabaseOpenHelper(Context context, String name, CursorFactory factory,
    			int version) {
    		super(context, DB_NAME, factory, DB_VERSION);
    	}
    	
    	@Override
    	public void onCreate(SQLiteDatabase sqLiteDatabase) {
    		DataRow nDataRow = new NoteDataRow();
    		String create_sql = getSqlTableDefinition(nDataRow.GetTableName(), nDataRow.GetTableDef());
    		Log.d(TAG, "create_sql: ---------------------"+create_sql+ "------------");
    		try{
    		  sqLiteDatabase.execSQL(create_sql);
    		  resultDbTablesCreated = DatabaseOpenHelper.Result.Success;				
    		}catch (Exception e) {
    	      resultDbTablesCreated = DatabaseOpenHelper.Result.errCantCreateTable;	
    		}
    		
    	}
    	
    	/**
    	 * 得到創建表的SQL語句
    	 * @param sTableName 表名
    	 * @param vecTableDef 表的字段數組
    	 * @return
    	 */
    	public String getSqlTableDefinition(String sTableName, DataField[] vecTableDef)
    	{
    		String def = "CREATE TABLE " + sTableName + " (";
    		for (int i = 0; i < vecTableDef.length; i++)
    		{
    			def += vecTableDef[i].GetColumnDefinition();
    			if (i < (vecTableDef.length - 1))
    				//中間逗號分隔
    				def += ", ";
    		}	
    		def += ")";
    		return def;
    	}
    	
    	
    	/* (non-Javadoc)
    	 * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
    	 */
    	@Override
    	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    		switch (newVersion) {
    		  case 2:
    			/** only add column on old table**/
    //			String add_column_sql = getSqlTableAddColumn(TABLE_NAME,newColumn);
    //			Log.d(TAG, "add_column_sql:--------------"+add_column_sql+"----------");
    //			db.execSQL(add_column_sql);
    //			break;
              case 3:
            	  //原來的字段集合
        		  List<String> columns = getColumns(db, TABLE_NAME);
        		  String rename_sql = getSqlTableRename(TABLE_NAME);
        		  Log.d(TAG, "rename_sql:--------------"+rename_sql+"----------");
        		  //重命名
        		  db.execSQL(rename_sql);
        		  //創建新表
        		  onCreate(db);
        		  //舊字段和新的字段求交集
        		  columns.retainAll(getColumns(db, TABLE_NAME));
        		  String cols = Utils.join(columns, ",");
        		  //將舊的數據插入到新表 
        		  db.execSQL(String.format( "INSERT INTO %s (%s) SELECT %s from temp_%s", TABLE_NAME, cols, cols, TABLE_NAME));
        		  String drop_sql = getSqlTableDrop(TEMP_TABLE_NAME);
        		  Log.d(TAG, "drop_sql:--------------"+drop_sql+"----------");
        		  db.execSQL(drop_sql);
    			break;
    		  default:
    			  String ds = getSqlTableDrop(TABLE_NAME);
    			  Log.d(TAG, "drop_sql:--------------"+ds+"----------");
    		    break;
    		}
    		  
    
    	}
    	
    	/**
    	 *  得到重命名SQL
    	 */
    	private String getSqlTableRename(String tableName){
    		  StringBuffer sb = new StringBuffer();
    		  sb.append("ALTER TABLE ");
    		  sb.append(tableName);
    		  sb.append(" RENAME TO temp_");
    		  sb.append(tableName);
    		  return sb.toString();
    	}
    	
    	/**
    	 *  得到刪除表SQL
    	 */
    	private String getSqlTableDrop(String tableName){
    		  StringBuffer sb = new StringBuffer();
    		  sb.append("DROP TABLE IF EXISTS ");
    		  sb.append(tableName);
    		  return sb.toString();
    	}
    	
    	/**
    	 *  得到新增字段的表SQL
    	 */
    	private String getSqlTableAddColumn(String tableName,String columnName){
    		  StringBuffer sb = new StringBuffer();
    		  sb.append("ALTER TABLE ");
    		  sb.append(tableName);
    		  sb.append(" ADD COLUMN ");
    		  sb.append(columnName);
    		  return sb.toString();
    	}
    	
    	/**
    	 *  得到這個Table中的所有字段組成的List集合
    	 */
    	public static List<String> getColumns(SQLiteDatabase db, String tableName) {
    	    List<String> ar = null;
    	    Cursor c = null;
    	    try {
    	    	//查一條數據得到所有字段
    	        c = db.rawQuery("select * from " + tableName + " limit 1", null);
    	        if (c != null) {
    	            ar = new ArrayList<String>(Arrays.asList(c.getColumnNames()));
    	        }
    	    } catch (Exception e) {
    	        e.printStackTrace();
    	    } finally {
    	        if (c != null)
    	            c.close();
    	    }
    	    return ar;
    	}
    
    	
    	/**
    	 *  得到數據庫的名字
    	 * 
    	 */
    	public final String getName()
    	{
    		return DB_NAME;
    	}
    
    	/** 得到錯誤信息描述 **/
    	public static int getErrDesc(Result result)
    	{
    		int msgId = R.string.errUnknown;
    		if (result == Result.errCantInsertNewData)
    			msgId = R.string.errCantInsertNewData;
    		if (result == Result.errCantUpdateData)
    			msgId = R.string.errCantUpdateData;
    		if (result == Result.errCantCreateTable)
    			msgId = R.string.errCantCreateTable;
    		if (result == Result.errNoDbAccess)
    			msgId = R.string.errNoDbAccess;
    		if (result == Result.errCantGetDataFromTable)
    			msgId = R.string.errCantGetDataFromTable;
    		if (result == Result.errCantFindData)
    			msgId = R.string.errCantFindData;
    		if (result == Result.errCantGetData)
    			msgId = R.string.errCantGetData;
    		if (result == Result.errCantDeleteData)
    			msgId = R.string.errCantDeleteData;
    		if (result == Result.errTableNotExists)
    			msgId = R.string.errTableNotExists;
    		if (result == Result.errCantSetValuesForDataRow)
    			msgId = R.string.errCantSetValuesForDataRow;
    		if (result == Result.errCantGetValuesFromDataRow)
    			msgId = R.string.errCantGetValuesFromDataRow;					
    		return msgId;
    	}
    		
    	/**關閉DB**/
    	public void close()
    	{
    		if (isOpened())
    			db.close();
    	}
    	
    	/**判斷DB是否打開**/
    	public boolean isOpened()
    	{
    		if (db != null)
    			return true;
    		return false;
    	}
    	
    	/**得到DB寫操作類 **/
    	public SQLiteDatabase getWriteSQLiteDb()
    	{
    		return getWritableDatabase();
    	}
    	
    	/**得到DB讀操作類 **/
    	public SQLiteDatabase getReadSQLiteDb()
    	{
    		return getReadableDatabase();
    	}
    	
    	/**查詢Table是否存在**/
    	public boolean isTableExists(String sTableName)
    	{
    		boolean bResult = false;
    		if (isOpened())
    		{
    			String sql = "select name from sqlite_master where type = 'table' and name = '%s'";		
    			sql = String.format(sql, sTableName);			
    			Cursor cr = db.rawQuery(sql, null);						
    			if (cr.getCount() > 0)
    				bResult = true;
    			cr.close();
    		}
    		return bResult;
    	}
    	
    	
    	/** 建表是否成功 **/
    	public boolean TablesCreated()
    	{
    		return resultDbTablesCreated == Result.Success;		
    	}
    
    	/** 判斷DB是否準備好了**/
    	public synchronized boolean DatabaseReady()
    	{
    		return (isOpened() && TablesCreated());
    	}
    	
    	/** 返回創建表的結果 是成功還是失敗 **/
    	public Result TablesCreationResult()
    	{
    		return resultDbTablesCreated;				
    	}
    
    			
    }
    


    表中字段类DataField

    /**
     *  表中的字段類
     * @author KrisLight
     */
    public class DataField
    {
    	//types 
    	/** Type枚举 如:INT,TEXT,BOOL**/
    	public static enum Type { INT, TEXT, BOOL };
    
    	//fields 
    	/** Calendar實例 **/
    	private Calendar dateOut = Calendar.getInstance();
    	
    	//fields 
    	/** 對應的數據類型 **/
    	private DataRow dataRow = null;
    	/** 對應字段的值 **/
    	private ContentValues values = null;
    	
    	//fields
    	/**字段索引**/
    	private int index = 0;
    	/** ContentValues存放鍵值對的鍵值 **/
    	private String sName = "";
    	/** 字段类型 从Type枚举中取一个类型的值 默認為Int **/
    	private Type FieldType = Type.INT;
    	/**是否可以為空**/
    	private boolean bCanBeNull = true;
    	/**是否是主鍵**/
    	private boolean bPrimaryKey = false;
    	
    	
    	//methods
    	/**
    	 * 构造方法 
    	 * @param index 索引
    	 * @param sName 字段名
    	 * @param FieldType 字段类型
    	 * @param bCanBeNull 是否为空
    	 * @param bPrimaryKey 是否为主键
    	 */
    	public DataField(int index, String sName, Type FieldType, boolean bCanBeNull, boolean bPrimaryKey)
    	{
    		this.index = index;
    		this.sName = sName;
    		this.FieldType = FieldType;
    		this.bCanBeNull = bCanBeNull;
    		this.bPrimaryKey = bPrimaryKey;
    	}
    	
    	/**
    	 * 得到每一個字段描述 形如: "name int PRIMARY KEY Not Null"
    	 * @return
    	 */
    	public String GetColumnDefinition()
    	{
    		String s = sName + " " + GetSqlType(FieldType);
    		if (bPrimaryKey)
    			s += " PRIMARY KEY";
    		if (!bCanBeNull)
    			s += " NOT NULL";
    		return s;
    	}
    	
    	public Type GetType()
    	{
    		return FieldType;
    	}
    	
    	public int GetIndex()
    	{
    		return index;
    	}
    	
    	/** 根據SqlType返回真實的類型字段 注意BOOL對應的是Integer 其他類型的用Text **/
    	public String GetSqlType(Type value)
    	{
    		switch (value)
    		{
    			case INT: return "INTEGER";
    			case TEXT: return "TEXT";
    			case BOOL: return "INTEGER";
    		}
    		return "TEXT";
    	}
    	
    	/** 设置这个字段对应的数据类型 **/
    	public void SetParentRow(DataRow dataRow)
    	{
    		this.dataRow = dataRow;
    		this.values = this.dataRow.GetContentValues();
    	}
    	
    	/** 得到字段的名字 **/
    	public String GetName()
    	{
    		return sName;
    	}
    	
    	//getters
    	/** 字符串类型的字段的值 **/
    	public String asString()
    	{
    		return values.getAsString(sName);
    	}
    	
    	/** Long类型的字段的值 **/
    	public long asLong()
    	{
    		return values.getAsLong(sName);
    	}
    	
    	/** Boolean类型的字段的值 **/
    	public boolean asBoolean()
    	{
    		return (values.getAsLong(sName) == 1);
    	}
    	
    	/** 判断是否为Null **/
    	public boolean isNull()
    	{
    		return (values.get(sName) == null);		
    	}
    	
    	/** 将Long类型的日期类型转换成标准的日期时间 **/
    	public Calendar asCalendar()
    	{
    		dateOut.setTimeInMillis(values.getAsLong(sName));
    		return dateOut; 
    	}
    
    	//setters
    	/** 设置字符串值 **/
    	public void set(String value)
    	{	
    		values.put(sName, value);
    	}
    	
    	/** 设置整型值 **/
    	public void set(long value)
    	{		
    		values.put(sName, value);
    	}	
    
    	/** 设置布尔值 **/
    	public void set(boolean value)
    	{
    		int i = (value)?1:0;
    		values.put(sName, i);		
    	}	
    
    	/** 设置日期值 **/
    	public void set(Calendar value)
    	{
    		values.put(sName, value.getTimeInMillis());
    	}
    
    	/** 设置Null值 **/
    	public void setNull()
    	{
    		values.put(sName, (String)null);
    	}
    	
    }
    


    数据原型类DataRow

    /**
     * 抽象的数据类型类,
     * 所有的数据原型都要继承这个类
     * @author KrisLight
     *
     */
    public abstract class DataRow
    {
    	/** 这个类型对应表中的字段集合 **/
    	private DataField[] vecTableDef = null;
    	/** 这个类型对应表中的字段的值 用ContentValues形式存放 **/
    	private ContentValues values = new ContentValues();
    	/** 構造方法 **/
    	public DataRow(){}
    		
    	/**
    	 * 設置字段集合并綁定
    	 * @param vecTableDef 字段集合
    	 */
    	public void SetTableDefinition(DataField[] vecTableDef)
    	{
    		this.vecTableDef = vecTableDef;		
    		UpdateDataFieldsParentRow(this);
    	}
    	
    	/** 將數據類型綁定其對應的所有字段 **/
    	public void UpdateDataFieldsParentRow(DataRow row)
    	{
    		for (int i = 0; i < vecTableDef.length; i++)
    			vecTableDef[i].SetParentRow(row);
    	}
    	
    	/** 拷貝另一個DataRow中的所有字段 **/
    	public void CopyTableDefinition(DataRow data)
    	{		
    		SetTableDefinition(data.vecTableDef);		
    	}
    	
    	/** 得到表中的所有字段 **/
    	public DataField[] GetTableDef()
    	{
    		return vecTableDef;
    	}
    	
    	/** 驗證方法 **/
    	public boolean Validate()
    	{
    		return false;
    	}
    	
    	/** 清空ContentValues **/
    	public void ClearContentValues()
    	{
    		values.clear();
    	}
    	
    	/** 得到ContentValues **/
    	public ContentValues GetContentValues()
    	{
    		return values;
    	}
    
    	/** 設置ContentValues **/
    	public void SetContentValues(ContentValues values)
    	{
    		this.values = values;
    		UpdateDataFieldsParentRow(this);
    	}
    	
    	/** 拷貝ContentValues **/
    	public boolean CopyContentValues(ContentValues values)
    	{
    		this.values = values;
    		UpdateDataFieldsParentRow(this);
    		try
    		{
    			GetValuesFromDataRow();
    			return true;
    		} catch (Exception e) {
    		}					
    		return false;
    	}
    	
    	/** 根據索引取出字段 **/
    	public DataField Value(int idx)
    	{
    		return vecTableDef[idx];
    	}
    	
    	/** 得到索引位置的字段名 **/
    	public String fieldName(int idx)
    	{
    		return vecTableDef[idx].GetName();	
    	}	
    	
    	/** 查詢結果 遍歷Cursor結果集給對應的字段賦值 **/
    	public boolean GetValuesFromCursor(Cursor cr)
    	{
    		if ((cr != null) && (cr.getPosition() != -1))
    		{
    			//遍歷
    			for (int idx = 0; idx < vecTableDef.length; idx++)
    			{
    				DataField field = Value(idx);
    				//check if null value
    				if (cr.isNull(idx))
    				{
    					//如果查出的值為空 ,設置為空
    					field.setNull();
    				} else {
    				//根據其對應的類型取值
    					final DataField.Type t = field.GetType();
    					//parse value by type
    					if (t == DataField.Type.INT)
    						field.set(cr.getLong(idx));
    					if (t == DataField.Type.TEXT)
    						field.set(cr.getString(idx));
    					if (t == DataField.Type.BOOL)
    						field.set((cr.getInt(idx) == 1)?true:false);
    				}				
    			}
    			return true;
    		}
    		return false;
    	}
    	
    	//sets fields values data (ContentValues values contener) from parent object fields
    	/** 為字段賦值 **/
    	public abstract void SetValuesForDataRow();
    
    	//gets data from fields values (ContentValues values contener) to parent object fields
    	/** 得到這個數據類型對應的所有的字段的值 **/
    	public abstract void GetValuesFromDataRow();
    
    	/** 得到表名 **/
    	public abstract String GetTableName();	
    	
    }
    

    Table类

    /**
     * 數據庫中的表類 包含了该表对应的数据类型以及对表的增删改查操作方法
     * @author KrisLight
     */
    public class DataTable
    {
    	/** 這個表綁定的數據類型 **/
    	private DataRow dataRow = null;
    	/** DB輔助類 **/
    	private DatabaseOpenHelper helper;
    
    	/**
    	 * 更據DataRow來決定是哪一個Table
    	 * @param dataRow
    	 */
    	public DataTable(DataRow dataRow,DatabaseOpenHelper helper)
    	{
    		this.dataRow = dataRow;
    		this.helper = helper;
    	}
    	
    	/** 得到表名 **/
    	public String getTableName()
    	{
    		return dataRow.GetTableName();
    	}
    	
    	//DataRow getter()
    	public DataRow getDataRow()
    	{
    		return dataRow;
    	}
    				
    	/** 基本的插入操作 **/
    	public long insertValues()
    	{
    		long lRowId = helper.getWritableDatabase().insert(getTableName(), null, dataRow.GetContentValues());
            return lRowId; 
    	}
    	
    	/** 基本的根據ID更新操作 **/
    	public long updateValues(long lRowId)
    	{
    		String sWhere = String.format("_ID = %d", lRowId);
    		long lRowsUpdated = helper.getWritableDatabase().update(getTableName(), dataRow.GetContentValues(), sWhere, null);
    		return lRowsUpdated;
    	}
      
    	/** 基本的根據ID刪除操作 **/
      public long deleteDataRow(long lRowId)
      {
    		String sWhere = String.format("_ID = %d", lRowId);
    		long lRowsUpdated = helper.getWritableDatabase().delete(getTableName(), sWhere, null);
    		return lRowsUpdated;
      }
    	
      /** 基本的根據Id查詢表中的所有字段值 **/
    	public Cursor locateDataRow(long lRowId)
    	{
    		List<String> columnNames = getColumn();
    		String cols = Utils.join(columnNames, ",");
    		final String s = "select %s from %s where _ID = %d";		
    		String sql = String.format(s, cols, getTableName(), lRowId);
    		Cursor cr = helper.getReadableDatabase().rawQuery(sql, null);
    		//if cursor valid, set first data row as current
    		if ((cr != null) && (cr.getCount() > 0))
    			cr.moveToFirst();
    		return cr;
    	}
    	
    	/** 基本的根據類型和REF_ID查詢鬧鈴提醒功能表的所有字段數據 **/
    	public Cursor locateAlarmDataRow(int iType, long lRefID)
    	{
    		List<String> columnNames = getColumn();
    		String cols = Utils.join(columnNames, ",");
    		final String s = "select %s from %s where Type = %d and RefID = %d";		
    		String sql = String.format(s, cols, getTableName(), iType, lRefID);
    		Cursor cr = helper.getReadableDatabase().rawQuery(sql, null);
    		if ((cr != null) && (cr.getCount() > 0))
    			cr.moveToFirst();
    		return cr;
    	}	
    	
    	/**
    	 * 封装的saveOrUpdate操作
    	 * @param bInsertMode  是否是插入模式 為true的話是插入新的數據 為false則直接更新舊數據
    	 * @param lEditRowId   ID
    	 * @return
    	 */
    	public DatabaseOpenHelper.Result updateData(boolean bInsertMode, long lEditRowId)
    	{
    		DatabaseOpenHelper.Result result = DatabaseOpenHelper.Result.errUnknown;
    		if (helper.isOpened())
    		{			
    			try
    			{
    				//為字段賦值
    				dataRow.SetValuesForDataRow();
    			} catch (Exception e) {
    				//異常就拋出錯誤信息 不能為數據類型的字段賦值
    				return DatabaseOpenHelper.Result.errCantSetValuesForDataRow;					
    			}
    			//select update mode
    			if (bInsertMode)
    			{
    				//insert new data row
    				long lRowId = insertValues();
    				if (lRowId > 0)
    				{
    					//插入成功
    					result = DatabaseOpenHelper.Result.Success;
    				} else {
    					//插入失敗
    					result = DatabaseOpenHelper.Result.errCantInsertNewData;
    				}
    			} else {
    				//update existing data row
    				long lRowsUpdated = updateValues(lEditRowId);
    				if (lRowsUpdated == 1)
    				{
    					//更新成功
    					result = DatabaseOpenHelper.Result.Success;
    				} else {
    					//更新失敗
    					result = DatabaseOpenHelper.Result.errCantUpdateData;
    				}									
    			}
    		} else {		
    			result = DatabaseOpenHelper.Result.errNoDbAccess;
    		}
    		return result;
    	}
    	
    	/** 封装的根據Id刪除 **/
    	public DatabaseOpenHelper.Result deleteData(long iRowId)
    	{		
    		DatabaseOpenHelper.Result result = DatabaseOpenHelper.Result.errUnknown;
    		if (helper.isOpened())
    		{			
    			if (helper.isTableExists(getTableName()))
    			{
    				long lRowsDeleted = deleteDataRow(iRowId);
    				if (lRowsDeleted == 1)
    				{
    					result = DatabaseOpenHelper.Result.Success;
    				} else {
    					result = DatabaseOpenHelper.Result.errCantDeleteData;
    				}
    			} else {
    				result = DatabaseOpenHelper.Result.errTableNotExists;
    			}
    		} else {		
    			result = DatabaseOpenHelper.Result.errNoDbAccess;
    		}
    		return result;		
    	}
    	
    	/** 封装的根據ID查詢數據 **/
      public DatabaseOpenHelper.Result getRowDataForEdit(long lRowId)
      {
      	DatabaseOpenHelper.Result result = DatabaseOpenHelper.Result.errUnknown;
    		//get requested data row
    		Cursor cr = locateDataRow(lRowId);
    		if (cr == null)
    		{
    			//如果返回為空 結果為errCantGetData
    			result = DatabaseOpenHelper.Result.errCantGetData;
    		} else {
    			if (cr.getCount() > 0)
    			{
    				if (dataRow.GetValuesFromCursor(cr))
    				{
    					try
    					{
    						dataRow.GetValuesFromDataRow();
    					} catch (Exception e) {
    						return DatabaseOpenHelper.Result.errCantGetValuesFromDataRow;					
    					}					
    					result = DatabaseOpenHelper.Result.Success;
    				} else {
    					//無法從表中取出数据
    					result = DatabaseOpenHelper.Result.errCantGetDataFromTable;	    	
    				}
    				//关闭光标
    				cr.close();
    			} else {
    				//无法找到数据
    				result = DatabaseOpenHelper.Result.errCantFindData;
    			}
    		}
    		return result;
      }
      
      
    	/** 得到這個表中的所有字段 **/
    	public List<String> getColumn() {
    	    List<String> ar = new ArrayList<String>();
    	    try {
    	    	    DataField[] fields = dataRow.GetTableDef();
    	    	    for(DataField f : fields){
    	    	    	ar.add(f.GetName());
    	    	    }
    	    } catch (Exception e) {
    	        e.printStackTrace();
    	    } 
    	    return ar;
    	}
    }
    


    安装程序类Installating

    public class Installation {
    	private static String sID = null;
        private static final String INSTALLATION = "INSTALLATION";
    
        public synchronized static String id(Context context) {
            if (sID == null) {  
                File installation = new File(context.getFilesDir(), INSTALLATION);
                try {
                    if (!installation.exists()){
                        writeInstallationFile(installation, context);
                    }
                    
                    sID = readInstallationFile(installation);
                } catch (Exception e) {
                    //throw new RuntimeException(e);
                }
            }
            return sID;
        }
    
        private static String readInstallationFile(File installation) throws IOException {
            RandomAccessFile f = new RandomAccessFile(installation, "r");
            byte[] bytes = new byte[(int) f.length()];
            f.readFully(bytes);
            f.close();
            return new String(bytes);
        }
    
        private static void writeInstallationFile(File installation, Context context) throws IOException {
        	
            FileOutputStream out = new FileOutputStream(installation);
            
            String id = "";
            
            try{
            	id = Settings.Secure.getString(context.getContentResolver(),
            	         Settings.Secure.ANDROID_ID);
            	
            	id+=id;
            	
            }catch(Exception e){
            	id = UUID.randomUUID().toString();
            }
            
            
            
            out.write(id.getBytes());
            out.close();
        }
    }


    获取资源类SearchResource

    public class SearchResource {
    	
    	public static int getDrawableResId(Context cnt, String name) throws NotFoundException {
    		int resid = 0;
    		resid = cnt.getResources().getIdentifier(name, "drawable", cnt.getPackageName());
    		if (resid == 0)
    			resid = cnt.getResources().getIdentifier( "transparent_background", "drawable", cnt.getPackageName());
    		return resid;
    	}
    
    	public static int getStringResId(Context cnt, String name) throws NotFoundException {
    		int resid = 0;
    		resid = cnt.getResources().getIdentifier(name, "string", cnt.getPackageName());
    		if (resid == 0)
    			resid = cnt.getResources().getIdentifier("empty_string", "string", cnt.getPackageName());
    		return resid;
    	}
    
    	public static int getLayoutResId(Context cnt, String name) throws NotFoundException {
    		int resid = 0;
    		resid = cnt.getResources().getIdentifier(name, "layout", cnt.getPackageName());
    		if (resid == 0)
    			resid = cnt.getResources().getIdentifier("empty_layout","layout", cnt.getPackageName());
    		return resid;
    	}
    	
    	public static int getItemResId(Context cnt, String name) throws NotFoundException {
    		int resid = cnt.getResources().getIdentifier(name, "id", cnt.getPackageName());
    		return resid;
    	}
    	
    	public static int getAnimResId(Context cnt, String name) throws NotFoundException {
    		int resid = cnt.getResources().getIdentifier(name, "anim", cnt.getPackageName());
    		return resid;
    	}
    	
    	public static int getAttrResId(Context cnt, String attrName) throws NotFoundException {
    		int resid = cnt.getResources().getIdentifier(attrName, "attr", cnt.getPackageName());
    		return resid;
    	}
    	
    	public static int getStyleResId(Context cnt, String attrName) throws NotFoundException {
    		int resid = cnt.getResources().getIdentifier(attrName, "style", cnt.getPackageName());
    		return resid;
    	}
    	
    	public static int getMenuResId(Context cnt, String name) throws NotFoundException {
    		int resid = cnt.getResources().getIdentifier(name, "menu", cnt.getPackageName());
    		return resid;
    	}
    	
    	public static int[] getStyleableArray(Context cnt, String name) {
    		return null;
    	}
    }
    


    发送短信类SendMessage

    public class SendMessage {
    	private static final String TAG = "SendMessage";
    	
    	private Context m_contect;
    	private ArrayList<HashMap<String, Object>> m_ContactList;
    	private ArrayList<HashMap<String, Object>> m_ContactListbuffer;
    
    	private String m_strMessageContent;
    	private int m_intMessageSendCount=0;
    	private int m_intMessageSendTotalParts;
    	private int m_intMessageSendParts;
    	public static final String SENT = "com.commez.psmd.SMS_SENT"; 
        public static final String DELIVERED = "com.commez.psmd.SMS_DELIVERED"; 
        
    	private ArrayList<String> m_phoneList;
    	private ListView m_ltvDialogContactList;
    	private CustomDialogAdapter m_DialogAdapter;
    	private Dialog dialog;
    	private boolean m_isSendCancel;
        private static Handler m_handler = new Handler();
    
        private BroadcastReceiver m_bcrSend;
        private BroadcastReceiver m_bcrDelivred;
    
    	public SendMessage(Context context, ArrayList<HashMap<String, Object>> contactList,  String messageContent){
    		this.m_contect = context;
    		this.m_strMessageContent = messageContent;
    		m_ContactListbuffer = new ArrayList<HashMap<String,Object>>(contactList);
    		m_isSendCancel = false;
    		fillPhoneNumber();
    	}
    	
    	public void startSendMessage(){
    		showSendingListDialog();
    		registerBroadCastReceivers();
    		m_intMessageSendCount = 0;
    		sendSMS(m_phoneList.get(m_intMessageSendCount).toString(), m_strMessageContent);		
    	}
    	
    	private void fillPhoneNumber(){
    		if(m_ContactListbuffer!=null){
    			
    			m_ContactList = new ArrayList<HashMap<String,Object>>();
    			
    			HashMap<String , Object> temp; 
    			for(int j=0; j<m_ContactListbuffer.size(); j++){
    				temp=new HashMap<String, Object>(); 
    				
    				if(m_ContactListbuffer.get(j).get("name")!=null)	
    					temp.put("name", m_ContactListbuffer.get(j).get("name").toString()); 
    				if(m_ContactListbuffer.get(j).get("number")!=null)
    					temp.put("number", m_ContactListbuffer.get(j).get("number").toString()); 
    				if(m_ContactListbuffer.get(j).get("contentid")!=null)
    					temp.put("contentid", m_ContactListbuffer.get(j).get("contentid").toString()); 
    
    				if(j==m_intMessageSendCount)
    					temp.put("sendstatus", "sending");   
    				else
    					temp.put("sendstatus", "unsend");   
    				
    				m_ContactList.add(temp);          			
    			}
    
    			m_phoneList = new ArrayList<String>();
    			
    			for(int i=0; i<m_ContactList.size(); i++){
    				m_phoneList.add(m_ContactList.get(i).get("number").toString());
    			}
    		}
    	}
    	
    	private void sendNextMessage(){
    		if(thereAreSMSToSend()){
    			
    			//m_phoneList.
    						
    			//m_DialogAdapter.notifyDataSetChanged(); 
    			/*if(m_ContactList!=null)
    				m_ContactList.clear();
    			
    			HashMap<String , Object> temp; 
    			for(int j=0; j<m_ContactListbuffer.size(); j++){
    				temp=new HashMap<String, Object>(); 
    				
    				if(m_ContactListbuffer.get(j).get("name")!=null)	
    					temp.put("name", m_ContactListbuffer.get(j).get("name").toString()); 
    				if(m_ContactListbuffer.get(j).get("number")!=null)
    					temp.put("number", m_ContactListbuffer.get(j).get("number").toString()); 
    				if(m_ContactListbuffer.get(j).get("contentid")!=null)
    					temp.put("contentid", m_ContactListbuffer.get(j).get("contentid").toString()); 
    
    				if(j<m_intMessageSendCount)
    					temp.put("sendstatus", "sent"); 
    				else if(j==m_intMessageSendCount)
    					temp.put("sendstatus", "sending"); 
    				else
    					temp.put("sendstatus", "unsend"); 
    
    				m_ContactList.add(j,temp);          			
    			}*/
    			
    			HashMap<String , Object> temp =new HashMap<String, Object>(); 
    			if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)	
    				temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString()); 
    			if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
    				temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString()); 
    			if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
    				temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString()); 
    
    			temp.put("sendstatus", "sending"); 
    			m_ContactList.set(m_intMessageSendCount,temp); 
    			
    			sendSMS(m_phoneList.get(m_intMessageSendCount).toString(), m_strMessageContent);
    			
    			m_DialogAdapter.notifyDataSetChanged(); 	
    			
    		}else{
    			Toast.makeText(m_contect, "All SMS have been sent",Toast.LENGTH_SHORT).show();
    			dialog.dismiss();
    			unRegisterBroadCastReceivers();
    			
    		}
    		}
    	
    	private void unRegisterBroadCastReceivers() {
    		m_contect.unregisterReceiver(m_bcrSend);
    		m_contect.unregisterReceiver(m_bcrDelivred);			
    	}
    	
    	private boolean thereAreSMSToSend(){
    		return m_intMessageSendCount < m_phoneList.size();
    	}
    	
    	private void sendSMS(String strPhoneNumber, String message){
    		SmsManager sms = SmsManager.getDefault();
    		ArrayList<String> parts = sms.divideMessage(message);
    		m_intMessageSendTotalParts = parts.size();
    		
    		ArrayList<PendingIntent> deliveryIntents = new ArrayList<PendingIntent>();
    		ArrayList<PendingIntent> sentIntents = new ArrayList<PendingIntent>();
    
    		PendingIntent sentPI = PendingIntent.getBroadcast(m_contect, 0, new Intent(SENT), 0);
    		PendingIntent deliveredPI = PendingIntent.getBroadcast(m_contect, 0, new Intent(DELIVERED), 0);
    		
    		for(int j=0; j<m_intMessageSendTotalParts; j++){
    			sentIntents.add(sentPI);
    			deliveryIntents.add(deliveredPI);
    		}
    		
    		m_intMessageSendParts = 0;
    		/**************************************************************/
    	/*	SystemClock.sleep(50);
    		
    		m_intMessageSendParts++;
    		if(m_intMessageSendParts == m_intMessageSendTotalParts){
    			m_intMessageSendCount++;
    			sendNextMessage();
    			m_DialogAdapter.notifyDataSetChanged(); 	
    		}
    		/******************************************************************/
    	//	sms.sendMultipartTextMessage(strPhoneNumber, null, parts, sentIntents, deliveryIntents);
    		
    		
    		//m_handler.removeCallbacks(updatTimer);
    		//m_handler.postDelayed(updatTimer, 3000);
    	}
    	
    	private Runnable updatTimer = new Runnable() {
    		public void run() {
    
    			if(m_intMessageSendCount<m_ContactList.size()){
    				
    				HashMap<String , Object> temp =new HashMap<String, Object>(); 
    				if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)	
    					temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString()); 
    				if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
    					temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString()); 
    				if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
    					temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString()); 
    
    				temp.put("sendstatus", "sent"); 
    				m_ContactList.set(m_intMessageSendCount,temp);      
    				
    				m_intMessageSendCount++;
    				sendNextMessage();
    			}
    		}
    	};
    	
    	private void registerBroadCastReceivers() {
    		
    		IntentFilter intentFilter = new IntentFilter(SENT);
    
    		m_bcrSend = new BroadcastReceiver() {
    			@Override
    			public void onReceive(Context arg0, Intent arg1) {
    				switch(getResultCode()){
    				
    				case Activity.RESULT_OK:
    					m_intMessageSendParts++;
    					if(m_intMessageSendParts == m_intMessageSendTotalParts && !m_isSendCancel){
    						
    						HashMap<String , Object> temp =new HashMap<String, Object>(); 
    						if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)	
    							temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString()); 
    						if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
    							temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString()); 
    						if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
    							temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString()); 
    
    						temp.put("sendstatus", "sent"); 
    						m_ContactList.set(m_intMessageSendCount,temp);          			
    						
    						m_intMessageSendCount++;
    						sendNextMessage();
    					}					
    					//Toast.makeText(m_contect, "SMS sent",Toast.LENGTH_SHORT).show();
    					
    					break;
             		case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
    					Toast.makeText(m_contect, "Generic failure",Toast.LENGTH_SHORT).show();
             			break; 
                 	case SmsManager.RESULT_ERROR_NO_SERVICE: 
    					Toast.makeText(m_contect, "No service",Toast.LENGTH_SHORT).show();
                	 	break; 
                 	case SmsManager.RESULT_ERROR_NULL_PDU: 
    					Toast.makeText(m_contect, "No PDU",Toast.LENGTH_SHORT).show();
                 		break; 
                 	case SmsManager.RESULT_ERROR_RADIO_OFF:
    					Toast.makeText(m_contect, "Radio off",Toast.LENGTH_SHORT).show();
                	 	break; 
    				}				
    			}	
            };
            
            m_contect.registerReceiver(m_bcrSend, intentFilter);  
            
            
    		IntentFilter intentFilter1 = new IntentFilter(DELIVERED);
    
    		m_bcrDelivred = new BroadcastReceiver() {
    			@Override
    			public void onReceive(Context arg0, Intent arg1) {
    				switch(getResultCode()){
    				
    				case Activity.RESULT_OK:
    					break;
    				case Activity.RESULT_CANCELED:
    					break;
    				}				
    			}	
    		};
            m_contect.registerReceiver(m_bcrDelivred, intentFilter1);  
    
            
    		/*m_contect.registerReceiver(new BroadcastReceiver(){
    
    			@Override
    			public void onReceive(Context arg0, Intent arg1) {
    				switch(getResultCode()){
    				
    				case Activity.RESULT_OK:
    					m_intMessageSendParts++;
    					if(m_intMessageSendParts == m_intMessageSendTotalParts && !m_isSendCancel){
    						
    						HashMap<String , Object> temp =new HashMap<String, Object>(); 
    						if(m_ContactListbuffer.get(m_intMessageSendCount).get("name")!=null)	
    							temp.put("name", m_ContactListbuffer.get(m_intMessageSendCount).get("name").toString()); 
    						if(m_ContactListbuffer.get(m_intMessageSendCount).get("number")!=null)
    							temp.put("number", m_ContactListbuffer.get(m_intMessageSendCount).get("number").toString()); 
    						if(m_ContactListbuffer.get(m_intMessageSendCount).get("contentid")!=null)
    							temp.put("contentid", m_ContactListbuffer.get(m_intMessageSendCount).get("contentid").toString()); 
    
    						temp.put("sendstatus", "sent"); 
    						m_ContactList.set(m_intMessageSendCount,temp);          			
    						
    						m_intMessageSendCount++;
    						sendNextMessage();
    					}					
    					//Toast.makeText(m_contect, "SMS sent",Toast.LENGTH_SHORT).show();
    					
    					break;
             		case SmsManager.RESULT_ERROR_GENERIC_FAILURE: 
    					Toast.makeText(m_contect, "Generic failure",Toast.LENGTH_SHORT).show();
             			break; 
                 	case SmsManager.RESULT_ERROR_NO_SERVICE: 
    					Toast.makeText(m_contect, "No service",Toast.LENGTH_SHORT).show();
                	 	break; 
                 	case SmsManager.RESULT_ERROR_NULL_PDU: 
    					Toast.makeText(m_contect, "No PDU",Toast.LENGTH_SHORT).show();
                 		break; 
                 	case SmsManager.RESULT_ERROR_RADIO_OFF:
    					Toast.makeText(m_contect, "Radio off",Toast.LENGTH_SHORT).show();
                	 	break; 
    				}				
    			}		
    		}, new IntentFilter(SENT));
    		
    		m_contect.registerReceiver(new BroadcastReceiver(){
    
    			@Override
    			public void onReceive(Context arg0, Intent arg1) {
    				switch(getResultCode()){
    				
    				case Activity.RESULT_OK:
    					break;
    				case Activity.RESULT_CANCELED:
    					break;
    				}				
    			}		
    		}, new IntentFilter(DELIVERED));	
    		
    		*/
    	}
    
    	private void showSendingListDialog() {
    		
    		LayoutInflater factory = LayoutInflater.from(m_contect);
    		View dialogView = factory.inflate(R.layout.sms_send_list, null);
    		m_ltvDialogContactList = (ListView) dialogView.findViewById(R.id.lv_sendlist);
    		setDialogAdapter();
    						
    		TextView dialogContent = (TextView) dialogView.findViewById(R.id.dialog_sendlist_content);
    		dialogContent.setText(R.string.dtl_SendList);
    		Button rightButton = (Button) dialogView.findViewById(R.id.dialog_sendlist_rightbtn);
    		rightButton.setText(R.string.dmg_SendBackground);
    		Button leftButton = (Button) dialogView.findViewById(R.id.dialog_sendlist_leftbtn);
    		leftButton.setText(R.string.dmg_SendCancel);
    		
    		
    		rightButton.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				dialog.dismiss();
    				
    			}
    		});
    			
    		leftButton.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				dialog.dismiss();
    
    			}
    		});
    		
    		dialog = new Dialog(m_contect);
    		dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		dialog.setCancelable(false);
    		dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
    		dialog.getWindow().setBackgroundDrawable(new ColorDrawable(0));
    		dialog.setContentView(dialogView);
    		dialog.show();
    				
    		/*dialog = new AlertDialog.Builder(m_contect).setTitle(R.string.dtl_SendList)
    				.setView(dialogView)
    				.setPositiveButton(R.string.dmg_SendCancel, new DialogInterface.OnClickListener() {		
    					@Override
    					public void onClick(DialogInterface dialog, int which) {
    						m_isSendCancel = true;
    						unRegisterBroadCastReceivers();
    					}})
    				.setNegativeButton(R.string.dmg_SendBackground, new DialogInterface.OnClickListener() {
    								@Override
    					public void onClick(DialogInterface dialog, int which) {
    
    					}}).create();
    		dialog.show();*/
    	}
    	
    	private void setDialogAdapter() {
    		m_DialogAdapter = new CustomDialogAdapter(m_contect, R.layout.sms_send_list_item, m_ContactList); 
    		m_ltvDialogContactList.setAdapter(m_DialogAdapter);
    	}
    	
    	private class CustomDialogAdapter extends ArrayAdapter<HashMap<String, Object>> {     
    		
    		public CustomDialogAdapter(Context context, int textViewResourceId, ArrayList<HashMap<String, Object>> Strings) {   
    			super(context, textViewResourceId, Strings);   
    		}       
    				
    		private class ViewHolder{    
    			TextView txvContact;
    			TextView txvSendStatus;
    			ProgressBar prgbSend;
    		}     
    		
    		ViewHolder viewHolder;     
    		
    		@Override  
    		public View getView(final int position, View convertView, ViewGroup parent) {      
    			
    			if(convertView==null){ 
    				LayoutInflater inflater = (LayoutInflater) m_contect.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
    				convertView = inflater.inflate(R.layout.sms_send_list_item, null); 
    				viewHolder=new ViewHolder();				
    				viewHolder.txvContact=(TextView) convertView.findViewById(R.id.txvSendlistitem_name); 
    				viewHolder.txvSendStatus=(TextView) convertView.findViewById(R.id.txvSendlistitem_status); 
    				viewHolder.prgbSend=(ProgressBar) convertView.findViewById(R.id.pb_sending); 
    			
    				convertView.setTag(viewHolder);     
    			} 
    			viewHolder=(ViewHolder) convertView.getTag();   				
    			viewHolder.txvContact.setText(m_ContactList.get(position).get("number").toString()); 
    			
    			
    			String isSend = m_ContactList.get(position).get("sendstatus").toString();
    			if(isSend=="sent"){
    				viewHolder.prgbSend.setVisibility(View.GONE);
    				viewHolder.txvSendStatus.setVisibility(View.VISIBLE);
    				viewHolder.txvSendStatus.setText(R.string.dmg_Sent);
    			}else if(isSend=="sending"){
    			viewHolder.prgbSend.setVisibility(View.VISIBLE);
    				viewHolder.txvSendStatus.setVisibility(View.GONE);
    			}else if(isSend=="unsend"){
    				viewHolder.prgbSend.setVisibility(View.GONE);
    				viewHolder.txvSendStatus.setVisibility(View.VISIBLE);
    				viewHolder.txvSendStatus.setText(R.string.dmg_SendWait);
    			}
    
    			return convertView;   
    		}    
    	} 
    	/*public static void sendMessage(Context context, String strAddress, String strMessage){
    		
    	    try {    
                 Uri smsUri = Uri.parse("tel:123456");
                 Intent intent = new Intent(Intent.ACTION_VIEW, smsUri);
                 intent.putExtra("sms_body", "");
                 intent.setType("vnd.android-dir/mms-sms"); 
     		     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
                 context.startActivity(intent);
    	    } catch (ActivityNotFoundException e) {
    
    	        Log.e(TAG, "Send SMS failed", e);
    	    }
    
    	}*/
    
    }
    

    时间字符串处理类1:

    public class C_DateUtils {
    	private static final String TAG = C_DateUtils.class.getSimpleName();
    	
    	
    	/**
    	 * check date is today
    	 * @param date
    	 * @return
    	 */
    	public static boolean isToday(Date date){
    		return isSameDate(new Date(), date);
    	}
    	
    	/**
    	 * check Date is same day
    	 * @param baseDate
    	 * @param thenDate
    	 * @return
    	 */
    	public static boolean isSameDate(Date baseDate, Date thenDate){
    		Time time = new Time();
            time.set(thenDate.getTime());
    
            int thenYear = time.year;
            int thenMonth = time.month;
            int thenMonthDay = time.monthDay;
    
            time.set(baseDate.getTime());
            return (thenYear == time.year)
                    && (thenMonth == time.month)
                    && (thenMonthDay == time.monthDay);
    	}
    	
    	/**
    	 * caculate day counts between startDate and endDate
    	 * @param startDate
    	 * @param endDate
    	 * @return
    	 */
    	public static int diffDays(Date startDate, Date endDate){
    		return (int)((endDate.getTime() - startDate.getTime()) / DateUtils.DAY_IN_MILLIS);
    	}
    	
    	/**
    	 * caculate week counts between startDate and endDate
    	 * @param startDate
    	 * @param endDate
    	 * @return
    	 */
    	public static int diffWeeks(Date startDate, Date endDate){
    		return (int)((endDate.getTime() - startDate.getTime()) / DateUtils.WEEK_IN_MILLIS);
    	}
    	
    	/**
    	 * caculate month counts between startDate and endDate
    	 * @param startDate
    	 * @param endDate
    	 * @return
    	 */
    	public static int diffMonths(Date startDate, Date endDate){
    		Time startTime = new Time();
    		startTime.set(startDate.getTime());
    		Time endTime = new Time();
    		endTime.set(endDate.getTime());
    		int diffYears = endTime.year - startTime.year;
    		
    		return diffYears * 12 + endTime.month - startTime.month;
    	}
    	
    	/**
    	 * caculate year counts between startDate and endDate
    	 * @param startDate
    	 * @param endDate
    	 * @return
    	 */
    	public static int diffYears(Date startDate, Date endDate){
    		Time startTime = new Time();
    		startTime.set(startDate.getTime());
    		Time endTime = new Time();
    		endTime.set(endDate.getTime());
    		int diffYears = endTime.year - startTime.year;
    		return diffYears;
    	}
    	
    	/**
    	 * return date is Saturday or Sunday
    	 * @param date
    	 * @return
    	 */
    	public static boolean isWeekend(Date date){
    		Time time = new Time();
    		time.set(date.getTime());
    		return (time.weekDay == Time.SATURDAY || time.weekDay == Time.SUNDAY);
    	}
    	
    }
    


    时间字符串处理类2:

    /**
     * 工具類
     * @author KrisLight
     *
     */
    public class Utils 
    {
    	/**
    	 * 透明度動畫變化持續時間
    	 */
    	public static int ANIM_ALPHA_DURATION = 100;
    	/**
    	 * 平移動畫持續時間
    	 */
    	public static int ANIM_TRANSLATE_DURATION = 30;	
    	
    	
    	/**
    	 *  周別格式   EEEE
    	 */
    	private SimpleDateFormat dateFormatWeekDay = new SimpleDateFormat("EEEE");
    	
    	/**
    	 *  月份格式    MMMM
    	 */
    	private SimpleDateFormat dateFormatMonth = new SimpleDateFormat("MMMM");
    	/**
    	 *  包括年,月,日,周的日期格式   EEEE, d MMMM yyyy
    	 */
    	private SimpleDateFormat dateFormatLong = new SimpleDateFormat("EEEE, d MMMM yyyy");
    	/**
    	 *  包括年,月,日的日期格式   dd-MM-yyyy
    	 */
    	private SimpleDateFormat dateFormatShort = new SimpleDateFormat("dd-MM-yyyy");
    	
    	/**
    	 * Sql中的日期格式   dd-MM-yyyy kk:mm.ss
    	 */
    	private SimpleDateFormat dateFormatSql = new SimpleDateFormat("dd-MM-yyyy kk:mm.ss");
    
    	//UTILS
    	public Utils()
    	{
    	}
    	
    	/**
    	 * 得到周別的日期字符串 
    	 */
    	public String GetWeekDay(Calendar date)
    	{
    		return dateFormatWeekDay.format(date.getTime());
    	}
    
    	/**
    	 * 得到月的日期字符串 
    	 */
    
    	public String GetMonth(Calendar date)
    	{
    		return dateFormatMonth.format(date.getTime());
    	}
    	
    	/**
    	 * 得到包括年,月,日,周的日期格式字符串 
    	 */
    	public String GetLongDate(Calendar date)
    	{
    		return dateFormatLong.format(date.getTime());
    	}
    	
    	/**
    	 * 得到包括年,月,日的日期格式字符串 
    	 */
    	public String GetShortDate(Calendar date)
    	{
    		return dateFormatShort.format(date.getTime());
    	}
    	
    	/**
    	 * 
    	 * @Function: pl.magot.vetch.ancal.Utils.GetLongTime
    	 * @Description: 得到時和分
    	 *
    	 * @param date 日期
    	 * @param b24HourMode  是否24小時制: true 是  false 否
    	 * @return  由小時和分鐘組成的字符串 如: 12:20
    	 *
    	 * @version:v1.0
    	 * @author:KrisLight
    	 * @date:2013/9/4 下午4:51:27
    	 *
    	 * Modification History:
    	 * Date         Author      Version     Description
    	 * -----------------------------------------------------------------
    	 * 2013/9/4    KrisLight      v1.0.0         create
    	 */
    	public String GetLongTime(Calendar date, boolean b24HourMode)
    	{
    		String s = "";
    		if (b24HourMode)
    		{
    			//k: 24 小时制的小时     M: 小时中的分钟
    			s = String.format("%tk:%tM", date, date);
    		} else {			
    			//l: 12 小时制的小时     M: 小时中的分钟
    			if (date.get(Calendar.AM_PM) == 0) //AM		
    				s = String.format("%tl:%tM am", date, date, date.get(Calendar.AM_PM));
    			if (date.get(Calendar.AM_PM) == 1) //PM						
    				s = String.format("%tl:%tM pm", date, date, date.get(Calendar.AM_PM));
    		}
    		return s; 
    	}
    
    	
    	/**
    	 * 
    	 * @Function: pl.magot.vetch.ancal.Utils.SqlStrToDate
    	 * @Description: 將用Sql語句查出來的日期字符串轉換成對應的日期Date
    	 *
    	 * @param s  sql format: "dd-MM-yyyy kk:mm.ss"
    	 * @param dateOut 轉換成功的日期
    	 * @param dateFail 轉換失敗默認的日期
    	 * @return
    	 *
    	 * @version:v1.0
    	 * @author:KrisLight
    	 * @date:2013/9/4 下午5:07:40
    	 *
    	 * Modification History:
    	 * Date         Author      Version     Description
    	 * -----------------------------------------------------------------
    	 * 2013/9/4    KrisLight      v1.0.0         create
    	 */
    	public static Calendar SqlStrToDate(String s, Calendar dateOut, Calendar dateFail)
    	{
    		if (s.length() == 19)
    		{
    			int dd = Integer.parseInt(s.substring(0, 2));
    			int MM = Integer.parseInt(s.substring(3, 5));
    			int yyyy = Integer.parseInt(s.substring(6, 10));
    			int kk = Integer.parseInt(s.substring(11, 13));
    			int mm = Integer.parseInt(s.substring(14, 16));
    			int ss = Integer.parseInt(s.substring(17, 19));
    			// set(int year, int month, int day, int hourOfDay, int minute, int second) 這裡月從0開始  1月對應的是0
    			dateOut.set(yyyy, MM - 1, dd, kk, mm, ss);
    			return dateOut;
    		}
    		return dateFail;		
    	}
    	
    	
    	/**
    	 * 
    	 * @Function: pl.magot.vetch.ancal.Utils.DateToSqlStr
    	 * @Description:將日期轉換成SQL中需要的日期格式
    	 *
    	 * @param date
    	 * @return
    	 *
    	 * @version:v1.0
    	 * @author:KrisLight
    	 * @date:2013/9/4 下午5:11:29
    	 *
    	 * Modification History:
    	 * Date         Author      Version     Description
    	 * -----------------------------------------------------------------
    	 * 2013/9/4    KrisLight      v1.0.0         create
    	 */
    	public String DateToSqlStr(Calendar date)
    	{
    		return dateFormatSql.format(date.getTime());
    	}
    	
    	/**
    	 *  將時間轉換成秒
    	 */
    	public static int GetTimeAsSeconds(Calendar date)
    	{
    		return (date.get(Calendar.HOUR_OF_DAY) * 3600) +
    			date.get(Calendar.MINUTE) * 60;
    	}
    
    	/**
    	 *  清除日期
    	 */
    	public static void ClearCalendarTime(Calendar cal)
    	{
    		cal.clear(Calendar.MILLISECOND);
    		cal.clear(Calendar.SECOND);
    		cal.clear(Calendar.MINUTE);
    		cal.clear(Calendar.HOUR_OF_DAY);
    	}
    	
    	/**
    	 *  判斷日期是否相等
    	 */
    	public static boolean YearDaysEqual(Calendar calDate, Calendar calDateTo)
    	{
    		if (calDate.get(Calendar.YEAR) == calDateTo.get(Calendar.YEAR))
    			if (calDate.get(Calendar.MONTH) == calDateTo.get(Calendar.MONTH))
    				if (calDate.get(Calendar.DAY_OF_MONTH) == calDateTo.get(Calendar.DAY_OF_MONTH))
    					return true;
    		return false;
    	}
    
    	/**
    	 *  判斷前一個日期是否大於后一個
    	 */
    	public static boolean YearDaysGreater(Calendar calDate, Calendar calDateTo)
    	{
    		if (calDate.get(Calendar.YEAR) >= calDateTo.get(Calendar.YEAR))
    			if (calDate.get(Calendar.MONTH) >= calDateTo.get(Calendar.MONTH))
    				if (calDate.get(Calendar.DAY_OF_MONTH) >= calDateTo.get(Calendar.DAY_OF_MONTH))
    					return true;
    		return false;
    	}
    	
    	/**
    	 * 判斷前一個時間是否等於或晚於後面一個時間 
    	 * 用於設置鬧鐘的時候與當前時間判斷
    	 * 設置的鬧鈴時間必須晚於當前時間
    	 */
    	public static boolean IsTimeOverdued(Calendar calDate, Calendar calDueDate)
    	{
    		if ((calDueDate.compareTo(calDate) == 0) || (calDueDate.compareTo(calDate) == 1))
    			return true;
    		return false;
    	}
    	
    	//compare time: for calendar view display
    	public static boolean IsInTimeRange(Calendar calDateStart, Calendar calDate, int iDurationInMinutes)
    	{
    		if (calDate.get(Calendar.HOUR_OF_DAY) == calDateStart.get(Calendar.HOUR_OF_DAY))
    			if (calDate.get(Calendar.MINUTE) >= calDateStart.get(Calendar.MINUTE))
    				if (calDate.get(Calendar.MINUTE) <= (calDateStart.get(Calendar.MINUTE) + iDurationInMinutes))
    					return true;
    		return false;
    	}	
    	
    	/**
    	 *  將時間轉換成long類型  形如: 200712122359
    	 */
    	public static long GetDateTimeKey(Calendar calDate)
    	{
    		long lYear = calDate.get(Calendar.YEAR) * 100000000;
    		long lMonth = calDate.get(Calendar.MONTH) * 1000000;
    		long lDay = calDate.get(Calendar.DAY_OF_MONTH) * 10000;
    		long lHour = calDate.get(Calendar.HOUR_OF_DAY) * 100;
    		long lMinute = calDate.get(Calendar.MINUTE);
    		return lYear + lMonth + lDay + lHour + lMinute;
    	}
    
    	/**
    	 *  首字母大寫
    	 */
    	public static String CapitalizeFirstLetter(String sText)
    	{
    		return sText.substring(0,1).toUpperCase() + sText.substring(1, sText.length()).toLowerCase();
    	}
    
    	/**
    	 *  得到App版本
    	 */
    	public static String getAppVersionName(Context ctx)
    	{
    		try
    		{
    			PackageInfo pi = ctx.getPackageManager().getPackageInfo("pl.magot.vetch.ancal", 0);
    			return pi.versionName;
    		} catch (NameNotFoundException e) {
    		}
    		return "";
    	}
    	
    	
    	/**
    	 * 
    	 * @Function: com.light.mycal.util.Utils.join
    	 * @Description: 集合中的元素以指定分隔符隔開
    	 *
    	 * @param list   集合List
    	 * @param delim  分隔符
    	 * @return  用分隔符隔開的集合元素字符串
    	 *
    	 * @version: v1.0
    	 * @author: KrisLight
    	 * @date: 2013/9/5 上午10:20:51
    	 *
    	 * Modification History:
    	 * Date         Author      Version     Description
    	 * -----------------------------------------------------------------
    	 * 2013/9/5    KrisLight      v1.0.0         create
    	 */
    	public static String join(List<String> list, String delim) {
    	    StringBuilder buf = new StringBuilder();
    	    int num = list.size();
    	    for (int i = 0; i < num; i++) {
    	        if (i != 0){
    	            buf.append(delim);
    	        }
    	        buf.append((String) list.get(i));
    	    }
    	    return buf.toString();
    	}
    	
    	/**
    	 *  開始alpha動畫
    	 */
      public static void startAlphaAnimIn(View view)
      {
    		AlphaAnimation anim = new AlphaAnimation(0.5F, 1);
    		anim.setDuration(ANIM_ALPHA_DURATION);
    		anim.startNow();
    		view.startAnimation(anim);
      }
      
    	/**
    	 *  開始translate動畫
    	 */
      public static void startTranslateAnimIn(View view)
      {
    		TranslateAnimation anim = new TranslateAnimation(0, 0, - view.getHeight(), 0);
    		anim.setDuration(ANIM_TRANSLATE_DURATION);
    		anim.startNow();
    		view.startAnimation(anim);
      }  
    	
    }
    


    图像处理类 

    1.图像缓存


    public class BitmapCache {
    	
        private static final 
    
    String TAG = "ImageCache";
    
        private static final int 
    
    DEFAULT_MEM_CACHE_SIZE = 1024 * 1024 * 8; // 8MB
    
        
    
    private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 
    
    1024 * 20; // 20MB
    
        // Compression settings when 
    
    writing images to disk cache
        private static final 
    
    CompressFormat DEFAULT_COMPRESS_FORMAT = 
    
    CompressFormat.JPEG;
        private static final int 
    
    DEFAULT_COMPRESS_QUALITY = 70;
        private static final 
    
    int DISK_CACHE_INDEX = 0;
    
        // Constants to easily 
    
    toggle various caches
        private static final boolean 
    
    DEFAULT_MEM_CACHE_ENABLED = true;
        private static final 
    
    boolean DEFAULT_DISK_CACHE_ENABLED = true;
        private 
    
    static final boolean DEFAULT_CLEAR_DISK_CACHE_ON_START = 
    
    false;
        private static final boolean 
    
    DEFAULT_INIT_DISK_CACHE_ON_CREATE = false;
    
        private 
    
    LruDiskCache mDiskLruCache;
        private 
    
    LruMemoryCache<String, Bitmap> mMemoryCache;
        private 
    
    ImageCacheParams mCacheParams;
        private final Object 
    
    mDiskCacheLock = new Object();
        private boolean 
    
    mDiskCacheStarting = true;
    
        /**
         * Creating a new 
    
    ImageCache object using the specified parameters.
         *
       
    
      * @param cacheParams The cache parameters to use to 
    
    initialize the cache
         */
        public BitmapCache
    
    (ImageCacheParams cacheParams) {
            init
    
    (cacheParams);
        }
    
    
        /**
         * Initialize the cache, 
    
    providing all parameters.
         *
         * @param cacheParams 
    
    The cache parameters to initialize the cache
         */
        
    
    private void init(ImageCacheParams cacheParams) {
            
    
    mCacheParams = cacheParams;
    
            // Set up memory cache
     
    
           if (mCacheParams.memoryCacheEnabled) {
                
    
    mMemoryCache = new LruMemoryCache<String, Bitmap>
    
    (mCacheParams.memCacheSize) {
                    /**
              
    
           * Measure item size in bytes rather than units 
    
    which is more practical
                     * for a bitmap 
    
    cache
                     */
                    @Override
             
    
           protected int sizeOf(String key, Bitmap bitmap) {
      
    
                      return BitmapCommonUtils.getBitmapSize
    
    (bitmap);
                    }
                };
            }
    
            
    
    // By default the disk cache is not initialized here as 
    
    it should be initialized
            // on a separate thread 
    
    due to disk access.
            if 
    
    (cacheParams.initDiskCacheOnCreate) {
                // Set 
    
    up disk cache
                initDiskCache();
            }
        }
    
       
    
     /**
         * Initializes the disk cache.  Note that this 
    
    includes disk access so this should not be
         * executed 
    
    on the main/UI thread. By default an ImageCache does not 
    
    initialize the disk
         * cache when it is created, 
    
    instead you should call initDiskCache() to initialize it 
    
    on a
         * background thread.
         */
        public void 
    
    initDiskCache() {
            // Set up disk cache
            
    
    synchronized (mDiskCacheLock) {
                if 
    
    (mDiskLruCache == null || mDiskLruCache.isClosed()) {
         
    
               File diskCacheDir = mCacheParams.diskCacheDir;
     
    
                   if (mCacheParams.diskCacheEnabled && 
    
    diskCacheDir != null) {
                        if (!
    
    diskCacheDir.exists()) {
                            
    
    diskCacheDir.mkdirs();
                        }
                   
    
         if (BitmapCommonUtils.getUsableSpace(diskCacheDir) > 
    
    mCacheParams.diskCacheSize) {
                            try 
    
    {
                                mDiskLruCache = 
    
    LruDiskCache.open(diskCacheDir, 1, 1, 
    
    mCacheParams.diskCacheSize);
                            } 
    
    catch (final IOException e) {
                                
    
    mCacheParams.diskCacheDir = null;
                             
    
       Log.e(TAG, "initDiskCache - " + e);
                        
    
        }
                        }
                    }
                }
      
    
              mDiskCacheStarting = false;
                
    
    mDiskCacheLock.notifyAll();
            }
        }
    
        /**
         * 
    
    Adds a bitmap to both memory and disk cache.
         * @param 
    
    data Unique identifier for the bitmap to store
         * 
    
    @param bitmap The bitmap to store
         */
        public void 
    
    addBitmapToCache(String data, Bitmap bitmap) {
            if 
    
    (data == null || bitmap == null) {
                return;
         
    
       }
    
            // Add to memory cache
            if 
    
    (mMemoryCache != null && mMemoryCache.get(data) == null) 
    
    {
                mMemoryCache.put(data, bitmap);
            }
    
         
    
       synchronized (mDiskCacheLock) {
               if 
    
    (mDiskLruCache != null && mDiskLruCache.getDirectory()!= 
    
    null ) {
                	
                	if(!
    
    mDiskLruCache.getDirectory().exists())
                		
    
    mDiskLruCache.getDirectory().mkdirs();
                	
      
    
                  final String key = 
    
    FileNameGenerator.generator(data);
                    
    
    OutputStream out = null;
                    try {
                 
    
           LruDiskCache.Snapshot snapshot = 
    
    mDiskLruCache.get(key);
                        if (snapshot 
    
    == null) {
                            final 
    
    LruDiskCache.Editor editor = mDiskLruCache.edit(key);
         
    
                       if (editor != null) {
                      
    
              out = editor.newOutputStream(DISK_CACHE_INDEX);
     
    
                               bitmap.compress(
                   
    
                         mCacheParams.compressFormat, 
    
    mCacheParams.compressQuality, out);
                           
    
         editor.commit();
                                
    
    out.close();
                            }
                        
    
    } else {
                            snapshot.getInputStream
    
    (DISK_CACHE_INDEX).close();
                        }
              
    
          } catch (final IOException e) {
                        
    
    Log.e(TAG, "addBitmapToCache - " + e);
                    } 
    
    catch (Exception e) {
                        Log.e(TAG, 
    
    "addBitmapToCache - " + e);
                    } finally {
        
    
                    try {
                            if (out != 
    
    null) {
                                out.close();
               
    
                 }
                        } catch (IOException e) 
    
    {}
                    }
                }
            }
        }
    
        /**
         
    
    * Get from memory cache.
         *
         * @param data Unique 
    
    identifier for which item to get
         * @return The bitmap 
    
    if found in cache, null otherwise
         */
        public Bitmap 
    
    getBitmapFromMemCache(String data) {
            if 
    
    (mMemoryCache != null) {
                final Bitmap 
    
    memBitmap = mMemoryCache.get(data);
                if 
    
    (memBitmap != null) {
                    return memBitmap;
        
    
            }
            }
            return null;
        }
    
        /**
         * 
    
    @param data
         * @return
         */
        public Bitmap 
    
    getBitmapFromDiskCache(String data) {
        	final 
    
    String key = FileNameGenerator.generator(data);
            
    
    synchronized (mDiskCacheLock) {
                while 
    
    (mDiskCacheStarting) {
                    try {
                   
    
         mDiskCacheLock.wait();
                    } catch 
    
    (InterruptedException e) {}
                }
                if 
    
    (mDiskLruCache != null) {
                    InputStream 
    
    inputStream = null;
                    try {
                      
    
      final LruDiskCache.Snapshot snapshot = 
    
    mDiskLruCache.get(key);
                        if (snapshot 
    
    != null) {
                            inputStream = 
    
    snapshot.getInputStream(DISK_CACHE_INDEX);
                    
    
            if (inputStream != null) {
                            
    
        final Bitmap bitmap = BitmapFactory.decodeStream
    
    (inputStream);
                                return bitmap;
      
    
                          }
                        }
                  
    
      } catch (final IOException e) {
                        
    
    Log.e(TAG, "getBitmapFromDiskCache - " + e);
                  
    
      } finally {
                        try {
                        
    
        if (inputStream != null) {
                                
    
    inputStream.close();
                            }
                 
    
           } catch (IOException e) {}
                    }
            
    
        }
                return null;
            }
        }
    
        /**
         * 
    
    Clears both the memory and disk cache associated with 
    
    this ImageCache object. Note that
         * this includes 
    
    disk access so this should not be executed on the main/UI 
    
    thread.
         */
        public void clearCache() {
        	
    
    clearMemoryCache();
            synchronized (mDiskCacheLock) 
    
    {
                mDiskCacheStarting = true;
                if 
    
    (mDiskLruCache != null && !mDiskLruCache.isClosed()) {
        
    
                try {
                        
    
    mDiskLruCache.delete();
                    } catch 
    
    (IOException e) {
                        Log.e(TAG, 
    
    "clearCache - " + e);
                    }
                    
    
    mDiskLruCache = null;
                    initDiskCache();
         
    
           }
            }
        }
        
        public void 
    
    clearMemoryCache(){
        	if (mMemoryCache != null) {
           
    
         mMemoryCache.evictAll();
            }
        }
    
        /**
         * 
    
    Flushes the disk cache associated with this ImageCache 
    
    object. Note that this includes
         * disk access so this 
    
    should not be executed on the main/UI thread.
         */
        
    
    public void flush() {
            synchronized 
    
    (mDiskCacheLock) {
                if (mDiskLruCache != null) 
    
    {
                    try {
                        
    
    mDiskLruCache.flush();
                    } catch 
    
    (IOException e) {
                        Log.e(TAG, "flush - 
    
    " + e);
                    }
                }
            }
        }
    
        
    
    /**
         * Closes the disk cache associated with this 
    
    ImageCache object. Note that this includes
         * disk 
    
    access so this should not be executed on the main/UI 
    
    thread.
         */
        public void close() {
            
    
    synchronized (mDiskCacheLock) {
                if 
    
    (mDiskLruCache != null) {
                    try {
                
    
            if (!mDiskLruCache.isClosed()) {
                      
    
          mDiskLruCache.close();
                            
    
    mDiskLruCache = null;
                        }
                    
    
    } catch (IOException e) {
                        Log.e(TAG, 
    
    "close - " + e);
                    }
                }
            }
       
    
     }
    
        /**
         * A holder class that contains cache 
    
    parameters.
         */
        public static class 
    
    ImageCacheParams {
            public int memCacheSize = 
    
    DEFAULT_MEM_CACHE_SIZE;
            public int diskCacheSize = 
    
    DEFAULT_DISK_CACHE_SIZE;
            public File diskCacheDir;
     
    
           public CompressFormat compressFormat = 
    
    DEFAULT_COMPRESS_FORMAT;
            public int 
    
    compressQuality = DEFAULT_COMPRESS_QUALITY;
            public 
    
    boolean memoryCacheEnabled = DEFAULT_MEM_CACHE_ENABLED;
       
    
         public boolean diskCacheEnabled = 
    
    DEFAULT_DISK_CACHE_ENABLED;
            public boolean 
    
    clearDiskCacheOnStart = 
    
    DEFAULT_CLEAR_DISK_CACHE_ON_START;
            public boolean 
    
    initDiskCacheOnCreate = 
    
    DEFAULT_INIT_DISK_CACHE_ON_CREATE;
    
    
            public 
    
    ImageCacheParams(File diskCacheDir) {
                
    
    this.diskCacheDir = diskCacheDir;
            }
            
            
    
    public ImageCacheParams(String diskCacheDir) {
                
    
    this.diskCacheDir = new File(diskCacheDir);
            }
    
          
    
      /**
             * @param context棿
             */
            public 
    
    void setMemCacheSizePercent(Context context, float 
    
    percent) {
                if (percent < 0.05f || percent > 
    
    0.8f) {
                    throw new 
    
    IllegalArgumentException("setMemCacheSizePercent - 
    
    percent must be "
                            + "between 0.05 
    
    and 0.8 (inclusive)");
                }
                
    
    memCacheSize = Math.round(percent * getMemoryClass
    
    (context) * 1024 * 1024);
            }
            
            
    		
    
    public void setMemCacheSize(int memCacheSize) {
    			
    
    this.memCacheSize = memCacheSize;
    		}
    
    		
    
    public void setDiskCacheSize(int diskCacheSize) {
    		
    
    	this.diskCacheSize = diskCacheSize;
    		}
    
    	
    
    	private static int getMemoryClass(Context 
    
    context) {
                return ((ActivityManager) 
    
    context.getSystemService(
                        
    
    Context.ACTIVITY_SERVICE)).getMemoryClass();
            }
        
    
    }
    
        
    
    }
    


    图像处理类

    public class BitmapCommonUtils {
    	
    	private static final String TAG = "BitmapCommonUtils";
    	
    	/**
    	 * @param context
    	 * @return
    	 */
        public static File getDiskCacheDir(Context context, String uniqueName) {
            final String cachePath = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ? 
                    		getExternalCacheDir(context).getPath() : context.getCacheDir().getPath();
    
            return new File(cachePath + File.separator + uniqueName);
        }
    
      
    
        /**
         * @param bitmap
         * @return
         */
        public static int getBitmapSize(Bitmap bitmap) {
            return bitmap.getRowBytes() * bitmap.getHeight();
        }
    
    
       /**
        * @param context
        * @return
        */
        public static File getExternalCacheDir(Context context) {
            final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
            return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
        }
    
        /**
         * @param path
         * @return
         */
        public static long getUsableSpace(File path) {
        	try{
        		 final StatFs stats = new StatFs(path.getPath());
        	     return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks();
        	}catch (Exception e) {
    			
    			e.printStackTrace();
    			return -1;
    		}
           
        }
    
    }
    

    图像Decoder类

    public class BitmapDecoder {
    	private static final String TAG = "BitmapDecoder";
    	private BitmapDecoder(){}
    
        public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,int reqWidth, int reqHeight) {
    
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            options.inPurgeable = true;
            BitmapFactory.decodeResource(res, resId, options);
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            options.inJustDecodeBounds = false;
            try {
            	  return BitmapFactory.decodeResource(res, resId, options);
    		} catch (OutOfMemoryError e) {
    			 e.printStackTrace();
    			 return null;
    		}
        }
    
        public static Bitmap decodeSampledBitmapFromFile(String filename,int reqWidth, int reqHeight) {
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            options.inPurgeable = true;
            BitmapFactory.decodeFile(filename, options);
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            options.inJustDecodeBounds = false;
            try {
            	  return BitmapFactory.decodeFile(filename, options);
    		} catch (OutOfMemoryError e) {
    			 e.printStackTrace();
    			 return null;
    		}
        }
    
        public static Bitmap decodeSampledBitmapFromDescriptor(FileDescriptor fileDescriptor, int reqWidth, int reqHeight) {
    
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            options.inPurgeable = true;
            BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
            options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
            options.inJustDecodeBounds = false;
            try {
            	 return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
    		} catch (OutOfMemoryError e) {
    			// Log.e(TAG, "decodeSampledBitmapFromDescriptor");
    			 e.printStackTrace();
    			 return null;
    		}
        }
    
        public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
    
            if (height > reqHeight || width > reqWidth) {
                if (width > height) {
                    inSampleSize = Math.round((float) height / (float) reqHeight);
                } else {
                    inSampleSize = Math.round((float) width / (float) reqWidth);
                }
    
                final float totalPixels = width * height;
    
                final float totalReqPixelsCap = reqWidth * reqHeight * 2;
    
                while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
                    inSampleSize++;
                }
            }
            return inSampleSize;
        }
    }
    

    图像显示配置类

    public class BitmapDisplayConfig {
    	
    	
    	private int bitmapWidth;
    	private int bitmapHeight;
    	
    	private Animation animation;
    	
    	private int animationType;
    	private Bitmap loadingBitmap;
    	private Bitmap loadfailBitmap;
    	
    
    	public int getBitmapWidth() {
    		return bitmapWidth;
    	}
    
    	public void setBitmapWidth(int bitmapWidth) {
    		this.bitmapWidth = bitmapWidth;
    	}
    
    	public int getBitmapHeight() {
    		return bitmapHeight;
    	}
    
    	public void setBitmapHeight(int bitmapHeight) {
    		this.bitmapHeight = bitmapHeight;
    	}
    
    	public Animation getAnimation() {
    		return animation;
    	}
    
    	public void setAnimation(Animation animation) {
    		this.animation = animation;
    	}
    
    	public int getAnimationType() {
    		return animationType;
    	}
    
    	public void setAnimationType(int animationType) {
    		this.animationType = animationType;
    	}
    
    	public Bitmap getLoadingBitmap() {
    		return loadingBitmap;
    	}
    
    	public void setLoadingBitmap(Bitmap loadingBitmap) {
    		this.loadingBitmap = loadingBitmap;
    	}
    
    	public Bitmap getLoadfailBitmap() {
    		return loadfailBitmap;
    	}
    
    	public void setLoadfailBitmap(Bitmap loadfailBitmap) {
    		this.loadfailBitmap = loadfailBitmap;
    	}
    
    	
    	public class AnimationType{
    		public static final int userDefined = 0;
    		public static final int fadeIn = 1;
    	}
    
    }
    


    图像流读取类

    public class BitmapProcess {
    	private static final String TAG = "BitmapProcess";
    	private boolean mHttpDiskCacheStarting = true;
    	private int cacheSize;
    	private static final int DEFAULT_CACHE_SIZE = 20 * 1024 * 1024; // 20MB
    
    	private LruDiskCache mOriginalDiskCache;
    	private final Object mHttpDiskCacheLock = new Object();
    	private static final int DISK_CACHE_INDEX = 0;
    
    	private File mOriginalCacheDir;
    	private Downloader downloader;
    	
    	private boolean neverCalculate = false;
    
    	public BitmapProcess(Downloader downloader,String filePath,int cacheSize) {
    		this.mOriginalCacheDir = new File(filePath+"/original");
    		this.downloader = downloader;
    		if(cacheSize<=0)
    			cacheSize = DEFAULT_CACHE_SIZE;
    		this.cacheSize = cacheSize;
    	}
    	
    	public void configCalculateBitmap(boolean neverCalculate){
    		this.neverCalculate = neverCalculate;
    	}
    
    	public Bitmap processBitmap(String data, BitmapDisplayConfig config) {
    		final String key = FileNameGenerator.generator(data);
    		FileDescriptor fileDescriptor = null;
    		FileInputStream fileInputStream = null;
    		LruDiskCache.Snapshot snapshot;
    		synchronized (mHttpDiskCacheLock) {
    			// Wait for disk cache to initialize
    			while (mHttpDiskCacheStarting) {
    				try {
    					mHttpDiskCacheLock.wait();
    				} catch (InterruptedException e) {
    				}
    			}
    
    			if (mOriginalDiskCache != null) {
    				try {
    					snapshot = mOriginalDiskCache.get(key);
    					if (snapshot == null) {
    						LruDiskCache.Editor editor = mOriginalDiskCache.edit(key);
    						if (editor != null) {
    							if (downloader.downloadToLocalStreamByUrl(data,editor.newOutputStream(DISK_CACHE_INDEX))) {
    								editor.commit();
    							} else {
    								editor.abort();
    							}
    						}
    						snapshot = mOriginalDiskCache.get(key);
    					}
    					if (snapshot != null) {
    						fileInputStream = (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX);
    						fileDescriptor = fileInputStream.getFD();
    					}
    				} catch (IOException e) {
    					Log.e(TAG, "processBitmap - " + e);
    				} catch (IllegalStateException e) {
    					Log.e(TAG, "processBitmap - " + e);
    				} finally {
    					if (fileDescriptor == null && fileInputStream != null) {
    						try {
    							fileInputStream.close();
    						} catch (IOException e) {
    						}
    					}
    				}
    			}
    		}
    
    		Bitmap bitmap = null;
    		if (fileDescriptor != null) {
    			if(neverCalculate)
    				bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
    			else
    				bitmap = BitmapDecoder.decodeSampledBitmapFromDescriptor(fileDescriptor, config.getBitmapWidth(),config.getBitmapHeight());
    		}
    		if (fileInputStream != null) {
    			try {
    				fileInputStream.close();
    			} catch (IOException e) {
    			}
    		}
    		return bitmap;
    	}
    
    	public void initHttpDiskCache() {
    		if (!mOriginalCacheDir.exists()) {
    			mOriginalCacheDir.mkdirs();
    		}
    		synchronized (mHttpDiskCacheLock) {
    			if (BitmapCommonUtils.getUsableSpace(mOriginalCacheDir) > cacheSize) {
    				try {
    					mOriginalDiskCache = LruDiskCache.open(mOriginalCacheDir, 1, 1,cacheSize);
    				} catch (IOException e) {
    					mOriginalDiskCache = null;
    				}
    			}
    			mHttpDiskCacheStarting = false;
    			mHttpDiskCacheLock.notifyAll();
    		}
    	}
    
    	public void clearCacheInternal() {
    		synchronized (mHttpDiskCacheLock) {
    			if (mOriginalDiskCache != null && !mOriginalDiskCache.isClosed()) {
    				try {
    					mOriginalDiskCache.delete();
    				} catch (IOException e) {
    					Log.e(TAG, "clearCacheInternal - " + e);
    				}
    				mOriginalDiskCache = null;
    				mHttpDiskCacheStarting = true;
    				initHttpDiskCache();
    			}
    		}
    	}
    
    	public void flushCacheInternal() {
    		synchronized (mHttpDiskCacheLock) {
    			if (mOriginalDiskCache != null) {
    				try {
    					mOriginalDiskCache.flush();
    				} catch (IOException e) {
    					Log.e(TAG, "flush - " + e);
    				}
    			}
    		}
    	}
    
    	public void closeCacheInternal() {
    		synchronized (mHttpDiskCacheLock) {
    			if (mOriginalDiskCache != null) {
    				try {
    					if (!mOriginalDiskCache.isClosed()) {
    						mOriginalDiskCache.close();
    						mOriginalDiskCache = null;
    					}
    				} catch (IOException e) {
    					Log.e(TAG, "closeCacheInternal - " + e);
    				}
    			}
    		}
    	}
    	
    	
    }
    


    下载类

    public interface Downloader  {
    	
    	public boolean downloadToLocalStreamByUrl(String urlString, OutputStream outputStream);
    }
    


    public class SimpleHttpDownloader implements Downloader{
    	
    	private static final String TAG = "BitmapDownloader";
    	
    	private static final int IO_BUFFER_SIZE = 8 * 1024; //8k
    	
    	 public boolean downloadToLocalStreamByUrl(String urlString, OutputStream outputStream) {
    	        HttpURLConnection urlConnection = null;
    	        BufferedOutputStream out = null;
    	        FlushedInputStream in = null;
    
    	        try {
    	            final URL url = new URL(urlString);
    	            urlConnection = (HttpURLConnection) url.openConnection();
    	            in = new FlushedInputStream(new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE));
    	            out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
    
    	            int b;
    	            while ((b = in.read()) != -1) {
    	                out.write(b);
    	            }
    	            return true;
    	        } catch (final IOException e) {
    	            Log.e(TAG, "Error in downloadBitmap - "+urlString +" : " + e);
    	        } finally {
    	            if (urlConnection != null) {
    	                urlConnection.disconnect();
    	            }
    	            try {
    	                if (out != null) {
    	                    out.close();
    	                }
    	                if (in != null) {
    	                    in.close();
    	                }
    	            } catch (final IOException e) {}
    	        }
    	        return false;
    	    }
    
    	    
    	    public class FlushedInputStream extends FilterInputStream {
    
    	    	public FlushedInputStream(InputStream inputStream) {
    	    		super(inputStream);
    	    	}
    
    	    	@Override
    	    	public long skip(long n) throws IOException {
    	    		long totalBytesSkipped = 0L;
    	    		while (totalBytesSkipped < n) {
    	    			long bytesSkipped = in.skip(n - totalBytesSkipped);
    	    			if (bytesSkipped == 0L) {
    	    				int by_te = read();
    	    				if (by_te < 0) {
    	    					break; // we reached EOF
    	    				} else {
    	    					bytesSkipped = 1; // we read one byte
    	    				}
    	    			}
    	    			totalBytesSkipped += bytesSkipped;
    	    		}
    	    		return totalBytesSkipped;
    	    	}
    	    }
    }
    











  • 相关阅读:
    Creative Cloud 无法连接问题
    HTTP_PROXY
    <video> controlsList
    Electron 问题
    含神经网络的离线AI翻译 APP

    (转载)移动Web开发技巧汇总
    2014年总结
    转载(web app变革之rem)
    火狐不支持backgroundPosition的js插件
  • 原文地址:https://www.cnblogs.com/krislight1105/p/3748354.html
Copyright © 2020-2023  润新知