|
|
|
@ -47,10 +47,12 @@ import java.util.HashSet;
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//声明GTask管理类,封装了对GTask进行管理的一些方法
|
|
|
|
|
public class GTaskManager {
|
|
|
|
|
//通过 getSimpleName()得到类的简写名称。然后赋值给TAG
|
|
|
|
|
private static final String TAG = GTaskManager.class.getSimpleName();
|
|
|
|
|
|
|
|
|
|
//进程状态:用0、1、2、3、4分别表示成功、网络错误、内部错误、同步中、取消同步
|
|
|
|
|
public static final int STATE_SUCCESS = 0;
|
|
|
|
|
|
|
|
|
|
public static final int STATE_NETWORK_ERROR = 1;
|
|
|
|
@ -61,6 +63,7 @@ public class GTaskManager {
|
|
|
|
|
|
|
|
|
|
public static final int STATE_SYNC_CANCELLED = 4;
|
|
|
|
|
|
|
|
|
|
// private 定义一系列不可被外部的类访问的量
|
|
|
|
|
private static GTaskManager mInstance = null;
|
|
|
|
|
|
|
|
|
|
private Activity mActivity;
|
|
|
|
@ -87,6 +90,7 @@ public class GTaskManager {
|
|
|
|
|
|
|
|
|
|
private HashMap<Long, String> mNidToGid;
|
|
|
|
|
|
|
|
|
|
//该类的构造函数
|
|
|
|
|
private GTaskManager() {
|
|
|
|
|
mSyncing = false;
|
|
|
|
|
mCancelled = false;
|
|
|
|
@ -99,6 +103,7 @@ public class GTaskManager {
|
|
|
|
|
mNidToGid = new HashMap<Long, String>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取一个实例,通过GTaskManager()新建一个mInstance
|
|
|
|
|
public static synchronized GTaskManager getInstance() {
|
|
|
|
|
if (mInstance == null) {
|
|
|
|
|
mInstance = new GTaskManager();
|
|
|
|
@ -106,20 +111,25 @@ public class GTaskManager {
|
|
|
|
|
return mInstance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//setActivityContext()用于获取当前的操作并更新至GTask中
|
|
|
|
|
public synchronized void setActivityContext(Activity activity) {
|
|
|
|
|
// used for getting authtoken
|
|
|
|
|
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();
|
|
|
|
@ -132,6 +142,7 @@ public class GTaskManager {
|
|
|
|
|
client.resetUpdateArray();
|
|
|
|
|
|
|
|
|
|
// login google task
|
|
|
|
|
//登录谷歌账号
|
|
|
|
|
if (!mCancelled) {
|
|
|
|
|
if (!client.login(mActivity)) {
|
|
|
|
|
throw new NetworkFailureException("login google task failed");
|
|
|
|
@ -139,10 +150,12 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get the task list from google
|
|
|
|
|
//从谷歌获取任务清单
|
|
|
|
|
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list));
|
|
|
|
|
initGTaskList();
|
|
|
|
|
|
|
|
|
|
// do content sync work
|
|
|
|
|
//获取Google上的JSONtasklist转为本地TaskList
|
|
|
|
|
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing));
|
|
|
|
|
syncContent();
|
|
|
|
|
} catch (NetworkFailureException e) {
|
|
|
|
@ -168,6 +181,7 @@ public class GTaskManager {
|
|
|
|
|
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//初始化GTask列表,将google上的JSONTaskList转为本地任务列表
|
|
|
|
|
private void initGTaskList() throws NetworkFailureException {
|
|
|
|
|
if (mCancelled)
|
|
|
|
|
return;
|
|
|
|
@ -247,6 +261,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//选择同步操作的类型并做好相应准备 具体做法是对每一种情况都把所有的任务判断一次,一旦发现是该种情况,就立即执行任务,否则判断下个任务
|
|
|
|
|
private void syncContent() throws NetworkFailureException {
|
|
|
|
|
int syncType;
|
|
|
|
|
Cursor c = null;
|
|
|
|
@ -260,6 +275,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for local deleted note
|
|
|
|
|
//处理本地删除的note
|
|
|
|
|
try {
|
|
|
|
|
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
|
|
|
|
|
"(type<>? AND parent_id=?)", new String[] {
|
|
|
|
@ -290,6 +306,7 @@ public class GTaskManager {
|
|
|
|
|
syncFolder();
|
|
|
|
|
|
|
|
|
|
// for note existing in database
|
|
|
|
|
//对已经存在与数据库的节点进行同步
|
|
|
|
|
try {
|
|
|
|
|
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
|
|
|
|
|
"(type=? AND parent_id<>?)", new String[] {
|
|
|
|
@ -327,6 +344,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// go through remaining items
|
|
|
|
|
//访问保留的项目
|
|
|
|
|
Iterator<Map.Entry<String, Node>> iter = mGTaskHashMap.entrySet().iterator();
|
|
|
|
|
while (iter.hasNext()) {
|
|
|
|
|
Map.Entry<String, Node> entry = iter.next();
|
|
|
|
@ -337,6 +355,7 @@ public class GTaskManager {
|
|
|
|
|
// mCancelled can be set by another thread, so we neet to check one by
|
|
|
|
|
// one
|
|
|
|
|
// clear local delete table
|
|
|
|
|
//清除本地删除的表格
|
|
|
|
|
if (!mCancelled) {
|
|
|
|
|
if (!DataUtils.batchDeleteNotes(mContentResolver, mLocalDeleteIdMap)) {
|
|
|
|
|
throw new ActionFailureException("failed to batch-delete local deleted notes");
|
|
|
|
@ -351,6 +370,7 @@ public class GTaskManager {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//对文件夹进行同步,具体操作与之前的同步操作一致
|
|
|
|
|
private void syncFolder() throws NetworkFailureException {
|
|
|
|
|
Cursor c = null;
|
|
|
|
|
String gid;
|
|
|
|
@ -362,6 +382,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for root folder
|
|
|
|
|
//同步根目录
|
|
|
|
|
try {
|
|
|
|
|
c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI,
|
|
|
|
|
Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null);
|
|
|
|
@ -391,6 +412,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for call-note folder
|
|
|
|
|
//同步来电记录的文件夹
|
|
|
|
|
try {
|
|
|
|
|
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)",
|
|
|
|
|
new String[] {
|
|
|
|
@ -425,6 +447,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for local existing folders
|
|
|
|
|
//同步已经存在的文件夹
|
|
|
|
|
try {
|
|
|
|
|
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
|
|
|
|
|
"(type=? AND parent_id<>?)", new String[] {
|
|
|
|
@ -461,6 +484,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for remote add folders
|
|
|
|
|
//同步远程添加的文件夹
|
|
|
|
|
Iterator<Map.Entry<String, TaskList>> iter = mGTaskListHashMap.entrySet().iterator();
|
|
|
|
|
while (iter.hasNext()) {
|
|
|
|
|
Map.Entry<String, TaskList> entry = iter.next();
|
|
|
|
@ -476,6 +500,7 @@ public class GTaskManager {
|
|
|
|
|
GTaskClient.getInstance().commitUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//在之前对于各方面的同步操作中多次调用了这个函数,作用是依据不同的同步类型去调用不同的函数,以达到本地与远程同步的实际操作
|
|
|
|
|
private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException {
|
|
|
|
|
if (mCancelled) {
|
|
|
|
|
return;
|
|
|
|
@ -522,12 +547,14 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//增加本地节点的操作,传入参量为待增添的节点
|
|
|
|
|
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)) {
|
|
|
|
@ -555,6 +582,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//以下为判断便签中的数据条目
|
|
|
|
|
if (js.has(GTaskStringUtils.META_HEAD_DATA)) {
|
|
|
|
|
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
|
|
|
|
|
for (int i = 0; i < dataArray.length(); i++) {
|
|
|
|
@ -585,17 +613,21 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create the local node
|
|
|
|
|
//把getGid()获取的node节点Gid,用于设置本地Gtask的ID,然后更新本地便签
|
|
|
|
|
sqlNote.setGtaskId(node.getGid());
|
|
|
|
|
sqlNote.commit(false);
|
|
|
|
|
|
|
|
|
|
// update gid-nid mapping
|
|
|
|
|
//更新gid与nid的映射表
|
|
|
|
|
mGidToNid.put(node.getGid(), sqlNote.getId());
|
|
|
|
|
mNidToGid.put(sqlNote.getId(), node.getGid());
|
|
|
|
|
|
|
|
|
|
// update meta
|
|
|
|
|
//更新本地节点
|
|
|
|
|
updateRemoteMeta(node.getGid(), sqlNote);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新本地节点,两个传入参数,一个是待更新的节点,一个是指向待增加位置的指针
|
|
|
|
|
private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException {
|
|
|
|
|
if (mCancelled) {
|
|
|
|
|
return;
|
|
|
|
@ -616,9 +648,11 @@ public class GTaskManager {
|
|
|
|
|
sqlNote.commit(true);
|
|
|
|
|
|
|
|
|
|
// update meta info
|
|
|
|
|
//升级meta
|
|
|
|
|
updateRemoteMeta(node.getGid(), sqlNote);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//这个函数是添加远程结点,参数node是要添加远程结点的本地结点,c是数据库的指针
|
|
|
|
|
private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException {
|
|
|
|
|
if (mCancelled) {
|
|
|
|
|
return;
|
|
|
|
@ -628,6 +662,7 @@ public class GTaskManager {
|
|
|
|
|
Node n;
|
|
|
|
|
|
|
|
|
|
// update remotely
|
|
|
|
|
// 如果sqlNote是节点类型,则设置好它的参数以及更新哈希表,再把节点更新到远程数据里
|
|
|
|
|
if (sqlNote.isNoteType()) {
|
|
|
|
|
Task task = new Task();
|
|
|
|
|
task.setContentByLocalJSON(sqlNote.getContent());
|
|
|
|
@ -648,6 +683,7 @@ public class GTaskManager {
|
|
|
|
|
TaskList tasklist = null;
|
|
|
|
|
|
|
|
|
|
// we need to skip folder if it has already existed
|
|
|
|
|
//当文件夹存在则跳过,若不存在则创建新的文件夹
|
|
|
|
|
String folderName = GTaskStringUtils.MIUI_FOLDER_PREFFIX;
|
|
|
|
|
if (sqlNote.getId() == Notes.ID_ROOT_FOLDER)
|
|
|
|
|
folderName += GTaskStringUtils.FOLDER_DEFAULT;
|
|
|
|
@ -672,6 +708,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// no match we can add now
|
|
|
|
|
//若没有匹配的任务列表,则创建一个新的任务列表
|
|
|
|
|
if (tasklist == null) {
|
|
|
|
|
tasklist = new TaskList();
|
|
|
|
|
tasklist.setContentByLocalJSON(sqlNote.getContent());
|
|
|
|
@ -682,16 +719,19 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// update local note
|
|
|
|
|
//进行本地节点的更新
|
|
|
|
|
sqlNote.setGtaskId(n.getGid());
|
|
|
|
|
sqlNote.commit(false);
|
|
|
|
|
sqlNote.resetLocalModified();
|
|
|
|
|
sqlNote.commit(true);
|
|
|
|
|
|
|
|
|
|
// gid-id mapping
|
|
|
|
|
//进行gid与nid映射关系的更新
|
|
|
|
|
mGidToNid.put(n.getGid(), sqlNote.getId());
|
|
|
|
|
mNidToGid.put(sqlNote.getId(), n.getGid());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新远程结点,node是要更新的结点,c是数据库的指针
|
|
|
|
|
private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException {
|
|
|
|
|
if (mCancelled) {
|
|
|
|
|
return;
|
|
|
|
@ -700,13 +740,16 @@ public class GTaskManager {
|
|
|
|
|
SqlNote sqlNote = new SqlNote(mContext, c);
|
|
|
|
|
|
|
|
|
|
// update remotely
|
|
|
|
|
//远程更新
|
|
|
|
|
node.setContentByLocalJSON(sqlNote.getContent());
|
|
|
|
|
GTaskClient.getInstance().addUpdateNode(node);
|
|
|
|
|
|
|
|
|
|
// update meta
|
|
|
|
|
//更新元数据
|
|
|
|
|
updateRemoteMeta(node.getGid(), sqlNote);
|
|
|
|
|
|
|
|
|
|
// move task if necessary
|
|
|
|
|
//判断节点类型是否符合要求
|
|
|
|
|
if (sqlNote.isNoteType()) {
|
|
|
|
|
Task task = (Task) node;
|
|
|
|
|
TaskList preParentList = task.getParent();
|
|
|
|
@ -726,10 +769,12 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// clear local modified flag
|
|
|
|
|
//清除本地修改标记
|
|
|
|
|
sqlNote.resetLocalModified();
|
|
|
|
|
sqlNote.commit(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新远程的元数据节点
|
|
|
|
|
private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException {
|
|
|
|
|
if (sqlNote != null && sqlNote.isNoteType()) {
|
|
|
|
|
MetaData metaData = mMetaHashMap.get(gid);
|
|
|
|
@ -746,6 +791,7 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//刷新本地便签ID,从远程同步
|
|
|
|
|
private void refreshLocalSyncId() throws NetworkFailureException {
|
|
|
|
|
if (mCancelled) {
|
|
|
|
|
return;
|
|
|
|
@ -758,6 +804,10 @@ public class GTaskManager {
|
|
|
|
|
initGTaskList();
|
|
|
|
|
|
|
|
|
|
Cursor c = null;
|
|
|
|
|
//query语句:五个参数,NoteColumns.TYPE + " DESC"-----为按类型递减顺序返回查询结果。
|
|
|
|
|
// newString[{String.valueOf(Notes.TYPE_SYSTEM),String.valueOf(Notes.ID_TRASH_FOLER)}
|
|
|
|
|
//------ 为选择参数。"(type<>? AND parent_id<>?)"-------指明返回行过滤器。SqlNote.PROJECTION_NOTE
|
|
|
|
|
//-------- 应返回的数据列的名字。Notes.CONTENT_NOTE_URI--------contentProvider包含所有数据集所对应的uri
|
|
|
|
|
try {
|
|
|
|
|
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
|
|
|
|
|
"(type<>? AND parent_id<>?)", new String[] {
|
|
|
|
@ -790,10 +840,12 @@ public class GTaskManager {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//string类化getSyncAccount()
|
|
|
|
|
public String getSyncAccount() {
|
|
|
|
|
return GTaskClient.getInstance().getSyncAccount().name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//取消同步,置mCancelled为true
|
|
|
|
|
public void cancelSync() {
|
|
|
|
|
mCancelled = true;
|
|
|
|
|
}
|
|
|
|
|