diff --git a/gtask/GTaskManager.java b/gtask/GTaskManager.java deleted file mode 100644 index bb86b16..0000000 --- a/gtask/GTaskManager.java +++ /dev/null @@ -1,824 +0,0 @@ - -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * 授权协议:Apache License, 版本 2.0("许可证"); - * 除非遵守许可证,否则不得使用本文件。 - * 您可以在以下网址获取许可证副本: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 除非适用法律要求或书面同意,根据许可证分发的软件按"原样"提供, - * 不附带任何明示或暗示的保证或条件。请参阅许可证,了解具体的权限和限制。 - */ - -package net.micode.notes.gtask.remote; - -import android.app.Activity; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.util.Log; - -import net.micode.notes.R; -import net.micode.notes.data.Notes; -import net.micode.notes.data.Notes.DataColumns; -import net.micode.notes.data.Notes.NoteColumns; -import net.micode.notes.gtask.data.MetaData; -import net.micode.notes.gtask.data.Node; -import net.micode.notes.gtask.data.SqlNote; -import net.micode.notes.gtask.data.Task; -import net.micode.notes.gtask.data.TaskList; -import net.micode.notes.gtask.exception.ActionFailureException; -import net.micode.notes.gtask.exception.NetworkFailureException; -import net.micode.notes.tool.DataUtils; -import net.micode.notes.tool.GTaskStringUtils; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; - - -public class GTaskManager { - private static final String TAG = GTaskManager.class.getSimpleName(); - - // 同步状态:成功 - public static final int STATE_SUCCESS = 0; - // 同步状态:网络错误 - public static final int STATE_NETWORK_ERROR = 1; - // 同步状态:内部错误 - public static final int STATE_INTERNAL_ERROR = 2; - // 同步状态:同步进行中 - public static final int STATE_SYNC_IN_PROGRESS = 3; - // 同步状态:同步已取消 - public static final int STATE_SYNC_CANCELLED = 4; - - private static GTaskManager mInstance = null; - - // 用于获取认证令牌的Activity - private Activity mActivity; - // 上下文环境 - private Context mContext; - // 内容解析器 - private ContentResolver mContentResolver; - // 同步进行中标志 - private boolean mSyncing; - // 同步取消标志 - private boolean mCancelled; - // 存储从Google获取的任务列表(键为GID) - private HashMap mGTaskListHashMap; - // 存储从Google获取的任务节点(键为GID) - private HashMap mGTaskHashMap; - // 存储元数据(键为关联的GID) - private HashMap mMetaHashMap; - // 元数据列表 - private TaskList mMetaList; - // 本地已删除笔记的ID集合 - private HashSet mLocalDeleteIdMap; - // GID到本地ID的映射 - private HashMap mGidToNid; - // 本地ID到GID的映射 - private HashMap mNidToGid; - - private GTaskManager() { - mSyncing = false; - mCancelled = false; - mGTaskListHashMap = new HashMap(); - mGTaskHashMap = new HashMap(); - mMetaHashMap = new HashMap(); - mMetaList = null; - mLocalDeleteIdMap = new HashSet(); - mGidToNid = new HashMap(); - mNidToGid = new HashMap(); - } - - // 获取单例实例 - public static synchronized GTaskManager getInstance() { - if (mInstance == null) { - mInstance = new GTaskManager(); - } - return mInstance; - } - - // 设置Activity上下文(用于获取认证令牌) - public synchronized void setActivityContext(Activity activity) { - mActivity = activity; - } - - // 执行同步操作 - public int sync(Context context, GTaskASyncTask asyncTask) { - if (mSyncing) { - Log.d(TAG, "Sync is in progress"); - return STATE_SYNC_IN_PROGRESS; - } - mContext = context; - mContentResolver = mContext.getContentResolver(); - mSyncing = true; - mCancelled = false; - // 清空各类映射和集合 - mGTaskListHashMap.clear(); - mGTaskHashMap.clear(); - mMetaHashMap.clear(); - mLocalDeleteIdMap.clear(); - mGidToNid.clear(); - mNidToGid.clear(); - - try { - GTaskClient client = GTaskClient.getInstance(); - client.resetUpdateArray(); - - // 登录Google任务 - if (!mCancelled) { - if (!client.login(mActivity)) { - throw new NetworkFailureException("login google task failed"); - } - } - - // 从Google获取任务列表并初始化 - asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list)); - initGTaskList(); - - // 执行内容同步 - asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing)); - syncContent(); - } catch (NetworkFailureException e) { - Log.e(TAG, e.toString()); - return STATE_NETWORK_ERROR; - } catch (ActionFailureException e) { - Log.e(TAG, e.toString()); - return STATE_INTERNAL_ERROR; - } catch (Exception e) { - Log.e(TAG, e.toString()); - e.printStackTrace(); - return STATE_INTERNAL_ERROR; - } finally { - // 清理资源 - mGTaskListHashMap.clear(); - mGTaskHashMap.clear(); - mMetaHashMap.clear(); - mLocalDeleteIdMap.clear(); - mGidToNid.clear(); - mNidToGid.clear(); - mSyncing = false; - } - - return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS; - } - - // 初始化Google任务列表 - private void initGTaskList() throws NetworkFailureException { - if (mCancelled) - return; - GTaskClient client = GTaskClient.getInstance(); - try { - JSONArray jsTaskLists = client.getTaskLists(); - - // 先初始化元数据列表 - mMetaList = null; - for (int i = 0; i < jsTaskLists.length(); i++) { - JSONObject object = jsTaskLists.getJSONObject(i); - String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); - String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME); - - // 处理元数据文件夹 - if (name.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META)) { - mMetaList = new TaskList(); - mMetaList.setContentByRemoteJSON(object); - - // 加载元数据 - JSONArray jsMetas = client.getTaskList(gid); - for (int j = 0; j < jsMetas.length(); j++) { - object = (JSONObject) jsMetas.getJSONObject(j); - MetaData metaData = new MetaData(); - metaData.setContentByRemoteJSON(object); - if (metaData.isWorthSaving()) { - mMetaList.addChildTask(metaData); - if (metaData.getGid() != null) { - mMetaHashMap.put(metaData.getRelatedGid(), metaData); - } - } - } - } - } - - // 如果元数据列表不存在则创建 - if (mMetaList == null) { - mMetaList = new TaskList(); - mMetaList.setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META); - GTaskClient.getInstance().createTaskList(mMetaList); - } - - // 初始化普通任务列表 - for (int i = 0; i < jsTaskLists.length(); i++) { - JSONObject object = jsTaskLists.getJSONObject(i); - String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); - String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME); - - // 过滤系统文件夹并处理用户自定义文件夹 - if (name.startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX) - && !name.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META)) { - TaskList tasklist = new TaskList(); - tasklist.setContentByRemoteJSON(object); - mGTaskListHashMap.put(gid, tasklist); - mGTaskHashMap.put(gid, tasklist); - - // 加载任务列表中的任务 - JSONArray jsTasks = client.getTaskList(gid); - for (int j = 0; j < jsTasks.length(); j++) { - object = (JSONObject) jsTasks.getJSONObject(j); - gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); - Task task = new Task(); - task.setContentByRemoteJSON(object); - if (task.isWorthSaving()) { - task.setMetaInfo(mMetaHashMap.get(gid)); - tasklist.addChildTask(task); - mGTaskHashMap.put(gid, task); - } - } - } - } - } catch (JSONException e) { - Log.e(TAG, e.toString()); - e.printStackTrace(); - throw new ActionFailureException("initGTaskList: handing JSONObject failed"); - } - } - - // 同步内容(包括笔记和文件夹) - private void syncContent() throws NetworkFailureException { - int syncType; - Cursor c = null; - String gid; - Node node; - - mLocalDeleteIdMap.clear(); - - if (mCancelled) { - return; - } - - // 处理本地已删除的笔记(存在于回收站中) - try { - c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, - "(type<>? AND parent_id=?)", new String[]{ - String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER) - }, null); - if (c != null) { - while (c.moveToNext()) { - gid = c.getString(SqlNote.GTASK_ID_COLUMN); - node = mGTaskHashMap.get(gid); - if (node != null) { - mGTaskHashMap.remove(gid); - // 执行远程删除操作 - doContentSync(Node.SYNC_ACTION_DEL_REMOTE, node, c); - } - - mLocalDeleteIdMap.add(c.getLong(SqlNote.ID_COLUMN)); - } - } else { - Log.w(TAG, "failed to query trash folder"); - } - } finally { - if (c != null) { - c.close(); - c = null; - } - } - - // 先同步文件夹 - syncFolder(); - - // 处理数据库中存在的普通笔记 - try { - c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, - "(type=? AND parent_id<>?)", new String[]{ - String.valueOf(Notes.TYPE_NOTE), String.valueOf(Notes.ID_TRASH_FOLER) - }, NoteColumns.TYPE + " DESC"); - if (c != null) { - while (c.moveToNext()) { - gid = c.getString(SqlNote.GTASK_ID_COLUMN); - node = mGTaskHashMap.get(gid); - if (node != null) { - mGTaskHashMap.remove(gid); - mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN)); - mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid); - syncType = node.getSyncAction(c); - } else { - if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { - // 本地新增笔记,需同步到远程 - syncType = Node.SYNC_ACTION_ADD_REMOTE; - } else { - // 远程已删除,本地需删除 - syncType = Node.SYNC_ACTION_DEL_LOCAL; - } - } - doContentSync(syncType, node, c); - } - } else { - Log.w(TAG, "failed to query existing note in database"); - } - - } finally { - if (c != null) { - c.close(); - c = null; - } - } - - // 处理剩余的远程任务(本地不存在的远程任务,需新增到本地) - Iterator> iter = mGTaskHashMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - node = entry.getValue(); - doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); - } - - // 检查取消状态并清理本地删除记录 - if (!mCancelled) { - if (!DataUtils.batchDeleteNotes(mContentResolver, mLocalDeleteIdMap)) { - throw new ActionFailureException("failed to batch-delete local deleted notes"); - } - } - - // 提交更新并刷新本地同步ID - if (!mCancelled) { - GTaskClient.getInstance().commitUpdate(); - refreshLocalSyncId(); - } - - } - - // 同步文件夹(包括系统文件夹和用户自定义文件夹) - private void syncFolder() throws NetworkFailureException { - Cursor c = null; - String gid; - Node node; - int syncType; - - if (mCancelled) { - return; - } - - // 处理根文件夹(系统文件夹) - try { - c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, - Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null); - if (c != null) { - c.moveToNext(); - gid = c.getString(SqlNote.GTASK_ID_COLUMN); - node = mGTaskHashMap.get(gid); - if (node != null) { - mGTaskHashMap.remove(gid); - mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER); - mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid); - // 仅在名称变更时更新远程名称 - if (!node.getName().equals( - GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) - doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); - } else { - // 本地不存在,需新增到远程 - doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c); - } - } else { - Log.w(TAG, "failed to query root folder"); - } - } finally { - if (c != null) { - c.close(); - c = null; - } - } - - // 处理通话记录文件夹(系统文件夹) - try { - c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)", - new String[]{ - String.valueOf(Notes.ID_CALL_RECORD_FOLDER) - }, null); - if (c != null) { - if (c.moveToNext()) { - gid = c.getString(SqlNote.GTASK_ID_COLUMN); - node = mGTaskHashMap.get(gid); - if (node != null) { - mGTaskHashMap.remove(gid); - mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER); - mNidToGid.put((long) Notes.ID_CALL_RECORD_FOLDER, gid); - // 仅在名称变更时更新远程名称 - if (!node.getName().equals( - GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) - doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); - } else { - // 本地不存在,需新增到远程 - doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c); - } - } - } else { - Log.w(TAG, "failed to query call note folder"); - } - } finally { - if (c != null) { - c.close(); - c = null; - } - } - - // 处理用户自定义文件夹 - try { - c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, - "(type=? AND parent_id<>?)", new String[]{ - String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER) - }, NoteColumns.TYPE + " DESC"); - if (c != null) { - while (c.moveToNext()) { - gid = c.getString(SqlNote.GTASK_ID_COLUMN); - node = mGTaskHashMap.get(gid); - if (node != null) { - mGTaskHashMap.remove(gid); - mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN)); - mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid); - syncType = node.getSyncAction(c); - } else { - if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { - // 本地新增文件夹,需同步到远程 - syncType = Node.SYNC_ACTION_ADD_REMOTE; - } else { - // 远程已删除,本地需删除 - syncType = Node.SYNC_ACTION_DEL_LOCAL; - } - } - doContentSync(syncType, node, c); - } - } else { - Log.w(TAG, "failed to query existing folder"); - } - } finally { - if (c != null) { - c.close(); - c = null; - } - } - - // 处理远程新增的文件夹(本地不存在的远程文件夹,需新增到本地) - Iterator> iter = mGTaskListHashMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - gid = entry.getKey(); - node = entry.getValue(); - if (mGTaskHashMap.containsKey(gid)) { - mGTaskHashMap.remove(gid); - doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); - } - } - - if (!mCancelled) - GTaskClient.getInstance().commitUpdate(); - } - - // 执行具体的内容同步操作 - private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException { - if (mCancelled) { - return; - } - - MetaData meta; - switch (syncType) { - case Node.SYNC_ACTION_ADD_LOCAL: - // 新增远程任务到本地 - addLocalNode(node); - break; - case Node.SYNC_ACTION_ADD_REMOTE: - // 新增本地任务到远程 - addRemoteNode(node, c); - break; - case Node.SYNC_ACTION_DEL_LOCAL: - // 删除本地任务(远程已删除) - meta = mMetaHashMap.get(c.getString(SqlNote.GTASK_ID_COLUMN)); - if (meta != null) { - GTaskClient.getInstance().deleteNode(meta); - } - mLocalDeleteIdMap.add(c.getLong(SqlNote.ID_COLUMN)); - break; - case Node.SYNC_ACTION_DEL_REMOTE: - // 删除远程任务(本地已删除) - meta = mMetaHashMap.get(node.getGid()); - if (meta != null) { - GTaskClient.getInstance().deleteNode(meta); - } - GTaskClient.getInstance().deleteNode(node); - break; - case Node.SYNC_ACTION_UPDATE_LOCAL: - // 更新本地任务(远程已修改) - updateLocalNode(node, c); - break; - case Node.SYNC_ACTION_UPDATE_REMOTE: - // 更新远程任务(本地已修改) - updateRemoteNode(node, c); - break; - case Node.SYNC_ACTION_UPDATE_CONFLICT: - // 冲突处理:使用本地修改覆盖远程 - updateRemoteNode(node, c); - break; - case Node.SYNC_ACTION_NONE: - break; - case Node.SYNC_ACTION_ERROR: - default: - throw new ActionFailureException("unkown sync action type"); - } - } - - // 新增远程任务到本地数据库 - private void addLocalNode(Node node) throws NetworkFailureException { - if (mCancelled) { - return; - } - - SqlNote sqlNote; - if (node instanceof TaskList) { - // 处理系统文件夹 - if (node.getName().equals( - GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) { - sqlNote = new SqlNote(mContext, Notes.ID_ROOT_FOLDER); - } else if (node.getName().equals( - GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) { - sqlNote = new SqlNote(mContext, Notes.ID_CALL_RECORD_FOLDER); - } else { - // 普通文件夹 - sqlNote = new SqlNote(mContext); - sqlNote.setContent(node.getLocalJSONFromContent()); - sqlNote.setParentId(Notes.ID_ROOT_FOLDER); - } - } else { - // 普通任务 - sqlNote = new SqlNote(mContext); - JSONObject js = node.getLocalJSONFromContent(); - try { - // 处理笔记ID冲突 - if (js.has(GTaskStringUtils.META_HEAD_NOTE)) { - JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); - if (note.has(NoteColumns.ID)) { - long id = note.getLong(NoteColumns.ID); - if (DataUtils.existInNoteDatabase(mContentResolver, id)) { - note.remove(NoteColumns.ID); - } - } - } - - // 处理数据项ID冲突 - if (js.has(GTaskStringUtils.META_HEAD_DATA)) { - JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); - for (int i = 0; i < dataArray.length(); i++) { - JSONObject data = dataArray.getJSONObject(i); - if (data.has(DataColumns.ID)) { - long dataId = data.getLong(DataColumns.ID); - if (DataUtils.existInDataDatabase(mContentResolver, dataId)) { - data.remove(DataColumns.ID); - } - } - } - - } - } catch (JSONException e) { - Log.w(TAG, e.toString()); - e.printStackTrace(); - } - sqlNote.setContent(js); - - // 获取父文件夹ID - Long parentId = mGidToNid.get(((Task) node).getParent().getGid()); - if (parentId == null) { - Log.e(TAG, "cannot find task's parent id locally"); - throw new ActionFailureException("cannot add local node"); - } - sqlNote.setParentId(parentId.longValue()); - } - - // 提交到本地数据库 - sqlNote.setGtaskId(node.getGid()); - sqlNote.commit(false); - - // 更新ID映射 - mGidToNid.put(node.getGid(), sqlNote.getId()); - mNidToGid.put(sqlNote.getId(), node.getGid()); - - // 更新元数据 - updateRemoteMeta(node.getGid(), sqlNote); - } - - // 更新本地任务(基于远程数据) - private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException { - if (mCancelled) { - return; - } - - SqlNote sqlNote = new SqlNote(mContext, c); - sqlNote.setContent(node.getLocalJSONFromContent()); - - // 获取父文件夹ID - Long parentId = (node instanceof Task) ? mGidToNid.get(((Task) node).getParent().getGid()) - : new Long(Notes.ID_ROOT_FOLDER); - if (parentId == null) { - Log.e(TAG, "cannot find task's parent id locally"); - throw new ActionFailureException("cannot update local node"); - } - sqlNote.setParentId(parentId.longValue()); - sqlNote.commit(true); - - // 更新元数据 - updateRemoteMeta(node.getGid(), sqlNote); - } - - // 新增本地任务到远程服务器 - private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException { - if (mCancelled) { - return; - } - - SqlNote sqlNote = new SqlNote(mContext, c); - Node n; - - // 处理普通笔记 - if (sqlNote.isNoteType()) { - Task task = new Task(); - task.setContentByLocalJSON(sqlNote.getContent()); - - // 获取父任务列表GID - String parentGid = mNidToGid.get(sqlNote.getParentId()); - if (parentGid == null) { - Log.e(TAG, "cannot find task's parent tasklist"); - throw new ActionFailureException("cannot add remote task"); - } - mGTaskListHashMap.get(parentGid).addChildTask(task); - - // 创建远程任务 - GTaskClient.getInstance().createTask(task); - n = (Node) task; - - // 添加元数据 - updateRemoteMeta(task.getGid(), sqlNote); - } else { - // 处理文件夹 - TaskList tasklist = null; - String folderName = GTaskStringUtils.MIUI_FOLDER_PREFFIX; - if (sqlNote.getId() == Notes.ID_ROOT_FOLDER) - folderName += GTaskStringUtils.FOLDER_DEFAULT; - else if (sqlNote.getId() == Notes.ID_CALL_RECORD_FOLDER) - folderName += GTaskStringUtils.FOLDER_CALL_NOTE; - else - folderName += sqlNote.getSnippet(); - - // 检查文件夹是否已存在 - Iterator> iter = mGTaskListHashMap.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - String gid = entry.getKey(); - TaskList list = entry.getValue(); - - if (list.getName().equals(folderName)) { - tasklist = list; - if (mGTaskHashMap.containsKey(gid)) { - mGTaskHashMap.remove(gid); - } - break; - } - } - - // 不存在则创建新文件夹 - if (tasklist == null) { - tasklist = new TaskList(); - tasklist.setContentByLocalJSON(sqlNote.getContent()); - GTaskClient.getInstance().createTaskList(tasklist); - mGTaskListHashMap.put(tasklist.getGid(), tasklist); - } - n = (Node) tasklist; - } - - // 更新本地笔记的GID - sqlNote.setGtaskId(n.getGid()); - sqlNote.commit(false); - sqlNote.resetLocalModified(); - sqlNote.commit(true); - - // 更新ID映射 - mGidToNid.put(n.getGid(), sqlNote.getId()); - mNidToGid.put(sqlNote.getId(), n.getGid()); - } - - // 更新远程任务(基于本地数据) - private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException { - if (mCancelled) { - return; - } - - SqlNote sqlNote = new SqlNote(mContext, c); - - // 更新远程任务内容 - node.setContentByLocalJSON(sqlNote.getContent()); - GTaskClient.getInstance().addUpdateNode(node); - - // 更新元数据 - updateRemoteMeta(node.getGid(), sqlNote); - - // 处理任务移动(如果父文件夹变更) - if (sqlNote.isNoteType()) { - Task task = (Task) node; - TaskList preParentList = task.getParent(); - - String curParentGid = mNidToGid.get(sqlNote.getParentId()); - if (curParentGid == null) { - Log.e(TAG, "cannot find task's parent tasklist"); - throw new ActionFailureException("cannot update remote task"); - } - TaskList curParentList = mGTaskListHashMap.get(curParentGid); - - if (preParentList != curParentList) { - preParentList.removeChildTask(task); - curParentList.addChildTask(task); - GTaskClient.getInstance().moveTask(task, preParentList, curParentList); - } - } - - // 清除本地修改标志 - sqlNote.resetLocalModified(); - sqlNote.commit(true); - } - - // 更新远程元数据 - private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException { - if (sqlNote != null && sqlNote.isNoteType()) { - MetaData metaData = mMetaHashMap.get(gid); - if (metaData != null) { - metaData.setMeta(gid, sqlNote.getContent()); - GTaskClient.getInstance().addUpdateNode(metaData); - } else { - metaData = new MetaData(); - metaData.setMeta(gid, sqlNote.getContent()); - mMetaList.addChildTask(metaData); - mMetaHashMap.put(gid, metaData); - GTaskClient.getInstance().createTask(metaData); - } - } - } - - // 刷新本地同步ID(更新笔记的最后同步时间) - private void refreshLocalSyncId() throws NetworkFailureException { - if (mCancelled) { - return; - } - - // 重新获取最新任务列表 - mGTaskHashMap.clear(); - mGTaskListHashMap.clear(); - mMetaHashMap.clear(); - initGTaskList(); - - Cursor c = null; - try { - c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, - "(type<>? AND parent_id<>?)", new String[]{ - String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER) - }, NoteColumns.TYPE + " DESC"); - if (c != null) { - while (c.moveToNext()) { - String gid = c.getString(SqlNote.GTASK_ID_COLUMN); - Node node = mGTaskHashMap.get(gid); - if (node != null) { - mGTaskHashMap.remove(gid); - ContentValues values = new ContentValues(); - values.put(NoteColumns.SYNC_ID, node.getLastModified()); - // 更新本地同步ID - mContentResolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, - c.getLong(SqlNote.ID_COLUMN)), values, null, null); - } else { - Log.e(TAG, "something is missed"); - throw new ActionFailureException( - "some local items don't have gid after sync"); - } - } - } else { - Log.w(TAG, "failed to query local note to refresh sync id"); - } - } finally { - if (c != null) { - c.close(); - c = null; - } - } - } - - // 获取同步账户名 - public String getSyncAccount() { - return GTaskClient.getInstance().getSyncAccount().name; - } - - // 取消同步 - public void cancelSync() { - mCancelled = true; - } -} \ No newline at end of file