From ebf89e64d21a6ea2542958ca37d21c4de0f6cb64 Mon Sep 17 00:00:00 2001 From: hmh <2150887269@qq.com> Date: Thu, 12 Jun 2025 14:47:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=AF=B9GTaskASyncTask.java,?= =?UTF-8?q?GTaskClient.java,GTaskManager.java,GTaskSyncService.java?= =?UTF-8?q?=E5=9B=9B=E4=B8=AA=E6=96=87=E4=BB=B6=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notes/gtask/remote/GTaskASyncTask.java | 75 ++++-- .../notes/gtask/remote/GTaskClient.java | 244 +++++++++++------- .../notes/gtask/remote/GTaskManager.java | 226 +++++++++++----- .../notes/gtask/remote/GTaskSyncService.java | 102 ++++---- 4 files changed, 421 insertions(+), 226 deletions(-) diff --git a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java index cd46ade..79d6b1b 100644 --- a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java +++ b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskASyncTask.java @@ -1,4 +1,3 @@ - /* * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * @@ -28,23 +27,36 @@ import net.micode.notes.R; import net.micode.notes.ui.NotesListActivity; import net.micode.notes.ui.NotesPreferenceActivity; - +/** + * 该类继承自 AsyncTask,用于在后台执行 Google 任务同步操作。 + * 同步过程中会显示通知,同步完成后会根据结果显示不同的通知信息。 + */ public class GTaskASyncTask extends AsyncTask { - + + // 同步通知的唯一 ID private static int GTASK_SYNC_NOTIFICATION_ID = 5234235; - + + /** + * 同步完成监听器接口,用于在同步完成后执行特定操作 + */ public interface OnCompleteListener { void onComplete(); } - + + // 应用上下文 private Context mContext; - + // 通知管理器 private NotificationManager mNotifiManager; - + // GTask 管理器实例 private GTaskManager mTaskManager; - + // 同步完成监听器 private OnCompleteListener mOnCompleteListener; - + + /** + * 构造函数,初始化上下文、监听器、通知管理器和 GTask 管理器 + * @param context 应用上下文 + * @param listener 同步完成监听器 + */ public GTaskASyncTask(Context context, OnCompleteListener listener) { mContext = context; mOnCompleteListener = listener; @@ -52,19 +64,32 @@ public class GTaskASyncTask extends AsyncTask { .getSystemService(Context.NOTIFICATION_SERVICE); mTaskManager = GTaskManager.getInstance(); } - + + /** + * 取消同步操作 + */ public void cancelSync() { mTaskManager.cancelSync(); } - + + /** + * 发布同步进度信息 + * @param message 进度信息 + */ public void publishProgess(String message) { publishProgress(new String[]{ message }); } - + + /** + * 显示同步通知 + * @param tickerId 通知的提示信息资源 ID + * @param content 通知的内容 + */ private void showNotification(int tickerId, String content) { PendingIntent pendingIntent; + // 根据不同的提示信息 ID 设置不同的点击跳转意图 if (tickerId != R.string.ticker_success) { pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE); @@ -82,14 +107,25 @@ public class GTaskASyncTask extends AsyncTask { Notification notification = builder.getNotification(); mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); } - + + /** + * 后台执行同步操作 + * @param unused 未使用的参数 + * @return 同步结果状态码 + */ @Override protected Integer doInBackground(Void... unused) { + // 发布登录进度信息 publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity .getSyncAccountName(mContext))); + // 调用 GTask 管理器的同步方法 return mTaskManager.sync(mContext, this); } - + + /** + * 更新同步进度,显示进度通知并发送广播 + * @param progress 进度信息 + */ @Override protected void onProgressUpdate(String... progress) { showNotification(R.string.ticker_syncing, progress[0]); @@ -97,12 +133,17 @@ public class GTaskASyncTask extends AsyncTask { ((GTaskSyncService) mContext).sendBroadcast(progress[0]); } } - + + /** + * 同步完成后执行的操作,根据同步结果显示不同的通知信息 + * @param result 同步结果状态码 + */ @Override protected void onPostExecute(Integer result) { if (result == GTaskManager.STATE_SUCCESS) { showNotification(R.string.ticker_success, mContext.getString( R.string.success_sync_account, mTaskManager.getSyncAccount())); + // 设置最后同步时间 NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); } else if (result == GTaskManager.STATE_NETWORK_ERROR) { showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network)); @@ -113,12 +154,12 @@ public class GTaskASyncTask extends AsyncTask { .getString(R.string.error_sync_cancelled)); } if (mOnCompleteListener != null) { + // 启动新线程调用同步完成监听器的方法 new Thread(new Runnable() { - public void run() { mOnCompleteListener.onComplete(); } }).start(); } } -} +} \ No newline at end of file diff --git a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java index c67dfdf..542417e 100644 --- a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java +++ b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskClient.java @@ -60,36 +60,42 @@ import java.util.zip.GZIPInputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; - +/** + * 该类用于与 Google 任务服务进行交互,包括登录、创建任务、创建任务列表等操作 + */ public class GTaskClient { + // 日志标签 private static final String TAG = GTaskClient.class.getSimpleName(); - + // Google 任务的基本 URL private static final String GTASK_URL = "https://mail.google.com/tasks/"; - + // 获取任务列表的 URL private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig"; - + // 提交任务操作的 URL private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig"; - + // 单例实例 private static GTaskClient mInstance = null; - + // HTTP 客户端 private DefaultHttpClient mHttpClient; - + // 获取任务列表的实际 URL private String mGetUrl; - + // 提交任务操作的实际 URL private String mPostUrl; - + // 客户端版本号 private long mClientVersion; - + // 是否登录标志 private boolean mLoggedin; - + // 最后登录时间 private long mLastLoginTime; - + // 操作 ID private int mActionId; - + // 同步账户 private Account mAccount; - + // 更新操作数组 private JSONArray mUpdateArray; + /** + * 私有构造函数,初始化客户端参数 + */ private GTaskClient() { mHttpClient = null; mGetUrl = GTASK_GET_URL; @@ -102,6 +108,10 @@ public class GTaskClient { mUpdateArray = null; } + /** + * 获取单例实例 + * @return GTaskClient 单例实例 + */ public static synchronized GTaskClient getInstance() { if (mInstance == null) { mInstance = new GTaskClient(); @@ -109,34 +119,35 @@ public class GTaskClient { return mInstance; } + /** + * 登录 Google 任务服务 + * @param activity 当前活动 + * @return 登录成功返回 true,失败返回 false + */ public boolean login(Activity activity) { - // we suppose that the cookie would expire after 5 minutes - // then we need to re-login + // 假设 cookie 有效期为 5 分钟,超过时间需要重新登录 final long interval = 1000 * 60 * 5; if (mLastLoginTime + interval < System.currentTimeMillis()) { mLoggedin = false; } - - // need to re-login after account switch + // 切换账户后需要重新登录 if (mLoggedin && !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity .getSyncAccountName(activity))) { mLoggedin = false; } - if (mLoggedin) { Log.d(TAG, "already logged in"); return true; } - mLastLoginTime = System.currentTimeMillis(); + // 登录 Google 账户获取认证令牌 String authToken = loginGoogleAccount(activity, false); if (authToken == null) { Log.e(TAG, "login google account failed"); return false; } - - // login with custom domain if necessary + // 非 gmail 或 googlemail 账户需要尝试自定义域名登录 if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() .endsWith("googlemail.com"))) { StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); @@ -145,13 +156,11 @@ public class GTaskClient { url.append(suffix + "/"); mGetUrl = url.toString() + "ig"; mPostUrl = url.toString() + "r/ig"; - if (tryToLoginGtask(activity, authToken)) { mLoggedin = true; } } - - // try to login with google official url + // 尝试使用 Google 官方 URL 登录 if (!mLoggedin) { mGetUrl = GTASK_GET_URL; mPostUrl = GTASK_POST_URL; @@ -159,21 +168,24 @@ public class GTaskClient { return false; } } - mLoggedin = true; return true; } + /** + * 登录 Google 账户获取认证令牌 + * @param activity 当前活动 + * @param invalidateToken 是否使旧令牌失效 + * @return 认证令牌,失败返回 null + */ private String loginGoogleAccount(Activity activity, boolean invalidateToken) { String authToken; AccountManager accountManager = AccountManager.get(activity); Account[] accounts = accountManager.getAccountsByType("com.google"); - if (accounts.length == 0) { Log.e(TAG, "there is no available google account"); return null; } - String accountName = NotesPreferenceActivity.getSyncAccountName(activity); Account account = null; for (Account a : accounts) { @@ -188,8 +200,7 @@ public class GTaskClient { Log.e(TAG, "unable to get an account with the same name in the settings"); return null; } - - // get the token now + // 获取认证令牌 AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, "goanna_mobile", null, activity, null, null); try { @@ -203,20 +214,23 @@ public class GTaskClient { Log.e(TAG, "get auth token failed"); authToken = null; } - return authToken; } + /** + * 尝试登录 Google 任务服务 + * @param activity 当前活动 + * @param authToken 认证令牌 + * @return 登录成功返回 true,失败返回 false + */ private boolean tryToLoginGtask(Activity activity, String authToken) { if (!loginGtask(authToken)) { - // maybe the auth token is out of date, now let's invalidate the - // token and try again + // 可能认证令牌过期,使旧令牌失效并重新尝试登录 authToken = loginGoogleAccount(activity, true); if (authToken == null) { Log.e(TAG, "login google account failed"); return false; } - if (!loginGtask(authToken)) { Log.e(TAG, "login gtask failed"); return false; @@ -225,6 +239,11 @@ public class GTaskClient { return true; } + /** + * 使用认证令牌登录 Google 任务服务 + * @param authToken 认证令牌 + * @return 登录成功返回 true,失败返回 false + */ private boolean loginGtask(String authToken) { int timeoutConnection = 10000; int timeoutSocket = 15000; @@ -235,15 +254,12 @@ public class GTaskClient { BasicCookieStore localBasicCookieStore = new BasicCookieStore(); mHttpClient.setCookieStore(localBasicCookieStore); HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); - - // login gtask try { String loginUrl = mGetUrl + "?auth=" + authToken; HttpGet httpGet = new HttpGet(loginUrl); HttpResponse response = null; response = mHttpClient.execute(httpGet); - - // get the cookie now + // 获取认证 cookie List cookies = mHttpClient.getCookieStore().getCookies(); boolean hasAuthCookie = false; for (Cookie cookie : cookies) { @@ -254,8 +270,7 @@ public class GTaskClient { if (!hasAuthCookie) { Log.w(TAG, "it seems that there is no auth cookie"); } - - // get the client version + // 获取客户端版本号 String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -272,18 +287,24 @@ public class GTaskClient { e.printStackTrace(); return false; } catch (Exception e) { - // simply catch all exceptions Log.e(TAG, "httpget gtask_url failed"); return false; } - return true; } + /** + * 获取操作 ID + * @return 操作 ID + */ private int getActionId() { return mActionId++; } + /** + * 创建 HttpPost 请求 + * @return HttpPost 请求对象 + */ private HttpPost createHttpPost() { HttpPost httpPost = new HttpPost(mPostUrl); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); @@ -291,13 +312,18 @@ public class GTaskClient { return httpPost; } + /** + * 获取 HTTP 响应内容 + * @param entity HTTP 响应实体 + * @return 响应内容 + * @throws IOException 读取响应内容时可能抛出的异常 + */ private String getResponseContent(HttpEntity entity) throws IOException { String contentEncoding = null; if (entity.getContentEncoding() != null) { contentEncoding = entity.getContentEncoding().getValue(); Log.d(TAG, "encoding: " + contentEncoding); } - InputStream input = entity.getContent(); if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { input = new GZIPInputStream(entity.getContent()); @@ -305,12 +331,10 @@ public class GTaskClient { Inflater inflater = new Inflater(true); input = new InflaterInputStream(entity.getContent(), inflater); } - try { InputStreamReader isr = new InputStreamReader(input); BufferedReader br = new BufferedReader(isr); StringBuilder sb = new StringBuilder(); - while (true) { String buff = br.readLine(); if (buff == null) { @@ -323,24 +347,27 @@ public class GTaskClient { } } + /** + * 提交 JSON 请求 + * @param js JSON 对象 + * @return 响应的 JSON 对象 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ private JSONObject postRequest(JSONObject js) throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); throw new ActionFailureException("not logged in"); } - HttpPost httpPost = createHttpPost(); try { LinkedList list = new LinkedList(); list.add(new BasicNameValuePair("r", js.toString())); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); httpPost.setEntity(entity); - - // execute the post + // 执行 POST 请求 HttpResponse response = mHttpClient.execute(httpPost); String jsString = getResponseContent(response.getEntity()); return new JSONObject(jsString); - } catch (ClientProtocolException e) { Log.e(TAG, e.toString()); e.printStackTrace(); @@ -360,25 +387,27 @@ public class GTaskClient { } } + /** + * 创建任务 + * @param task 任务对象 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public void createTask(Task task) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); - - // action_list + // 添加创建任务的操作 actionList.put(task.getCreateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - - // client_version + // 设置客户端版本号 jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - - // post + // 提交请求 JSONObject jsResponse = postRequest(jsPost); JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( GTaskStringUtils.GTASK_JSON_RESULTS).get(0); + // 设置任务的 Google ID task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); - } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); @@ -386,25 +415,27 @@ public class GTaskClient { } } + /** + * 创建任务列表 + * @param tasklist 任务列表对象 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public void createTaskList(TaskList tasklist) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); - - // action_list + // 添加创建任务列表的操作 actionList.put(tasklist.getCreateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - - // client version + // 设置客户端版本号 jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - - // post + // 提交请求 JSONObject jsResponse = postRequest(jsPost); JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( GTaskStringUtils.GTASK_JSON_RESULTS).get(0); + // 设置任务列表的 Google ID tasklist.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); - } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); @@ -412,17 +443,19 @@ public class GTaskClient { } } + /** + * 提交更新操作 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public void commitUpdate() throws NetworkFailureException { if (mUpdateArray != null) { try { JSONObject jsPost = new JSONObject(); - - // action_list + // 添加更新操作数组 jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray); - - // client_version + // 设置客户端版本号 jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - + // 提交请求 postRequest(jsPost); mUpdateArray = null; } catch (JSONException e) { @@ -433,20 +466,31 @@ public class GTaskClient { } } + /** + * 添加更新节点操作 + * @param node 节点对象 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public void addUpdateNode(Node node) throws NetworkFailureException { if (node != null) { - // too many update items may result in an error - // set max to 10 items + // 更新项过多时先提交更新 if (mUpdateArray != null && mUpdateArray.length() > 10) { commitUpdate(); } - if (mUpdateArray == null) mUpdateArray = new JSONArray(); + // 添加更新操作 mUpdateArray.put(node.getUpdateAction(getActionId())); } } + /** + * 移动任务 + * @param task 任务对象 + * @param preParent 原父任务列表 + * @param curParent 当前父任务列表 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public void moveTask(Task task, TaskList preParent, TaskList curParent) throws NetworkFailureException { commitUpdate(); @@ -454,31 +498,25 @@ public class GTaskClient { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); JSONObject action = new JSONObject(); - - // action_list + // 设置移动任务的操作 action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE); action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid()); if (preParent == curParent && task.getPriorSibling() != null) { - // put prioring_sibing_id only if moving within the tasklist and - // it is not the first one action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling()); } action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); if (preParent != curParent) { - // put the dest_list only if moving between tasklists action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid()); } actionList.put(action); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - - // client_version + // 设置客户端版本号 jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - + // 提交请求 postRequest(jsPost); - } catch (JSONException e) { Log.e(TAG, e.toString()); e.printStackTrace(); @@ -486,20 +524,24 @@ public class GTaskClient { } } + /** + * 删除节点 + * @param node 节点对象 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public void deleteNode(Node node) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); - - // action_list + // 设置节点为已删除 node.setDeleted(true); + // 添加删除操作 actionList.put(node.getUpdateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - - // client_version + // 设置客户端版本号 jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - + // 提交请求 postRequest(jsPost); mUpdateArray = null; } catch (JSONException e) { @@ -509,18 +551,21 @@ public class GTaskClient { } } + /** + * 获取任务列表 + * @return 任务列表的 JSON 数组 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public JSONArray getTaskLists() throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); throw new ActionFailureException("not logged in"); } - try { HttpGet httpGet = new HttpGet(mGetUrl); HttpResponse response = null; response = mHttpClient.execute(httpGet); - - // get the task list + // 获取任务列表的 JSON 数据 String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -547,14 +592,19 @@ public class GTaskClient { } } + /** + * 获取指定任务列表下的任务 + * @param listGid 任务列表的 Google ID + * @return 任务的 JSON 数组 + * @throws NetworkFailureException 网络请求失败时抛出的异常 + */ public JSONArray getTaskList(String listGid) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); JSONObject action = new JSONObject(); - - // action_list + // 设置获取任务列表的操作 action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL); action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); @@ -562,10 +612,9 @@ public class GTaskClient { action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false); actionList.put(action); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - - // client_version + // 设置客户端版本号 jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - + // 提交请求 JSONObject jsResponse = postRequest(jsPost); return jsResponse.getJSONArray(GTaskStringUtils.GTASK_JSON_TASKS); } catch (JSONException e) { @@ -575,11 +624,18 @@ public class GTaskClient { } } + /** + * 获取同步账户 + * @return 同步账户对象 + */ public Account getSyncAccount() { return mAccount; } + /** + * 重置更新操作数组 + */ public void resetUpdateArray() { mUpdateArray = null; } -} +} \ No newline at end of file diff --git a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java index d2b4082..4dd71b3 100644 --- a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java +++ b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskManager.java @@ -47,46 +47,54 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Map; - +/** + * GTaskManager 是一个单例类,用于管理 Google 任务的同步操作。 + * 它负责登录 Google 任务,获取任务列表,执行内容同步等操作。 + */ 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 任务列表的 HashMap private HashMap mGTaskListHashMap; - + // 存储 Google 任务节点的 HashMap private HashMap mGTaskHashMap; - + // 存储元数据的 HashMap private HashMap mMetaHashMap; - + // 元数据任务列表 private TaskList mMetaList; - + // 存储本地已删除笔记 ID 的 HashSet private HashSet mLocalDeleteIdMap; - + // 存储 Google 任务 ID 到本地笔记 ID 的映射 private HashMap mGidToNid; - + // 存储本地笔记 ID 到 Google 任务 ID 的映射 private HashMap mNidToGid; + /** + * 私有构造函数,用于初始化 GTaskManager 对象。 + * 初始化各种数据结构和状态标志。 + */ private GTaskManager() { mSyncing = false; mCancelled = false; @@ -99,6 +107,11 @@ public class GTaskManager { mNidToGid = new HashMap(); } + /** + * 获取 GTaskManager 的单例对象。 + * 如果对象尚未创建,则创建一个新的实例。 + * @return GTaskManager 的单例对象 + */ public static synchronized GTaskManager getInstance() { if (mInstance == null) { mInstance = new GTaskManager(); @@ -106,11 +119,22 @@ public class GTaskManager { return mInstance; } + /** + * 设置用于获取认证令牌的 Activity 对象。 + * @param activity 调用该方法的 Activity 对象 + */ public synchronized void setActivityContext(Activity activity) { // used for getting authtoken mActivity = activity; } + /** + * 执行 Google 任务的同步操作。 + * 该方法会登录 Google 任务,获取任务列表,并执行内容同步。 + * @param context 调用该方法的 Context 对象 + * @param asyncTask 用于发布同步进度的异步任务对象 + * @return 同步结果的状态码 + */ public int sync(Context context, GTaskASyncTask asyncTask) { if (mSyncing) { Log.d(TAG, "Sync is in progress"); @@ -131,18 +155,18 @@ public class GTaskManager { GTaskClient client = GTaskClient.getInstance(); client.resetUpdateArray(); - // login google task + // 登录 Google 任务 if (!mCancelled) { if (!client.login(mActivity)) { throw new NetworkFailureException("login google task failed"); } } - // get the task list from google + // 获取 Google 任务列表 asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list)); initGTaskList(); - // do content sync work + // 执行内容同步操作 asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing)); syncContent(); } catch (NetworkFailureException e) { @@ -168,6 +192,11 @@ public class GTaskManager { return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS; } + /** + * 初始化 Google 任务列表。 + * 该方法会从 Google 服务器获取任务列表,并初始化元数据和任务节点。 + * @throws NetworkFailureException 如果网络请求失败 + */ private void initGTaskList() throws NetworkFailureException { if (mCancelled) return; @@ -175,7 +204,7 @@ public class GTaskManager { try { JSONArray jsTaskLists = client.getTaskLists(); - // init meta list first + // 初始化元数据列表 mMetaList = null; for (int i = 0; i < jsTaskLists.length(); i++) { JSONObject object = jsTaskLists.getJSONObject(i); @@ -187,7 +216,7 @@ public class GTaskManager { mMetaList = new TaskList(); mMetaList.setContentByRemoteJSON(object); - // load meta data + // 加载元数据 JSONArray jsMetas = client.getTaskList(gid); for (int j = 0; j < jsMetas.length(); j++) { object = (JSONObject) jsMetas.getJSONObject(j); @@ -203,7 +232,7 @@ public class GTaskManager { } } - // create meta list if not existed + // 如果元数据列表不存在,则创建一个新的元数据列表 if (mMetaList == null) { mMetaList = new TaskList(); mMetaList.setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX @@ -211,7 +240,7 @@ public class GTaskManager { GTaskClient.getInstance().createTaskList(mMetaList); } - // init task list + // 初始化任务列表 for (int i = 0; i < jsTaskLists.length(); i++) { JSONObject object = jsTaskLists.getJSONObject(i); String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); @@ -225,7 +254,7 @@ public class GTaskManager { mGTaskListHashMap.put(gid, tasklist); mGTaskHashMap.put(gid, tasklist); - // load tasks + // 加载任务 JSONArray jsTasks = client.getTaskList(gid); for (int j = 0; j < jsTasks.length(); j++) { object = (JSONObject) jsTasks.getJSONObject(j); @@ -247,6 +276,11 @@ public class GTaskManager { } } + /** + * 执行内容同步操作。 + * 该方法会处理本地已删除的笔记、文件夹和笔记的同步,以及刷新本地同步 ID。 + * @throws NetworkFailureException 如果网络请求失败 + */ private void syncContent() throws NetworkFailureException { int syncType; Cursor c = null; @@ -259,7 +293,7 @@ public class GTaskManager { return; } - // for local deleted note + // 处理本地已删除的笔记 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(type<>? AND parent_id=?)", new String[] { @@ -286,10 +320,10 @@ public class GTaskManager { } } - // sync folder first + // 同步文件夹 syncFolder(); - // for note existing in database + // 处理数据库中存在的笔记 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(type=? AND parent_id<>?)", new String[] { @@ -306,10 +340,10 @@ public class GTaskManager { syncType = node.getSyncAction(c); } else { if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { - // local add + // 本地新增 syncType = Node.SYNC_ACTION_ADD_REMOTE; } else { - // remote delete + // 远程删除 syncType = Node.SYNC_ACTION_DEL_LOCAL; } } @@ -326,7 +360,7 @@ public class GTaskManager { } } - // go through remaining items + // 处理剩余的任务项 Iterator> iter = mGTaskHashMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); @@ -334,16 +368,14 @@ public class GTaskManager { doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); } - // 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"); } } - // refresh local sync id + // 刷新本地同步 ID if (!mCancelled) { GTaskClient.getInstance().commitUpdate(); refreshLocalSyncId(); @@ -351,6 +383,11 @@ public class GTaskManager { } + /** + * 同步文件夹。 + * 该方法会处理根文件夹、通话记录文件夹和本地现有文件夹的同步,以及远程新增文件夹的处理。 + * @throws NetworkFailureException 如果网络请求失败 + */ private void syncFolder() throws NetworkFailureException { Cursor c = null; String gid; @@ -361,7 +398,7 @@ public class GTaskManager { return; } - // for root folder + // 处理根文件夹 try { c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null); @@ -373,7 +410,7 @@ public class GTaskManager { mGTaskHashMap.remove(gid); mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER); mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid); - // for system folder, only update remote name if necessary + // 对于系统文件夹,仅在必要时更新远程名称 if (!node.getName().equals( GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); @@ -390,7 +427,7 @@ public class GTaskManager { } } - // for call-note folder + // 处理通话记录文件夹 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)", new String[] { @@ -404,8 +441,7 @@ public class GTaskManager { mGTaskHashMap.remove(gid); mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER); mNidToGid.put((long) Notes.ID_CALL_RECORD_FOLDER, gid); - // for system folder, only update remote name if - // necessary + // 对于系统文件夹,仅在必要时更新远程名称 if (!node.getName().equals( GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) @@ -424,7 +460,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[] { @@ -441,10 +477,10 @@ public class GTaskManager { syncType = node.getSyncAction(c); } else { if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { - // local add + // 本地新增 syncType = Node.SYNC_ACTION_ADD_REMOTE; } else { - // remote delete + // 远程删除 syncType = Node.SYNC_ACTION_DEL_LOCAL; } } @@ -460,7 +496,7 @@ public class GTaskManager { } } - // for remote add folders + // 处理远程新增文件夹 Iterator> iter = mGTaskListHashMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); @@ -476,6 +512,14 @@ public class GTaskManager { GTaskClient.getInstance().commitUpdate(); } + /** + * 根据同步类型执行具体的同步操作。 + * 该方法会根据同步类型调用相应的添加、删除或更新方法。 + * @param syncType 同步类型 + * @param node 任务节点 + * @param c 数据库游标 + * @throws NetworkFailureException 如果网络请求失败 + */ private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; @@ -510,8 +554,8 @@ public class GTaskManager { updateRemoteNode(node, c); break; case Node.SYNC_ACTION_UPDATE_CONFLICT: - // merging both modifications maybe a good idea - // right now just use local update simply + // 合并双方的修改可能是个好主意 + // 目前简单地使用本地更新 updateRemoteNode(node, c); break; case Node.SYNC_ACTION_NONE: @@ -522,6 +566,12 @@ public class GTaskManager { } } + /** + * 在本地添加任务节点。 + * 该方法会根据节点类型创建本地笔记,并更新相关的映射和元数据。 + * @param node 任务节点 + * @throws NetworkFailureException 如果网络请求失败 + */ private void addLocalNode(Node node) throws NetworkFailureException { if (mCancelled) { return; @@ -549,7 +599,7 @@ public class GTaskManager { if (note.has(NoteColumns.ID)) { long id = note.getLong(NoteColumns.ID); if (DataUtils.existInNoteDatabase(mContentResolver, id)) { - // the id is not available, have to create a new one + // 该 ID 不可用,必须创建一个新的 ID note.remove(NoteColumns.ID); } } @@ -562,8 +612,7 @@ public class GTaskManager { if (data.has(DataColumns.ID)) { long dataId = data.getLong(DataColumns.ID); if (DataUtils.existInDataDatabase(mContentResolver, dataId)) { - // the data id is not available, have to create - // a new one + // 该数据 ID 不可用,必须创建一个新的 ID data.remove(DataColumns.ID); } } @@ -584,25 +633,32 @@ public class GTaskManager { sqlNote.setParentId(parentId.longValue()); } - // create the local node + // 创建本地节点 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); } + /** + * 在本地更新任务节点。 + * 该方法会更新本地笔记的内容和父节点,并更新相关的元数据。 + * @param node 任务节点 + * @param c 数据库游标 + * @throws NetworkFailureException 如果网络请求失败 + */ private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; } SqlNote sqlNote; - // update the note locally + // 本地更新笔记 sqlNote = new SqlNote(mContext, c); sqlNote.setContent(node.getLocalJSONFromContent()); @@ -615,10 +671,17 @@ public class GTaskManager { sqlNote.setParentId(parentId.longValue()); sqlNote.commit(true); - // update meta info + // 更新元数据信息 updateRemoteMeta(node.getGid(), sqlNote); } + /** + * 在远程添加任务节点。 + * 该方法会根据本地笔记信息创建远程任务或任务列表,并更新本地笔记的 GTask ID。 + * @param node 任务节点 + * @param c 数据库游标 + * @throws NetworkFailureException 如果网络请求失败 + */ private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; @@ -627,7 +690,7 @@ public class GTaskManager { SqlNote sqlNote = new SqlNote(mContext, c); Node n; - // update remotely + // 远程更新 if (sqlNote.isNoteType()) { Task task = new Task(); task.setContentByLocalJSON(sqlNote.getContent()); @@ -642,12 +705,12 @@ public class GTaskManager { GTaskClient.getInstance().createTask(task); n = (Node) task; - // add meta + // 添加元数据 updateRemoteMeta(task.getGid(), sqlNote); } else { 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; @@ -671,7 +734,7 @@ public class GTaskManager { } } - // no match we can add now + // 如果没有匹配的文件夹,则添加新的文件夹 if (tasklist == null) { tasklist = new TaskList(); tasklist.setContentByLocalJSON(sqlNote.getContent()); @@ -681,17 +744,24 @@ public class GTaskManager { n = (Node) tasklist; } - // update local note + // 更新本地笔记 sqlNote.setGtaskId(n.getGid()); sqlNote.commit(false); sqlNote.resetLocalModified(); sqlNote.commit(true); - // gid-id mapping + // gid-id 映射 mGidToNid.put(n.getGid(), sqlNote.getId()); mNidToGid.put(sqlNote.getId(), n.getGid()); } + /** + * 在远程更新任务节点。 + * 该方法会更新远程任务的内容和父节点,并清除本地修改标志。 + * @param node 任务节点 + * @param c 数据库游标 + * @throws NetworkFailureException 如果网络请求失败 + */ private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; @@ -699,14 +769,14 @@ 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(); @@ -725,11 +795,18 @@ public class GTaskManager { } } - // clear local modified flag + // 清除本地修改标志 sqlNote.resetLocalModified(); sqlNote.commit(true); } + /** + * 更新远程元数据。 + * 该方法会根据笔记信息更新远程元数据。 + * @param gid 任务节点的 GTask ID + * @param sqlNote 本地笔记对象 + * @throws NetworkFailureException 如果网络请求失败 + */ private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException { if (sqlNote != null && sqlNote.isNoteType()) { MetaData metaData = mMetaHashMap.get(gid); @@ -746,12 +823,17 @@ public class GTaskManager { } } + /** + * 刷新本地同步 ID。 + * 该方法会获取最新的 Google 任务列表,并更新本地笔记的同步 ID。 + * @throws NetworkFailureException 如果网络请求失败 + */ private void refreshLocalSyncId() throws NetworkFailureException { if (mCancelled) { return; } - // get the latest gtask list + // 获取最新的 Google 任务列表 mGTaskHashMap.clear(); mGTaskListHashMap.clear(); mMetaHashMap.clear(); @@ -790,11 +872,19 @@ public class GTaskManager { } } + /** + * 获取同步账户的名称。 + * @return 同步账户的名称 + */ public String getSyncAccount() { return GTaskClient.getInstance().getSyncAccount().name; } + /** + * 取消同步操作。 + * 设置取消标志为 true。 + */ public void cancelSync() { mCancelled = true; } -} +} \ No newline at end of file diff --git a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java index cca36f7..f039486 100644 --- a/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java +++ b/src/Notes/Notes/app/src/main/java/net/micode/notes/gtask/remote/GTaskSyncService.java @@ -23,106 +23,114 @@ import android.content.Intent; import android.os.Bundle; import android.os.IBinder; +// GTaskSyncService 是一个用于管理 Google 任务同步的服务 public class GTaskSyncService extends Service { - public final static String ACTION_STRING_NAME = "sync_action_type"; + // 定义广播相关的常量 + public final static String ACTION_STRING_NAME = "sync_action_type"; // 广播中用于标识同步操作类型的键 + public final static int ACTION_START_SYNC = 0; // 开始同步操作 + public final static int ACTION_CANCEL_SYNC = 1; // 取消同步操作 + public final static int ACTION_INVALID = 2; // 无效操作 - public final static int ACTION_START_SYNC = 0; + public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service"; // 广播的名称 + public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing"; // 广播中用于标识是否正在同步的键 + public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg"; // 广播中用于标识同步进度信息的键 - public final static int ACTION_CANCEL_SYNC = 1; - - public final static int ACTION_INVALID = 2; - - public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service"; - - public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing"; - - public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg"; - - private static GTaskASyncTask mSyncTask = null; - - private static String mSyncProgress = ""; + // 静态变量,用于管理同步任务 + private static GTaskASyncTask mSyncTask = null; // 当前的同步任务 + private static String mSyncProgress = ""; // 同步进度信息 + // 开始同步任务 private void startSync() { if (mSyncTask == null) { mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() { public void onComplete() { - mSyncTask = null; - sendBroadcast(""); - stopSelf(); + mSyncTask = null; // 同步完成时,清空同步任务 + sendBroadcast(""); // 发送广播通知同步完成 + stopSelf(); // 停止服务 } }); - sendBroadcast(""); - mSyncTask.execute(); + sendBroadcast(""); // 发送广播通知同步开始 + mSyncTask.execute(); // 执行同步任务 } } + // 取消同步任务 private void cancelSync() { if (mSyncTask != null) { - mSyncTask.cancelSync(); + mSyncTask.cancelSync(); // 调用同步任务的取消方法 } } + // 服务创建时调用 @Override public void onCreate() { - mSyncTask = null; + mSyncTask = null; // 初始化同步任务为 null } + // 服务启动时调用 @Override public int onStartCommand(Intent intent, int flags, int startId) { - Bundle bundle = intent.getExtras(); + Bundle bundle = intent.getExtras(); // 获取启动服务时传递的额外数据 if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) { switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) { - case ACTION_START_SYNC: - startSync(); + case ACTION_START_SYNC: // 如果是开始同步操作 + startSync(); // 调用 startSync 方法开始同步 break; - case ACTION_CANCEL_SYNC: - cancelSync(); + case ACTION_CANCEL_SYNC: // 如果是取消同步操作 + cancelSync(); // 调用 cancelSync 方法取消同步 break; - default: + default: // 其他无效操作 break; } - return START_STICKY; + return START_STICKY; // 返回 START_STICKY,表示如果服务被系统杀死,系统会尝试重新启动服务 } - return super.onStartCommand(intent, flags, startId); + return super.onStartCommand(intent, flags, startId); // 如果没有传递有效的操作类型,调用父类方法 } + // 在低内存情况下调用 @Override public void onLowMemory() { if (mSyncTask != null) { - mSyncTask.cancelSync(); + mSyncTask.cancelSync(); // 在低内存情况下取消同步任务 } } + // 服务绑定时调用 public IBinder onBind(Intent intent) { - return null; + return null; // 该服务不支持绑定,返回 null } + // 发送广播通知同步状态或进度 public void sendBroadcast(String msg) { - mSyncProgress = msg; - Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME); - intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); - intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); - sendBroadcast(intent); + mSyncProgress = msg; // 更新同步进度信息 + Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME); // 创建广播意图 + intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); // 添加是否正在同步的信息 + intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); // 添加同步进度信息 + sendBroadcast(intent); // 发送广播 } + // 静态方法,用于从 Activity 启动同步服务 public static void startSync(Activity activity) { - GTaskManager.getInstance().setActivityContext(activity); - Intent intent = new Intent(activity, GTaskSyncService.class); - intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC); - activity.startService(intent); + GTaskManager.getInstance().setActivityContext(activity); // 设置 Activity 上下文到 GTaskManager + Intent intent = new Intent(activity, GTaskSyncService.class); // 创建启动服务的意图 + intent.putExtra(GTASK_SERVICE_BROADCAST_NAME, ACTION_START_SYNC); // 添加开始同步的操作类型 + activity.startService(intent); // 启动服务 } + // 静态方法,用于取消同步 public static void cancelSync(Context context) { - Intent intent = new Intent(context, GTaskSyncService.class); - intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC); - context.startService(intent); + Intent intent = new Intent(context, GTaskSyncService.class); // 创建启动服务的意图 + intent.putExtra(GTASK_SERVICE_BROADCAST_NAME, ACTION_CANCEL_SYNC); // 添加取消同步的操作类型 + context.startService(intent); // 启动服务 } + // 静态方法,用于检查是否正在同步 public static boolean isSyncing() { - return mSyncTask != null; + return mSyncTask != null; // 如果 mSyncTask 不为 null,则表示正在同步 } + // 静态方法,用于获取同步进度信息 public static String getProgressString() { - return mSyncProgress; + return mSyncProgress; // 返回同步进度信息 } -} +} \ No newline at end of file