@ -48,45 +48,34 @@ import java.util.Iterator;
import java.util.Map ;
import java.util.Map ;
// Google任务管理器类, 负责同步逻辑
public class GTaskManager {
public class GTaskManager {
private static final String TAG = GTaskManager . class . getSimpleName ( ) ;
private static final String TAG = GTaskManager . class . getSimpleName ( ) ;
public static final int STATE_SUCCESS = 0 ;
// 同步状态常量
public static final int STATE_SUCCESS = 0 ; // 同步成功
public static final int STATE_NETWORK_ERROR = 1 ;
public static final int STATE_NETWORK_ERROR = 1 ; // 网络错误
public static final int STATE_INTERNAL_ERROR = 2 ; // 内部错误
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 ; // 同步已取消
public static final int STATE_SYNC_IN_PROGRESS = 3 ;
private static GTaskManager mInstance = null ; // 单例实例
public static final int STATE_SYNC_CANCELLED = 4 ;
private Activity mActivity ; // Activity上下文( 用于获取认证token)
private Context mContext ; // 应用上下文
private static GTaskManager mInstance = null ;
private ContentResolver mContentResolver ; // 内容解析器
private boolean mSyncing ; // 同步状态标志
private Activity mActivity ;
private boolean mCancelled ; // 取消同步标志
private Context mContext ;
// 数据存储相关HashMap
private HashMap < String , TaskList > mGTaskListHashMap ; // 任务列表HashMap
private ContentResolver mContentResolver ;
private HashMap < String , Node > mGTaskHashMap ; // 节点HashMap
private HashMap < String , MetaData > mMetaHashMap ; // 元数据HashMap
private boolean mSyncing ;
private TaskList mMetaList ; // 元数据列表
private HashSet < Long > mLocalDeleteIdMap ; // 本地删除ID集合
private boolean mCancelled ;
private HashMap < String , Long > mGidToNid ; // Google ID到本地ID的映射
private HashMap < Long , String > mNidToGid ; // 本地ID到Google ID的映射
private HashMap < String , TaskList > mGTaskListHashMap ;
// 私有构造函数
private HashMap < String , Node > mGTaskHashMap ;
private HashMap < String , MetaData > mMetaHashMap ;
private TaskList mMetaList ;
private HashSet < Long > mLocalDeleteIdMap ;
private HashMap < String , Long > mGidToNid ;
private HashMap < Long , String > mNidToGid ;
private GTaskManager ( ) {
private GTaskManager ( ) {
mSyncing = false ;
mSyncing = false ;
mCancelled = false ;
mCancelled = false ;
@ -99,6 +88,7 @@ public class GTaskManager {
mNidToGid = new HashMap < Long , String > ( ) ;
mNidToGid = new HashMap < Long , String > ( ) ;
}
}
// 获取单例实例
public static synchronized GTaskManager getInstance ( ) {
public static synchronized GTaskManager getInstance ( ) {
if ( mInstance = = null ) {
if ( mInstance = = null ) {
mInstance = new GTaskManager ( ) ;
mInstance = new GTaskManager ( ) ;
@ -106,11 +96,13 @@ public class GTaskManager {
return mInstance ;
return mInstance ;
}
}
// 设置Activity上下文
public synchronized void setActivityContext ( Activity activity ) {
public synchronized void setActivityContext ( Activity activity ) {
// used for getting auth token
// 用于获取认证 token
mActivity = activity ;
mActivity = activity ;
}
}
// 执行同步操作
public int sync ( Context context , GTaskASyncTask asyncTask ) {
public int sync ( Context context , GTaskASyncTask asyncTask ) {
if ( mSyncing ) {
if ( mSyncing ) {
Log . d ( TAG , "Sync is in progress" ) ;
Log . d ( TAG , "Sync is in progress" ) ;
@ -120,6 +112,7 @@ public class GTaskManager {
mContentResolver = mContext . getContentResolver ( ) ;
mContentResolver = mContext . getContentResolver ( ) ;
mSyncing = true ;
mSyncing = true ;
mCancelled = false ;
mCancelled = false ;
// 清空所有临时数据存储
mGTaskListHashMap . clear ( ) ;
mGTaskListHashMap . clear ( ) ;
mGTaskHashMap . clear ( ) ;
mGTaskHashMap . clear ( ) ;
mMetaHashMap . clear ( ) ;
mMetaHashMap . clear ( ) ;
@ -131,18 +124,18 @@ public class GTaskManager {
GTaskClient client = GTaskClient . getInstance ( ) ;
GTaskClient client = GTaskClient . getInstance ( ) ;
client . resetUpdateArray ( ) ;
client . resetUpdateArray ( ) ;
// login google task
// 1. 登录Google任务服务
if ( ! mCancelled ) {
if ( ! mCancelled ) {
if ( ! client . login ( mActivity ) ) {
if ( ! client . login ( mActivity ) ) {
throw new NetworkFailureException ( "login google task failed" ) ;
throw new NetworkFailureException ( "login google task failed" ) ;
}
}
}
}
// get the task list from google
// 2. 初始化Google任务列表
asyncTask . publishProgess ( mContext . getString ( R . string . sync_progress_init_list ) ) ;
asyncTask . publishProgess ( mContext . getString ( R . string . sync_progress_init_list ) ) ;
initGTaskList ( ) ;
initGTaskList ( ) ;
// do content sync work
// 3. 同步内容
asyncTask . publishProgess ( mContext . getString ( R . string . sync_progress_syncing ) ) ;
asyncTask . publishProgess ( mContext . getString ( R . string . sync_progress_syncing ) ) ;
syncContent ( ) ;
syncContent ( ) ;
} catch ( NetworkFailureException e ) {
} catch ( NetworkFailureException e ) {
@ -156,6 +149,7 @@ public class GTaskManager {
e . printStackTrace ( ) ;
e . printStackTrace ( ) ;
return STATE_INTERNAL_ERROR ;
return STATE_INTERNAL_ERROR ;
} finally {
} finally {
// 清理临时数据
mGTaskListHashMap . clear ( ) ;
mGTaskListHashMap . clear ( ) ;
mGTaskHashMap . clear ( ) ;
mGTaskHashMap . clear ( ) ;
mMetaHashMap . clear ( ) ;
mMetaHashMap . clear ( ) ;
@ -168,6 +162,7 @@ public class GTaskManager {
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS ;
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS ;
}
}
// 初始化Google任务列表
private void initGTaskList ( ) throws NetworkFailureException {
private void initGTaskList ( ) throws NetworkFailureException {
if ( mCancelled )
if ( mCancelled )
return ;
return ;
@ -175,7 +170,7 @@ public class GTaskManager {
try {
try {
JSONArray jsTaskLists = client . getTaskLists ( ) ;
JSONArray jsTaskLists = client . getTaskLists ( ) ;
// init meta list first
// 1. 首先初始化元数据列表
mMetaList = null ;
mMetaList = null ;
for ( int i = 0 ; i < jsTaskLists . length ( ) ; i + + ) {
for ( int i = 0 ; i < jsTaskLists . length ( ) ; i + + ) {
JSONObject object = jsTaskLists . getJSONObject ( i ) ;
JSONObject object = jsTaskLists . getJSONObject ( i ) ;
@ -187,7 +182,7 @@ public class GTaskManager {
mMetaList = new TaskList ( ) ;
mMetaList = new TaskList ( ) ;
mMetaList . setContentByRemoteJSON ( object ) ;
mMetaList . setContentByRemoteJSON ( object ) ;
// load meta data
// 加载元数据
JSONArray jsMetas = client . getTaskList ( gid ) ;
JSONArray jsMetas = client . getTaskList ( gid ) ;
for ( int j = 0 ; j < jsMetas . length ( ) ; j + + ) {
for ( int j = 0 ; j < jsMetas . length ( ) ; j + + ) {
object = ( JSONObject ) jsMetas . getJSONObject ( j ) ;
object = ( JSONObject ) jsMetas . getJSONObject ( j ) ;
@ -203,7 +198,7 @@ public class GTaskManager {
}
}
}
}
// create meta list if not existed
// 2. 如果元数据列表不存在,则创建
if ( mMetaList = = null ) {
if ( mMetaList = = null ) {
mMetaList = new TaskList ( ) ;
mMetaList = new TaskList ( ) ;
mMetaList . setName ( GTaskStringUtils . MIUI_FOLDER_PREFFIX
mMetaList . setName ( GTaskStringUtils . MIUI_FOLDER_PREFFIX
@ -211,7 +206,7 @@ public class GTaskManager {
GTaskClient . getInstance ( ) . createTaskList ( mMetaList ) ;
GTaskClient . getInstance ( ) . createTaskList ( mMetaList ) ;
}
}
// init task list
// 3. 初始化其他任务列表
for ( int i = 0 ; i < jsTaskLists . length ( ) ; i + + ) {
for ( int i = 0 ; i < jsTaskLists . length ( ) ; i + + ) {
JSONObject object = jsTaskLists . getJSONObject ( i ) ;
JSONObject object = jsTaskLists . getJSONObject ( i ) ;
String gid = object . getString ( GTaskStringUtils . GTASK_JSON_ID ) ;
String gid = object . getString ( GTaskStringUtils . GTASK_JSON_ID ) ;
@ -225,7 +220,7 @@ public class GTaskManager {
mGTaskListHashMap . put ( gid , tasklist ) ;
mGTaskListHashMap . put ( gid , tasklist ) ;
mGTaskHashMap . put ( gid , tasklist ) ;
mGTaskHashMap . put ( gid , tasklist ) ;
// load tasks
// 加载任务
JSONArray jsTasks = client . getTaskList ( gid ) ;
JSONArray jsTasks = client . getTaskList ( gid ) ;
for ( int j = 0 ; j < jsTasks . length ( ) ; j + + ) {
for ( int j = 0 ; j < jsTasks . length ( ) ; j + + ) {
object = ( JSONObject ) jsTasks . getJSONObject ( j ) ;
object = ( JSONObject ) jsTasks . getJSONObject ( j ) ;
@ -247,6 +242,7 @@ public class GTaskManager {
}
}
}
}
// 同步内容
private void syncContent ( ) throws NetworkFailureException {
private void syncContent ( ) throws NetworkFailureException {
int syncType ;
int syncType ;
Cursor c = null ;
Cursor c = null ;
@ -259,7 +255,7 @@ public class GTaskManager {
return ;
return ;
}
}
// for local deleted note
// 1. 同步本地已删除的笔记
try {
try {
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
"(type<>? AND parent_id=?)" , new String [ ] {
"(type<>? AND parent_id=?)" , new String [ ] {
@ -286,10 +282,10 @@ public class GTaskManager {
}
}
}
}
// sync folder first
// 2. 首先同步文件夹
syncFolder ( ) ;
syncFolder ( ) ;
// for note existing in database
// 3. 同步数据库中存在的笔记
try {
try {
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
"(type=? AND parent_id<>?)" , new String [ ] {
"(type=? AND parent_id<>?)" , new String [ ] {
@ -306,10 +302,10 @@ public class GTaskManager {
syncType = node . getSyncAction ( c ) ;
syncType = node . getSyncAction ( c ) ;
} else {
} else {
if ( c . getString ( SqlNote . GTASK_ID_COLUMN ) . trim ( ) . length ( ) = = 0 ) {
if ( c . getString ( SqlNote . GTASK_ID_COLUMN ) . trim ( ) . length ( ) = = 0 ) {
// local add
// 本地新增
syncType = Node . SYNC_ACTION_ADD_REMOTE ;
syncType = Node . SYNC_ACTION_ADD_REMOTE ;
} else {
} else {
// remote delete
// 远程删除
syncType = Node . SYNC_ACTION_DEL_LOCAL ;
syncType = Node . SYNC_ACTION_DEL_LOCAL ;
}
}
}
}
@ -326,7 +322,7 @@ public class GTaskManager {
}
}
}
}
// go through remaining items
// 4. 处理剩余的远程新增项
Iterator < Map . Entry < String , Node > > iter = mGTaskHashMap . entrySet ( ) . iterator ( ) ;
Iterator < Map . Entry < String , Node > > iter = mGTaskHashMap . entrySet ( ) . iterator ( ) ;
while ( iter . hasNext ( ) ) {
while ( iter . hasNext ( ) ) {
Map . Entry < String , Node > entry = iter . next ( ) ;
Map . Entry < String , Node > entry = iter . next ( ) ;
@ -334,23 +330,21 @@ public class GTaskManager {
doContentSync ( Node . SYNC_ACTION_ADD_LOCAL , node , null ) ;
doContentSync ( Node . SYNC_ACTION_ADD_LOCAL , node , null ) ;
}
}
// mCancelled can be set by another thread, so we neet to check one by
// 5. 清除本地删除表
// one
// clear local delete table
if ( ! mCancelled ) {
if ( ! mCancelled ) {
if ( ! DataUtils . batchDeleteNotes ( mContentResolver , mLocalDeleteIdMap ) ) {
if ( ! DataUtils . batchDeleteNotes ( mContentResolver , mLocalDeleteIdMap ) ) {
throw new ActionFailureException ( "failed to batch-delete local deleted notes" ) ;
throw new ActionFailureException ( "failed to batch-delete local deleted notes" ) ;
}
}
}
}
// refresh local sync id
// 6. 刷新本地同步ID
if ( ! mCancelled ) {
if ( ! mCancelled ) {
GTaskClient . getInstance ( ) . commitUpdate ( ) ;
GTaskClient . getInstance ( ) . commitUpdate ( ) ;
refreshLocalSyncId ( ) ;
refreshLocalSyncId ( ) ;
}
}
}
}
// 同步文件夹
private void syncFolder ( ) throws NetworkFailureException {
private void syncFolder ( ) throws NetworkFailureException {
Cursor c = null ;
Cursor c = null ;
String gid ;
String gid ;
@ -361,7 +355,7 @@ public class GTaskManager {
return ;
return ;
}
}
// for root folder
// 1. 同步根文件夹
try {
try {
c = mContentResolver . query ( ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI ,
c = mContentResolver . query ( ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI ,
Notes . ID_ROOT_FOLDER ) , SqlNote . PROJECTION_NOTE , null , null , null ) ;
Notes . ID_ROOT_FOLDER ) , SqlNote . PROJECTION_NOTE , null , null , null ) ;
@ -373,7 +367,7 @@ public class GTaskManager {
mGTaskHashMap . remove ( gid ) ;
mGTaskHashMap . remove ( gid ) ;
mGidToNid . put ( gid , ( long ) Notes . ID_ROOT_FOLDER ) ;
mGidToNid . put ( gid , ( long ) Notes . ID_ROOT_FOLDER ) ;
mNidToGid . put ( ( long ) Notes . ID_ROOT_FOLDER , gid ) ;
mNidToGid . put ( ( long ) Notes . ID_ROOT_FOLDER , gid ) ;
// for system folder, only update remote name if necessary
// 对于系统文件夹,仅在必要时更新远程名称
if ( ! node . getName ( ) . equals (
if ( ! node . getName ( ) . equals (
GTaskStringUtils . MIUI_FOLDER_PREFFIX + GTaskStringUtils . FOLDER_DEFAULT ) )
GTaskStringUtils . MIUI_FOLDER_PREFFIX + GTaskStringUtils . FOLDER_DEFAULT ) )
doContentSync ( Node . SYNC_ACTION_UPDATE_REMOTE , node , c ) ;
doContentSync ( Node . SYNC_ACTION_UPDATE_REMOTE , node , c ) ;
@ -390,7 +384,7 @@ public class GTaskManager {
}
}
}
}
// for call-note folder
// 2. 同步通话记录文件夹
try {
try {
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE , "(_id=?)" ,
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE , "(_id=?)" ,
new String [ ] {
new String [ ] {
@ -404,8 +398,7 @@ public class GTaskManager {
mGTaskHashMap . remove ( gid ) ;
mGTaskHashMap . remove ( gid ) ;
mGidToNid . put ( gid , ( long ) Notes . ID_CALL_RECORD_FOLDER ) ;
mGidToNid . put ( gid , ( long ) Notes . ID_CALL_RECORD_FOLDER ) ;
mNidToGid . put ( ( long ) Notes . ID_CALL_RECORD_FOLDER , gid ) ;
mNidToGid . put ( ( long ) Notes . ID_CALL_RECORD_FOLDER , gid ) ;
// for system folder, only update remote name if
// 对于系统文件夹,仅在必要时更新远程名称
// necessary
if ( ! node . getName ( ) . equals (
if ( ! node . getName ( ) . equals (
GTaskStringUtils . MIUI_FOLDER_PREFFIX
GTaskStringUtils . MIUI_FOLDER_PREFFIX
+ GTaskStringUtils . FOLDER_CALL_NOTE ) )
+ GTaskStringUtils . FOLDER_CALL_NOTE ) )
@ -424,7 +417,7 @@ public class GTaskManager {
}
}
}
}
// for local existing folders
// 3. 同步本地存在的文件夹
try {
try {
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
"(type=? AND parent_id<>?)" , new String [ ] {
"(type=? AND parent_id<>?)" , new String [ ] {
@ -441,10 +434,10 @@ public class GTaskManager {
syncType = node . getSyncAction ( c ) ;
syncType = node . getSyncAction ( c ) ;
} else {
} else {
if ( c . getString ( SqlNote . GTASK_ID_COLUMN ) . trim ( ) . length ( ) = = 0 ) {
if ( c . getString ( SqlNote . GTASK_ID_COLUMN ) . trim ( ) . length ( ) = = 0 ) {
// local add
// 本地新增
syncType = Node . SYNC_ACTION_ADD_REMOTE ;
syncType = Node . SYNC_ACTION_ADD_REMOTE ;
} else {
} else {
// remote delete
// 远程删除
syncType = Node . SYNC_ACTION_DEL_LOCAL ;
syncType = Node . SYNC_ACTION_DEL_LOCAL ;
}
}
}
}
@ -460,7 +453,7 @@ public class GTaskManager {
}
}
}
}
// for remote add folders
// 4. 处理远程新增的文件夹
Iterator < Map . Entry < String , TaskList > > iter = mGTaskListHashMap . entrySet ( ) . iterator ( ) ;
Iterator < Map . Entry < String , TaskList > > iter = mGTaskListHashMap . entrySet ( ) . iterator ( ) ;
while ( iter . hasNext ( ) ) {
while ( iter . hasNext ( ) ) {
Map . Entry < String , TaskList > entry = iter . next ( ) ;
Map . Entry < String , TaskList > entry = iter . next ( ) ;
@ -476,6 +469,7 @@ public class GTaskManager {
GTaskClient . getInstance ( ) . commitUpdate ( ) ;
GTaskClient . getInstance ( ) . commitUpdate ( ) ;
}
}
// 执行内容同步操作
private void doContentSync ( int syncType , Node node , Cursor c ) throws NetworkFailureException {
private void doContentSync ( int syncType , Node node , Cursor c ) throws NetworkFailureException {
if ( mCancelled ) {
if ( mCancelled ) {
return ;
return ;
@ -510,8 +504,8 @@ public class GTaskManager {
updateRemoteNode ( node , c ) ;
updateRemoteNode ( node , c ) ;
break ;
break ;
case Node . SYNC_ACTION_UPDATE_CONFLICT :
case Node . SYNC_ACTION_UPDATE_CONFLICT :
// merging both modifications maybe a good idea
// 合并修改可能是一个好主意
// right now just use local update simply
// 目前简单使用本地更新
updateRemoteNode ( node , c ) ;
updateRemoteNode ( node , c ) ;
break ;
break ;
case Node . SYNC_ACTION_NONE :
case Node . SYNC_ACTION_NONE :
@ -522,6 +516,7 @@ public class GTaskManager {
}
}
}
}
// 添加本地节点
private void addLocalNode ( Node node ) throws NetworkFailureException {
private void addLocalNode ( Node node ) throws NetworkFailureException {
if ( mCancelled ) {
if ( mCancelled ) {
return ;
return ;
@ -529,6 +524,7 @@ public class GTaskManager {
SqlNote sqlNote ;
SqlNote sqlNote ;
if ( node instanceof TaskList ) {
if ( node instanceof TaskList ) {
// 处理文件夹
if ( node . getName ( ) . equals (
if ( node . getName ( ) . equals (
GTaskStringUtils . MIUI_FOLDER_PREFFIX + GTaskStringUtils . FOLDER_DEFAULT ) ) {
GTaskStringUtils . MIUI_FOLDER_PREFFIX + GTaskStringUtils . FOLDER_DEFAULT ) ) {
sqlNote = new SqlNote ( mContext , Notes . ID_ROOT_FOLDER ) ;
sqlNote = new SqlNote ( mContext , Notes . ID_ROOT_FOLDER ) ;
@ -541,15 +537,17 @@ public class GTaskManager {
sqlNote . setParentId ( Notes . ID_ROOT_FOLDER ) ;
sqlNote . setParentId ( Notes . ID_ROOT_FOLDER ) ;
}
}
} else {
} else {
// 处理笔记
sqlNote = new SqlNote ( mContext ) ;
sqlNote = new SqlNote ( mContext ) ;
JSONObject js = node . getLocalJSONFromContent ( ) ;
JSONObject js = node . getLocalJSONFromContent ( ) ;
try {
try {
// 处理元数据
if ( js . has ( GTaskStringUtils . META_HEAD_NOTE ) ) {
if ( js . has ( GTaskStringUtils . META_HEAD_NOTE ) ) {
JSONObject note = js . getJSONObject ( GTaskStringUtils . META_HEAD_NOTE ) ;
JSONObject note = js . getJSONObject ( GTaskStringUtils . META_HEAD_NOTE ) ;
if ( note . has ( NoteColumns . ID ) ) {
if ( note . has ( NoteColumns . ID ) ) {
long id = note . getLong ( NoteColumns . ID ) ;
long id = note . getLong ( NoteColumns . ID ) ;
if ( DataUtils . existInNoteDatabase ( mContentResolver , id ) ) {
if ( DataUtils . existInNoteDatabase ( mContentResolver , id ) ) {
// the id is not available, have to create a new one
// ID不可用, 需要创建新的
note . remove ( NoteColumns . ID ) ;
note . remove ( NoteColumns . ID ) ;
}
}
}
}
@ -562,13 +560,11 @@ public class GTaskManager {
if ( data . has ( DataColumns . ID ) ) {
if ( data . has ( DataColumns . ID ) ) {
long dataId = data . getLong ( DataColumns . ID ) ;
long dataId = data . getLong ( DataColumns . ID ) ;
if ( DataUtils . existInDataDatabase ( mContentResolver , dataId ) ) {
if ( DataUtils . existInDataDatabase ( mContentResolver , dataId ) ) {
// the data id is not available, have to create
// 数据ID不可用, 需要创建新的
// a new one
data . remove ( DataColumns . ID ) ;
data . remove ( DataColumns . ID ) ;
}
}
}
}
}
}
}
}
} catch ( JSONException e ) {
} catch ( JSONException e ) {
Log . w ( TAG , e . toString ( ) ) ;
Log . w ( TAG , e . toString ( ) ) ;
@ -576,6 +572,7 @@ public class GTaskManager {
}
}
sqlNote . setContent ( js ) ;
sqlNote . setContent ( js ) ;
// 设置父文件夹ID
Long parentId = mGidToNid . get ( ( ( Task ) node ) . getParent ( ) . getGid ( ) ) ;
Long parentId = mGidToNid . get ( ( ( Task ) node ) . getParent ( ) . getGid ( ) ) ;
if ( parentId = = null ) {
if ( parentId = = null ) {
Log . e ( TAG , "cannot find task's parent id locally" ) ;
Log . e ( TAG , "cannot find task's parent id locally" ) ;
@ -584,28 +581,30 @@ public class GTaskManager {
sqlNote . setParentId ( parentId . longValue ( ) ) ;
sqlNote . setParentId ( parentId . longValue ( ) ) ;
}
}
// create the local node
// 创建本地节点
sqlNote . setGtaskId ( node . getGid ( ) ) ;
sqlNote . setGtaskId ( node . getGid ( ) ) ;
sqlNote . commit ( false ) ;
sqlNote . commit ( false ) ;
// update gid-nid mapping
// 更新ID映射
mGidToNid . put ( node . getGid ( ) , sqlNote . getId ( ) ) ;
mGidToNid . put ( node . getGid ( ) , sqlNote . getId ( ) ) ;
mNidToGid . put ( sqlNote . getId ( ) , node . getGid ( ) ) ;
mNidToGid . put ( sqlNote . getId ( ) , node . getGid ( ) ) ;
// update meta
// 更新元数据
updateRemoteMeta ( node . getGid ( ) , sqlNote ) ;
updateRemoteMeta ( node . getGid ( ) , sqlNote ) ;
}
}
// 更新本地节点
private void updateLocalNode ( Node node , Cursor c ) throws NetworkFailureException {
private void updateLocalNode ( Node node , Cursor c ) throws NetworkFailureException {
if ( mCancelled ) {
if ( mCancelled ) {
return ;
return ;
}
}
SqlNote sqlNote ;
SqlNote sqlNote ;
// update the note locally
// 更新本地笔记
sqlNote = new SqlNote ( mContext , c ) ;
sqlNote = new SqlNote ( mContext , c ) ;
sqlNote . setContent ( node . getLocalJSONFromContent ( ) ) ;
sqlNote . setContent ( node . getLocalJSONFromContent ( ) ) ;
// 设置父文件夹ID
Long parentId = ( node instanceof Task ) ? mGidToNid . get ( ( ( Task ) node ) . getParent ( ) . getGid ( ) )
Long parentId = ( node instanceof Task ) ? mGidToNid . get ( ( ( Task ) node ) . getParent ( ) . getGid ( ) )
: new Long ( Notes . ID_ROOT_FOLDER ) ;
: new Long ( Notes . ID_ROOT_FOLDER ) ;
if ( parentId = = null ) {
if ( parentId = = null ) {
@ -615,10 +614,11 @@ public class GTaskManager {
sqlNote . setParentId ( parentId . longValue ( ) ) ;
sqlNote . setParentId ( parentId . longValue ( ) ) ;
sqlNote . commit ( true ) ;
sqlNote . commit ( true ) ;
// update meta info
// 更新元数据
updateRemoteMeta ( node . getGid ( ) , sqlNote ) ;
updateRemoteMeta ( node . getGid ( ) , sqlNote ) ;
}
}
// 添加远程节点
private void addRemoteNode ( Node node , Cursor c ) throws NetworkFailureException {
private void addRemoteNode ( Node node , Cursor c ) throws NetworkFailureException {
if ( mCancelled ) {
if ( mCancelled ) {
return ;
return ;
@ -627,11 +627,13 @@ public class GTaskManager {
SqlNote sqlNote = new SqlNote ( mContext , c ) ;
SqlNote sqlNote = new SqlNote ( mContext , c ) ;
Node n ;
Node n ;
// update remotely
// 远程更新
if ( sqlNote . isNoteType ( ) ) {
if ( sqlNote . isNoteType ( ) ) {
// 处理笔记
Task task = new Task ( ) ;
Task task = new Task ( ) ;
task . setContentByLocalJSON ( sqlNote . getContent ( ) ) ;
task . setContentByLocalJSON ( sqlNote . getContent ( ) ) ;
// 获取父文件夹ID
String parentGid = mNidToGid . get ( sqlNote . getParentId ( ) ) ;
String parentGid = mNidToGid . get ( sqlNote . getParentId ( ) ) ;
if ( parentGid = = null ) {
if ( parentGid = = null ) {
Log . e ( TAG , "cannot find task's parent tasklist" ) ;
Log . e ( TAG , "cannot find task's parent tasklist" ) ;
@ -639,15 +641,17 @@ public class GTaskManager {
}
}
mGTaskListHashMap . get ( parentGid ) . addChildTask ( task ) ;
mGTaskListHashMap . get ( parentGid ) . addChildTask ( task ) ;
// 创建远程任务
GTaskClient . getInstance ( ) . createTask ( task ) ;
GTaskClient . getInstance ( ) . createTask ( task ) ;
n = ( Node ) task ;
n = ( Node ) task ;
// add meta
// 添加元数据
updateRemoteMeta ( task . getGid ( ) , sqlNote ) ;
updateRemoteMeta ( task . getGid ( ) , sqlNote ) ;
} else {
} else {
// 处理文件夹
TaskList tasklist = null ;
TaskList tasklist = null ;
// we need to skip folder if it has already existed
// 跳过已存在的文件夹
String folderName = GTaskStringUtils . MIUI_FOLDER_PREFFIX ;
String folderName = GTaskStringUtils . MIUI_FOLDER_PREFFIX ;
if ( sqlNote . getId ( ) = = Notes . ID_ROOT_FOLDER )
if ( sqlNote . getId ( ) = = Notes . ID_ROOT_FOLDER )
folderName + = GTaskStringUtils . FOLDER_DEFAULT ;
folderName + = GTaskStringUtils . FOLDER_DEFAULT ;
@ -656,6 +660,7 @@ public class GTaskManager {
else
else
folderName + = sqlNote . getSnippet ( ) ;
folderName + = sqlNote . getSnippet ( ) ;
// 查找匹配的文件夹
Iterator < Map . Entry < String , TaskList > > iter = mGTaskListHashMap . entrySet ( ) . iterator ( ) ;
Iterator < Map . Entry < String , TaskList > > iter = mGTaskListHashMap . entrySet ( ) . iterator ( ) ;
while ( iter . hasNext ( ) ) {
while ( iter . hasNext ( ) ) {
Map . Entry < String , TaskList > entry = iter . next ( ) ;
Map . Entry < String , TaskList > entry = iter . next ( ) ;
@ -671,7 +676,7 @@ public class GTaskManager {
}
}
}
}
// no match we can add now
// 没有匹配项则创建新文件夹
if ( tasklist = = null ) {
if ( tasklist = = null ) {
tasklist = new TaskList ( ) ;
tasklist = new TaskList ( ) ;
tasklist . setContentByLocalJSON ( sqlNote . getContent ( ) ) ;
tasklist . setContentByLocalJSON ( sqlNote . getContent ( ) ) ;
@ -681,17 +686,18 @@ public class GTaskManager {
n = ( Node ) tasklist ;
n = ( Node ) tasklist ;
}
}
// update local note
// 更新本地笔记
sqlNote . setGtaskId ( n . getGid ( ) ) ;
sqlNote . setGtaskId ( n . getGid ( ) ) ;
sqlNote . commit ( false ) ;
sqlNote . commit ( false ) ;
sqlNote . resetLocalModified ( ) ;
sqlNote . resetLocalModified ( ) ;
sqlNote . commit ( true ) ;
sqlNote . commit ( true ) ;
// gid-id mapping
// 更新ID映射
mGidToNid . put ( n . getGid ( ) , sqlNote . getId ( ) ) ;
mGidToNid . put ( n . getGid ( ) , sqlNote . getId ( ) ) ;
mNidToGid . put ( sqlNote . getId ( ) , n . getGid ( ) ) ;
mNidToGid . put ( sqlNote . getId ( ) , n . getGid ( ) ) ;
}
}
// 更新远程节点
private void updateRemoteNode ( Node node , Cursor c ) throws NetworkFailureException {
private void updateRemoteNode ( Node node , Cursor c ) throws NetworkFailureException {
if ( mCancelled ) {
if ( mCancelled ) {
return ;
return ;
@ -699,18 +705,19 @@ public class GTaskManager {
SqlNote sqlNote = new SqlNote ( mContext , c ) ;
SqlNote sqlNote = new SqlNote ( mContext , c ) ;
// update remotely
// 更新远程节点
node . setContentByLocalJSON ( sqlNote . getContent ( ) ) ;
node . setContentByLocalJSON ( sqlNote . getContent ( ) ) ;
GTaskClient . getInstance ( ) . addUpdateNode ( node ) ;
GTaskClient . getInstance ( ) . addUpdateNode ( node ) ;
// update meta
// 更新元数据
updateRemoteMeta ( node . getGid ( ) , sqlNote ) ;
updateRemoteMeta ( node . getGid ( ) , sqlNote ) ;
// move task if necessary
// 如果是笔记,可能需要移动位置
if ( sqlNote . isNoteType ( ) ) {
if ( sqlNote . isNoteType ( ) ) {
Task task = ( Task ) node ;
Task task = ( Task ) node ;
TaskList preParentList = task . getParent ( ) ;
TaskList preParentList = task . getParent ( ) ;
// 获取当前父文件夹ID
String curParentGid = mNidToGid . get ( sqlNote . getParentId ( ) ) ;
String curParentGid = mNidToGid . get ( sqlNote . getParentId ( ) ) ;
if ( curParentGid = = null ) {
if ( curParentGid = = null ) {
Log . e ( TAG , "cannot find task's parent tasklist" ) ;
Log . e ( TAG , "cannot find task's parent tasklist" ) ;
@ -718,6 +725,7 @@ public class GTaskManager {
}
}
TaskList curParentList = mGTaskListHashMap . get ( curParentGid ) ;
TaskList curParentList = mGTaskListHashMap . get ( curParentGid ) ;
// 如果父文件夹发生变化,移动任务
if ( preParentList ! = curParentList ) {
if ( preParentList ! = curParentList ) {
preParentList . removeChildTask ( task ) ;
preParentList . removeChildTask ( task ) ;
curParentList . addChildTask ( task ) ;
curParentList . addChildTask ( task ) ;
@ -725,18 +733,21 @@ public class GTaskManager {
}
}
}
}
// clear local modified flag
// 清除本地修改标志
sqlNote . resetLocalModified ( ) ;
sqlNote . resetLocalModified ( ) ;
sqlNote . commit ( true ) ;
sqlNote . commit ( true ) ;
}
}
// 更新远程元数据
private void updateRemoteMeta ( String gid , SqlNote sqlNote ) throws NetworkFailureException {
private void updateRemoteMeta ( String gid , SqlNote sqlNote ) throws NetworkFailureException {
if ( sqlNote ! = null & & sqlNote . isNoteType ( ) ) {
if ( sqlNote ! = null & & sqlNote . isNoteType ( ) ) {
MetaData metaData = mMetaHashMap . get ( gid ) ;
MetaData metaData = mMetaHashMap . get ( gid ) ;
if ( metaData ! = null ) {
if ( metaData ! = null ) {
// 更新现有元数据
metaData . setMeta ( gid , sqlNote . getContent ( ) ) ;
metaData . setMeta ( gid , sqlNote . getContent ( ) ) ;
GTaskClient . getInstance ( ) . addUpdateNode ( metaData ) ;
GTaskClient . getInstance ( ) . addUpdateNode ( metaData ) ;
} else {
} else {
// 创建新元数据
metaData = new MetaData ( ) ;
metaData = new MetaData ( ) ;
metaData . setMeta ( gid , sqlNote . getContent ( ) ) ;
metaData . setMeta ( gid , sqlNote . getContent ( ) ) ;
mMetaList . addChildTask ( metaData ) ;
mMetaList . addChildTask ( metaData ) ;
@ -746,12 +757,13 @@ public class GTaskManager {
}
}
}
}
// 刷新本地同步ID
private void refreshLocalSyncId ( ) throws NetworkFailureException {
private void refreshLocalSyncId ( ) throws NetworkFailureException {
if ( mCancelled ) {
if ( mCancelled ) {
return ;
return ;
}
}
// get the latest gtask list
// 重新获取Google任务列表
mGTaskHashMap . clear ( ) ;
mGTaskHashMap . clear ( ) ;
mGTaskListHashMap . clear ( ) ;
mGTaskListHashMap . clear ( ) ;
mMetaHashMap . clear ( ) ;
mMetaHashMap . clear ( ) ;
@ -759,6 +771,7 @@ public class GTaskManager {
Cursor c = null ;
Cursor c = null ;
try {
try {
// 查询所有非系统笔记
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
c = mContentResolver . query ( Notes . CONTENT_NOTE_URI , SqlNote . PROJECTION_NOTE ,
"(type<>? AND parent_id<>?)" , new String [ ] {
"(type<>? AND parent_id<>?)" , new String [ ] {
String . valueOf ( Notes . TYPE_SYSTEM ) , String . valueOf ( Notes . ID_TRASH_FOLER )
String . valueOf ( Notes . TYPE_SYSTEM ) , String . valueOf ( Notes . ID_TRASH_FOLER )
@ -769,6 +782,7 @@ public class GTaskManager {
Node node = mGTaskHashMap . get ( gid ) ;
Node node = mGTaskHashMap . get ( gid ) ;
if ( node ! = null ) {
if ( node ! = null ) {
mGTaskHashMap . remove ( gid ) ;
mGTaskHashMap . remove ( gid ) ;
// 更新同步时间戳
ContentValues values = new ContentValues ( ) ;
ContentValues values = new ContentValues ( ) ;
values . put ( NoteColumns . SYNC_ID , node . getLastModified ( ) ) ;
values . put ( NoteColumns . SYNC_ID , node . getLastModified ( ) ) ;
mContentResolver . update ( ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI ,
mContentResolver . update ( ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI ,
@ -790,10 +804,12 @@ public class GTaskManager {
}
}
}
}
// 获取当前同步账户
public String getSyncAccount ( ) {
public String getSyncAccount ( ) {
return GTaskClient . getInstance ( ) . getSyncAccount ( ) . name ;
return GTaskClient . getInstance ( ) . getSyncAccount ( ) . name ;
}
}
// 取消同步
public void cancelSync ( ) {
public void cancelSync ( ) {
mCancelled = true ;
mCancelled = true ;
}
}