package org.orange.familylink.database; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.orange.familylink.data.Contact; import org.orange.familylink.data.Message; import org.orange.familylink.data.MessageLogRecord; import org.orange.familylink.data.MessageLogRecord.Status; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.util.Log; /** * 数据库操作类,有contacts和messages表 * @author OrangeTeam * */ public class FamilyLinkDBAdapter { SQLiteDatabase db; private final Context context; FamilyLinkDBOpenHelper dbHelper; /** * 构造方法实例化数据库 * @param mContext */ public FamilyLinkDBAdapter(Context mContext){ context = mContext; dbHelper = new FamilyLinkDBOpenHelper(context, Contract.DATABASE_NAME, null, Contract.DATABASE_VERSION); } /** * 数据库构建的类 * @author OrangeTeam * */ static class FamilyLinkDBOpenHelper extends SQLiteOpenHelper{ public FamilyLinkDBOpenHelper(Context context, String name, CursorFactory factory, int version){ super(context, name, factory, version); } public FamilyLinkDBOpenHelper(Context context){ super(context, Contract.DATABASE_NAME, null, Contract.DATABASE_VERSION); } /* * 在数据库构建中系统调用的方法,用于执行sql语句,生成表和索引等 * (non-Javadoc) * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase) */ @Override public void onCreate(SQLiteDatabase arg0) { arg0.execSQL(Contract.Contacts.CONTACTS_TABLE_CREATE); arg0.execSQL(Contract.Messages.MESSAGES_TABLE_CREATE); arg0.execSQL(Contract.Messages.INDEX_CREATE); } /* * 在数据库构建中系统调用的方法,用于升级数据库 * (non-Javadoc) * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int) */ @Override public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { Log.w("FamilyLinkDBAdapter", "Upgrading from version " + arg1 + " to " + arg2 + ", which will destroy all data"); arg0.execSQL("DROP TABLE IF EXISTS " + Contract.DATABASE_CONTACTS_TABLE); arg0.execSQL("DROP TABLE IF EXISTS " + Contract.DATABASE_MESSAGES_TABLE); onCreate(arg0); } } /** * 打开一个可写的数据库 * @throws SQLiteException */ public void open() throws SQLiteException{ try{ db = dbHelper.getWritableDatabase(); }catch(SQLiteException e){ db = dbHelper.getReadableDatabase(); } } /** * 判断数据库是否打开 * @return 如果返回值是true,则说明数据库已经打开 */ public boolean isOpen(){ return (db != null && db.isOpen()); } /** * 关闭数据库 */ public void close(){ if(db.isOpen()) db.close(); } /** * 把Bitmap转换为字节数组进行存储 * @param bitmap * @return byte[] */ private byte[] codePhoto(Bitmap bitmap){ //计算位图的大小 int bytes = bitmap.getRowBytes() * bitmap.getHeight(); //分配缓存 ByteBuffer buffer = ByteBuffer.allocate(bytes); //把位图加载到缓存中 bitmap.copyPixelsToBuffer(buffer); byte[] array = buffer.array(); return array; } /** * 用于向contacts表中插入数据 * @param name 要存储的联系人的姓名 * @param phoneNumber 要存储的联系人的电话号码 * @param photo 是Bitmap对象,要存储的联系人的照片 */ public void insertContact(String name, String phoneNumber, Bitmap photo){ ContentValues contentValues = new ContentValues(); contentValues.put(Contract.Contacts.COLUMN_NAME_NAME, name); contentValues.put(Contract.Contacts.COLUMN_NAME_PHONE_NUMBER, phoneNumber); contentValues.put(Contract.Contacts.COLUMN_NAME_PHOTO, codePhoto(photo)); db.insert(Contract.DATABASE_CONTACTS_TABLE, null, contentValues); } /** * 用于向contacts表中插入数据 * @param contact */ public void insertContact(Contact contact){ //如果提供的联系人是空就结束插入 if(contact == null)return; ContentValues contentValues = new ContentValues(); contentValues.put(Contract.Contacts.COLUMN_NAME_NAME, contact.getName()); contentValues.put(Contract.Contacts.COLUMN_NAME_PHONE_NUMBER, contact.getPhoneNumber()); contentValues.put(Contract.Contacts.COLUMN_NAME_PHOTO, codePhoto(contact.getPhoto())); db.insert(Contract.DATABASE_CONTACTS_TABLE, null, contentValues); } /*** * 用于向contacts表中插入数据 * @param contacts */ public void inserListsContacts(List<Contact> contacts){ //如果联系人是空就停止插入操作 if(contacts == null || contacts.isEmpty())return; ContentValues contentValues = new ContentValues(); for(Contact aContact : contacts){ contentValues.put(Contract.Contacts.COLUMN_NAME_NAME, aContact.getName()); contentValues.put(Contract.Contacts.COLUMN_NAME_PHONE_NUMBER, aContact.getPhoneNumber()); contentValues.put(Contract.Contacts.COLUMN_NAME_PHOTO, codePhoto(aContact.getPhoto())); db.insert(Contract.DATABASE_CONTACTS_TABLE, null, contentValues); } } /** * 用于向messages表中插入数据 * @param messageLogRecord */ public void insertMessage(MessageLogRecord messageLogRecord){ //如果消息日志为空就停止插入操作 if(messageLogRecord == null)return; ContentValues contentValues = new ContentValues(); contentValues.put(Contract.Messages.COLUMN_NAME_CONTACT_ID, messageLogRecord.getContact().getId()); contentValues.put(Contract.Messages.COLUMN_NAME_ADDRESS, messageLogRecord.getAddress()); contentValues.put(Contract.Messages.COLUMN_NAME_TIME, messageLogRecord.getDate().getTime()); contentValues.put(Contract.Messages.COLUMN_NAME_STATUS, messageLogRecord.getStatus().name()); contentValues.put(Contract.Messages.COLUMN_NAME_BODY, messageLogRecord.getMessage().getBody()); contentValues.put(Contract.Messages.COLUMN_NAME_CODE, messageLogRecord.getMessage().getCode()); db.insert(Contract.DATABASE_MESSAGES_TABLE, null, contentValues); } /** * 用于向messages表中插入数据 * @param messageLogRecords */ public void insertListsMessages(List<MessageLogRecord> messageLogRecords){ if(messageLogRecords == null || messageLogRecords.isEmpty())return; ContentValues contentValues = new ContentValues(); for(MessageLogRecord aMessageLogRecord : messageLogRecords){ contentValues.put(Contract.Messages.COLUMN_NAME_CONTACT_ID, aMessageLogRecord.getContact().getId()); contentValues.put(Contract.Messages.COLUMN_NAME_ADDRESS, aMessageLogRecord.getAddress()); contentValues.put(Contract.Messages.COLUMN_NAME_TIME, aMessageLogRecord.getDate().getTime()); contentValues.put(Contract.Messages.COLUMN_NAME_STATUS, aMessageLogRecord.getStatus().name()); contentValues.put(Contract.Messages.COLUMN_NAME_BODY, aMessageLogRecord.getMessage().getBody()); contentValues.put(Contract.Messages.COLUMN_NAME_CODE, aMessageLogRecord.getMessage().getCode()); db.insert(Contract.DATABASE_MESSAGES_TABLE, null, contentValues); } } /** * 删除一条联系人记录 * @param contact * @return 删除是否成功,进行的删除的联系人参数为空也表示删除失败 */ public boolean deleteContact(Contact contact){ if(contact == null)return false; long mId = contact.getId(); return (db.delete(Contract.DATABASE_CONTACTS_TABLE, Contract.Contacts._ID + " = " + mId, null) > 0); } /** * 删除多个联系人记录 * @param contacts * @return 表示删除是否成功,进行的删除的联系人参数为空也表示删除失败 */ public boolean deleteListsContacts(List<Contact> contacts){ if(contacts == null || contacts.isEmpty())return false; long mId; for(Contact aContact : contacts){ mId = aContact.getId(); return (db.delete(Contract.DATABASE_CONTACTS_TABLE, Contract.Contacts._ID + " = " + mId, null) > 0); } return true; } /** *删除一条信息记录 * @param messageLogRecord * @return 表示删除是否成功,但消息日志参数为空也表示删除不成功 */ public boolean deleteMessage(MessageLogRecord messageLogRecord){ if(messageLogRecord == null)return false; long mId = messageLogRecord.getId(); return (db.delete(Contract.DATABASE_MESSAGES_TABLE, Contract.Messages._ID + " = " + mId, null) > 0); } /** * 删除多条信息记录 * @param messageLogRecords * @return 表示删除是否成功,但消息日志参数是空也表示删除不成功 */ public boolean deleteListsMessages(List<MessageLogRecord> messageLogRecords){ if(messageLogRecords == null || messageLogRecords.isEmpty())return false; long mId; for(MessageLogRecord aMessageLogRecord : messageLogRecords){ mId = aMessageLogRecord.getId(); return (db.delete(Contract.DATABASE_MESSAGES_TABLE, Contract.Messages._ID + " = " + mId, null) > 0); } return true; } /** * 更新联系人 * @param contact */ public void updateContact(Contact contact){ //参数为空是停止更新 if(contact == null)return; ContentValues contentValues = new ContentValues(); long mId = contact.getId(); //先把游标指向要更新的那条记录 Cursor cursor = db.query(Contract.DATABASE_CONTACTS_TABLE, null, Contract.Contacts._ID + " = " + mId, null, null, null, null); cursor.moveToFirst(); //名字字段如果不相同就进行更新 if(!cursor.getString(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_NAME)) .equals(contact.getName())){ contentValues.put(Contract.Contacts.COLUMN_NAME_NAME, contact.getName()); db.update(Contract.DATABASE_CONTACTS_TABLE, contentValues, Contract.Contacts._ID + " = " + mId, null); contentValues.clear(); } //电话号码字段如果不相同就进行更新 if(!cursor.getString(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_PHONE_NUMBER)) .equals(contact.getPhoneNumber())){ contentValues.put(Contract.Contacts.COLUMN_NAME_PHONE_NUMBER, contact.getPhoneNumber()); db.update(Contract.DATABASE_CONTACTS_TABLE, contentValues, Contract.Contacts._ID + " = " + mId, null); contentValues.clear(); } //从数据库中获取照片,解码成Bitmap if(!BitmapFactory.decodeByteArray( cursor.getBlob(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_PHOTO)), 0, cursor.getBlob(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_PHOTO)).length) .equals(contact.getPhoto())){ contentValues.put(Contract.Contacts.COLUMN_NAME_PHOTO, codePhoto(contact.getPhoto())); } } /** * 更新信息记录 * @param messageLogRecord */ public void updateMessage(MessageLogRecord messageLogRecord){ if(messageLogRecord == null)return; ContentValues contentValues = new ContentValues(); long mId = messageLogRecord.getId(); //先把游标指向要更新的那条记录 Cursor cursor = db.query(Contract.DATABASE_MESSAGES_TABLE, null, Contract.Messages._ID + " = " + mId, null, null, null, null); cursor.moveToFirst(); if(cursor.getLong(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_CONTACT_ID)) != messageLogRecord.getContact().getId()){ contentValues.put(Contract.Messages.COLUMN_NAME_CONTACT_ID, messageLogRecord.getContact().getId()); db.update(Contract.DATABASE_MESSAGES_TABLE, contentValues, Contract.Messages._ID + " = " + mId, null); contentValues.clear(); } if(!cursor.getString(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_ADDRESS)) .equals(messageLogRecord.getAddress())){ contentValues.put(Contract.Messages.COLUMN_NAME_ADDRESS, messageLogRecord.getAddress()); db.update(Contract.DATABASE_MESSAGES_TABLE, contentValues, Contract.Messages._ID + " = " + mId, null); contentValues.clear(); } if(cursor.getLong(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_TIME)) != messageLogRecord.getDate().getTime()){ contentValues.put(Contract.Messages.COLUMN_NAME_TIME, messageLogRecord.getDate().getTime()); db.update(Contract.DATABASE_MESSAGES_TABLE, contentValues, Contract.Messages._ID + " = " + mId, null); contentValues.clear(); } if(cursor.getString(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_STATUS)) .equals(messageLogRecord.getStatus().name())){ contentValues.put(Contract.Messages.COLUMN_NAME_STATUS, messageLogRecord.getStatus().name()); db.update(Contract.DATABASE_MESSAGES_TABLE, contentValues, Contract.Messages._ID + " = " + mId, null); contentValues.clear(); } if(!cursor.getString(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_BODY)) .equals(messageLogRecord.getMessage().getBody())){ contentValues.put(Contract.Messages.COLUMN_NAME_BODY, messageLogRecord.getMessage().getBody()); db.update(Contract.DATABASE_MESSAGES_TABLE, contentValues, Contract.Messages._ID + " = " + mId, null); contentValues.clear(); } if(cursor.getInt(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_CODE)) != messageLogRecord.getMessage().getCode()){ contentValues.put(Contract.Messages.COLUMN_NAME_CODE, messageLogRecord.getMessage().getCode()); db.update(Contract.DATABASE_MESSAGES_TABLE, contentValues, Contract.Messages._ID + " = " + mId, null); contentValues.clear(); } } /** * 查询一条联系人记录 * @param where 条件子句 * @param order to sort * @return 返回一条联系人记录 * @throws SQLException 表示未能从数据库中获得查询结果 */ public Contact getContact(String where, String order) throws SQLException{ ArrayList<Contact> contacts = new ArrayList<Contact>(); contacts = getListsContacts(where, order); return contacts.get(0); } /** * 查询多条联系人记录 * @param where 条件子句 * @param order to sort * @return 返回多条联系人记录 * @throws SQLException 表示未能从数据库中获得查询结果 */ public ArrayList<Contact> getListsContacts(String where, String order) throws SQLException{ ArrayList<Contact> contacts = new ArrayList<Contact>(); Contact contact = new Contact(); Cursor cursor = db.query(Contract.DATABASE_CONTACTS_TABLE, null, where, null, null, null, order); if(cursor.getCount() == 0 || !cursor.moveToFirst()){ throw new SQLException("No record found from database"); }else{ for(int i = 0; i <= cursor.getCount(); i++){ cursor.moveToPosition(i); long mId = cursor.getLong(cursor.getColumnIndex(Contract.Contacts._ID)); String mName = cursor.getString(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_NAME)); String mPhoneNumber = cursor.getString(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_PHONE_NUMBER)); Bitmap mBitmap = BitmapFactory.decodeByteArray( cursor.getBlob(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_PHOTO)), 0, cursor.getBlob(cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_PHOTO)).length); contact.setId(mId); contact.setName(mName); contact.setPhoneNumber(mPhoneNumber); contact.setPhoto(mBitmap); contacts.add(contact.clone()); } } return contacts; } /** * 查询一条信息记录 * @param where 条件子句 * @param order to sort * @return 返回一条信息记录 * @throws SQLException 没有查询成功 */ public MessageLogRecord getMessage(String where, String order) throws SQLException{ ArrayList<MessageLogRecord> messageLogRecords = new ArrayList<MessageLogRecord>(); messageLogRecords = getListsMessages(where, order); return messageLogRecords.get(0); } /** * 查询多条信息记录 * @param where 条件子句 * @param order to sort * @return 返回多条信息记录 * @throws SQLException 没有查询成功 */ public ArrayList<MessageLogRecord> getListsMessages(String where, String order) throws SQLException{ ArrayList<MessageLogRecord> messageLogRecords = new ArrayList<MessageLogRecord>(); MessageLogRecord messageLogRecord = new MessageLogRecord(); Message aMessage = new Message(){ @Override public void send(Context context, Uri messageUri, String dest, String password) { throw new UnsupportedOperationException("unsupport send message. " + "This is a simple storage object."); } @Override public void receive(String receivedMessage, String password) { throw new UnsupportedOperationException("unsupport receive message. " + "This is a simple storage object."); } }; Cursor cursor = db.query(Contract.DATABASE_MESSAGES_TABLE, null, where, null, null, null, order); if(cursor.getCount() == 0 || !cursor.moveToFirst()){ throw new SQLException("No record found from database"); }else{ for(int i= 0; i <= cursor.getCount(); i++){ cursor.moveToPosition(i); long mId = cursor.getLong(cursor.getColumnIndex(Contract.Messages._ID)); long mContactId = cursor.getLong(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_CONTACT_ID)); String mAddress = cursor.getString(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_ADDRESS)); long mTime = cursor.getLong(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_TIME)); String mStatus = cursor.getString(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_STATUS)); String mBody = cursor.getString(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_BODY)); int mCode = cursor.getInt(cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_CODE)); messageLogRecord.setId(mId); messageLogRecord.setContact(getContact(Contract.Contacts._ID + " = " + mContactId, null)); messageLogRecord.setAddress(mAddress); messageLogRecord.setDate(new Date(mTime)); messageLogRecord.setStatus(Status.valueOf(mStatus)); messageLogRecord.setMessage(aMessage.setBody(mBody).setCode(mCode)); messageLogRecords.add(messageLogRecord.clone()); } } return messageLogRecords; } }