1,拨号盘搜索联系人数据库更新
在论述拨号盘搜索联系人之前,首先看下dialer.db数据库的更新, dialer.db数据库路径如下,
一般在data/data 目录下。dialer.db 数据库有4个表单,
主要看smartdial_table和prefix_table 2个表单,
smartdial_table是联系人信息,包括手机和SIM卡的联系人;
prefix_table 主要包含联系人的电话号码以及姓名经过对应转化后的数字。
smartdial_table表如下,
prefix_table表如下,
联系人姓名对应规则其实很简单,例如 abc 对应的就是222.
在DialtactsActivity的onCreate方法中,会对mDialerDatabaseHelper变量进行初始化,
mDialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(this);
然后在onResume方法中,调用DialerDatabaseHelper的startSmartDialUpdateThread方法更新数据库,
mDialerDatabaseHelper.startSmartDialUpdateThread();
startSmartDialUpdateThread方法调用流程图如下,
DialerDatabaseHelper的startSmartDialUpdateThread方法如下,
new SmartDialUpdateAsyncTask().execute();
直接构造SmartDialUpdateAsyncTask对象,并且调用其execute方法。
SmartDialUpdateAsyncTask是DialerDatabaseHelper的内部类,继承于AsyncTask,
private class SmartDialUpdateAsyncTask extends AsyncTask {
简单的实现了doInBackground/onCancelled/onPostExecute 三个方法,
直接看doInBackground方法,直接调用updateSmartDialDatabase方法,
updateSmartDialDatabase();
updateSmartDialDatabase方法的主要逻辑如下,
1,在SharedPreferences中获取上次更新数据库的时间,并且利用该时间查询contacts2.db数据库,如果数据未更新则直接返回,
final SharedPreferences databaseLastUpdateSharedPref = mContext.getSharedPreferences(
DATABASE_LAST_CREATED_SHARED_PREF, Context.MODE_PRIVATE);
final String lastUpdateMillis = String.valueOf(
databaseLastUpdateSharedPref.getLong(LAST_UPDATED_MILLIS, 0));
final Cursor updatedContactCursor = mContext.getContentResolver().query(PhoneQuery.URI,
PhoneQuery.PROJECTION, PhoneQuery.SELECTION,
new String[]{lastUpdateMillis}, null);
•••
2,删除/更新 dialer.db数据库中表的相关信息,
removeDeletedContacts(db, lastUpdateMillis);
removePotentiallyCorruptedContacts(db, lastUpdateMillis);
removeUpdatedContacts(db, updatedContactCursor);
3,调用insertUpdatedContactsAndNumberPrefix方法更新dialer.db 数据库的smartdial_table表和prefix_table表。
insertUpdatedContactsAndNumberPrefix(db, updatedContactCursor, currentMillis);
4,首先从smartdial_table表中查询联系人的姓名,然后调用insertNamePrefixes方法将姓名进行转化,插入prefix_table表中。
final Cursor nameCursor = db.rawQuery(
"SELECT DISTINCT " +SmartDialDbColumns.DISPLAY_NAME_PRIMARY + ", " +
SmartDialDbColumns.CONTACT_ID + " FROM " + Tables.SMARTDIAL_TABLE +
WHERE " + SmartDialDbColumns.LAST_SMARTDIAL_UPDATE_TIME +
" = " + Long.toString(currentMillis), new String[] {});
•••
insertNamePrefixes(db, nameCursor);
•••
5,将更新时间保存在SharedPreferences中,并发出数据库更新的通知,
final SharedPreferences.Editor editor = databaseLastUpdateSharedPref.edit();
editor.putLong(LAST_UPDATED_MILLIS, currentMillis);
editor.commit();
// Notify content observers that smart dial database has been updated.
mContext.getContentResolver().notifyChange(SMART_DIAL_UPDATED_URI, null, false);
当然,在SmartDialCursorLoader中会注册该监听,然后进行处理。
1.1 insertUpdatedContactsAndNumberPrefix
insertUpdatedContactsAndNumberPrefix方法主要逻辑如下,
1,构造插入表单SQL语句,
//构造smartdial_table表单插入语句
final String sqlInsert = "INSERT INTO " + Tables.SMARTDIAL_TABLE + " (" +
•••
final SQLiteStatement insert = db.compileStatement(sqlInsert);
//构造prefix_table表单插入语句
final String numberSqlInsert = "INSERT INTO " + Tables.PREFIX_TABLE + " (" +
•••
final SQLiteStatement numberInsert = db.compileStatement(numberSqlInsert);
2,利用contacts2.db数据库的查询结果的Cursor对象逐条获取联系人的信息
updatedContactCursor.moveToPosition(-1);
while (updatedContactCursor.moveToNext()) {
insert.clearBindings();
•••
首先获取联系人信息插入smartdial_table表单
final String number = updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER);
•••
final String displayName = updatedContactCursor.getString(
PhoneQuery.PHONE_DISPLAY_NAME);
•••
insert.bindLong(1, updatedContactCursor.getLong(PhoneQuery.PHONE_ID));
insert.bindLong(3, updatedContactCursor.getLong(PhoneQuery.PHONE_CONTACT_ID));
insert.bindLong(6, updatedContactCursor.getLong(PhoneQuery.PHONE_PHOTO_ID));
•••
insert.executeInsert();
然后获取号码插入prefix_table表单
final String contactPhoneNumber =
updatedContactCursor.getString(PhoneQuery.PHONE_NUMBER);
final ArrayList<String> numberPrefixes =
SmartDialPrefix.parseToNumberTokens(contactPhoneNumber);
for (String numberPrefix : numberPrefixes) {
numberInsert.bindLong(1, updatedContactCursor.getLong(
PhoneQuery.PHONE_CONTACT_ID));
numberInsert.bindString(2, numberPrefix);
numberInsert.executeInsert();
numberInsert.clearBindings();
}
这样,就完成了smartdial_table表单的更新,以及prefix_table表单联系人号码的更新。
下一个方法就是prefix_table表单联系人姓名的更新。