From e303788fac81f968a2418109d5dfe1c5d596193f Mon Sep 17 00:00:00 2001 From: cnz <2869874844@qq.com> Date: Mon, 19 May 2025 17:17:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A2=81=E5=93=B2=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notes/gtask/remote/GTaskClient.java | 181 ++++++++++++------ 1 file changed, 118 insertions(+), 63 deletions(-) diff --git a/src/net/micode/notes/gtask/remote/GTaskClient.java b/src/net/micode/notes/gtask/remote/GTaskClient.java index c67dfdf..f1c70a1 100644 --- a/src/net/micode/notes/gtask/remote/GTaskClient.java +++ b/src/net/micode/notes/gtask/remote/GTaskClient.java @@ -14,7 +14,9 @@ * limitations under the License. */ -package net.micode.notes.gtask.remote; + //这个类实现了完整的Google Tasks API客户端功能,为上层应用提供了简洁的接口来管理Google任务数据。 + +package net.micode.notes.gtask.remote;//导入包 import android.accounts.Account; import android.accounts.AccountManager; @@ -60,36 +62,33 @@ import java.util.zip.GZIPInputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; - +/** + * Google任务客户端类,负责与Google Tasks API交互 + */ public class GTaskClient { private static final String TAG = GTaskClient.class.getSimpleName(); + // Google任务相关URL常量 private static final String GTASK_URL = "https://mail.google.com/tasks/"; - private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig"; - private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig"; - private static GTaskClient mInstance = null; + private static GTaskClient mInstance = null; // 单例实例 + // HTTP客户端和相关属性 private DefaultHttpClient mHttpClient; - private String mGetUrl; - private String mPostUrl; - - private long mClientVersion; - - private boolean mLoggedin; - - private long mLastLoginTime; - - private int mActionId; - - private Account mAccount; - - private JSONArray mUpdateArray; - + private long mClientVersion; // 客户端版本 + private boolean mLoggedin; // 登录状态 + private long mLastLoginTime; // 最后登录时间 + private int mActionId; // 动作ID计数器 + private Account mAccount; // 当前账户 + private JSONArray mUpdateArray; // 待更新的动作数组 + + /** + * 私有构造函数 + */ private GTaskClient() { mHttpClient = null; mGetUrl = GTASK_GET_URL; @@ -102,6 +101,9 @@ public class GTaskClient { mUpdateArray = null; } + /** + * 获取单例实例 + */ public static synchronized GTaskClient getInstance() { if (mInstance == null) { mInstance = new GTaskClient(); @@ -109,18 +111,21 @@ public class GTaskClient { return mInstance; } + /** + * 登录Google任务 + * @param activity 活动上下文 + * @return 是否登录成功 + */ 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))) { + // 检查账户是否变更 + if (mLoggedin && !TextUtils.equals(getSyncAccount().name, + NotesPreferenceActivity.getSyncAccountName(activity))) { mLoggedin = false; } @@ -130,15 +135,16 @@ public class GTaskClient { } 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 - if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() - .endsWith("googlemail.com"))) { + // 处理自定义域名账户(非gmail.com/googlemail.com) + if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || + mAccount.name.toLowerCase().endsWith("googlemail.com"))) { StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); int index = mAccount.name.indexOf('@') + 1; String suffix = mAccount.name.substring(index); @@ -151,7 +157,7 @@ public class GTaskClient { } } - // try to login with google official url + // 尝试使用官方Google URL登录 if (!mLoggedin) { mGetUrl = GTASK_GET_URL; mPostUrl = GTASK_POST_URL; @@ -164,6 +170,9 @@ public class GTaskClient { return true; } + /** + * 登录Google账户获取认证令牌 + */ private String loginGoogleAccount(Activity activity, boolean invalidateToken) { String authToken; AccountManager accountManager = AccountManager.get(activity); @@ -174,6 +183,7 @@ public class GTaskClient { return null; } + // 获取设置中配置的同步账户 String accountName = NotesPreferenceActivity.getSyncAccountName(activity); Account account = null; for (Account a : accounts) { @@ -189,7 +199,7 @@ public class GTaskClient { return null; } - // get the token now + // 获取认证令牌 AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, "goanna_mobile", null, activity, null, null); try { @@ -207,10 +217,12 @@ public class GTaskClient { return authToken; } + /** + * 尝试登录Google任务 + */ 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"); @@ -225,7 +237,11 @@ public class GTaskClient { return true; } + /** + * 实际执行Google任务登录 + */ private boolean loginGtask(String authToken) { + // 设置HTTP参数 int timeoutConnection = 10000; int timeoutSocket = 15000; HttpParams httpParameters = new BasicHttpParams(); @@ -236,14 +252,13 @@ public class GTaskClient { mHttpClient.setCookieStore(localBasicCookieStore); HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); - // login gtask + // 登录Google任务 try { String loginUrl = mGetUrl + "?auth=" + authToken; HttpGet httpGet = new HttpGet(loginUrl); - HttpResponse response = null; - response = mHttpClient.execute(httpGet); + HttpResponse response = mHttpClient.execute(httpGet); - // get the cookie now + // 检查认证cookie List cookies = mHttpClient.getCookieStore().getCookies(); boolean hasAuthCookie = false; for (Cookie cookie : cookies) { @@ -255,7 +270,7 @@ public class GTaskClient { 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,7 +287,6 @@ public class GTaskClient { e.printStackTrace(); return false; } catch (Exception e) { - // simply catch all exceptions Log.e(TAG, "httpget gtask_url failed"); return false; } @@ -280,10 +294,16 @@ public class GTaskClient { return true; } + /** + * 获取下一个动作ID + */ private int getActionId() { return mActionId++; } + /** + * 创建HTTP POST请求 + */ private HttpPost createHttpPost() { HttpPost httpPost = new HttpPost(mPostUrl); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); @@ -291,6 +311,9 @@ public class GTaskClient { return httpPost; } + /** + * 获取HTTP响应内容 + */ private String getResponseContent(HttpEntity entity) throws IOException { String contentEncoding = null; if (entity.getContentEncoding() != null) { @@ -299,6 +322,7 @@ public class GTaskClient { } InputStream input = entity.getContent(); + // 处理GZIP和DEFLATE压缩 if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { input = new GZIPInputStream(entity.getContent()); } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) { @@ -323,6 +347,9 @@ public class GTaskClient { } } + /** + * 发送POST请求 + */ private JSONObject postRequest(JSONObject js) throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); @@ -336,7 +363,7 @@ public class GTaskClient { 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); @@ -360,20 +387,23 @@ public class GTaskClient { } } + /** + * 创建任务 + */ 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); @@ -386,20 +416,23 @@ public class GTaskClient { } } + /** + * 创建任务列表 + */ 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); @@ -412,17 +445,21 @@ public class GTaskClient { } } + /** + * 提交所有待更新操作 + */ 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,10 +470,12 @@ public class GTaskClient { } } + /** + * 添加待更新节点 + */ public void addUpdateNode(Node node) throws NetworkFailureException { if (node != null) { - // too many update items may result in an error - // set max to 10 items + // 防止更新项过多导致错误,限制最多10项 if (mUpdateArray != null && mUpdateArray.length() > 10) { commitUpdate(); } @@ -447,6 +486,9 @@ public class GTaskClient { } } + /** + * 移动任务 + */ public void moveTask(Task task, TaskList preParent, TaskList curParent) throws NetworkFailureException { commitUpdate(); @@ -455,26 +497,25 @@ public class GTaskClient { 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 + // 同一任务列表内移动时设置前一个兄弟节点ID 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 + // 不同任务列表间移动时设置目标列表ID 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); @@ -486,18 +527,21 @@ public class GTaskClient { } } + /** + * 删除节点 + */ 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); @@ -509,6 +553,9 @@ public class GTaskClient { } } + /** + * 获取所有任务列表 + */ public JSONArray getTaskLists() throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); @@ -517,10 +564,9 @@ public class GTaskClient { try { HttpGet httpGet = new HttpGet(mGetUrl); - HttpResponse response = null; - response = mHttpClient.execute(httpGet); + HttpResponse response = mHttpClient.execute(httpGet); - // get the task list + // 解析响应获取任务列表 String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -547,6 +593,9 @@ public class GTaskClient { } } + /** + * 获取指定任务列表的所有任务 + */ public JSONArray getTaskList(String listGid) throws NetworkFailureException { commitUpdate(); try { @@ -554,7 +603,7 @@ public class GTaskClient { 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()); @@ -563,7 +612,7 @@ public class GTaskClient { 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); @@ -575,11 +624,17 @@ public class GTaskClient { } } + /** + * 获取当前同步账户 + */ public Account getSyncAccount() { return mAccount; } + /** + * 重置更新数组 + */ public void resetUpdateArray() { mUpdateArray = null; } -} +} \ No newline at end of file