diff --git a/java/net/micode/notes/gtask/remote/GTaskClient.java b/java/net/micode/notes/gtask/remote/GTaskClient.java index c67dfdf..d8ddc99 100644 --- a/java/net/micode/notes/gtask/remote/GTaskClient.java +++ b/java/net/micode/notes/gtask/remote/GTaskClient.java @@ -65,31 +65,22 @@ public class GTaskClient { private static final String TAG = GTaskClient.class.getSimpleName(); 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 DefaultHttpClient mHttpClient; - - private String mGetUrl; - - private String mPostUrl; - - private long mClientVersion; - - private boolean mLoggedin; - - private long mLastLoginTime; - - private int mActionId; - - private Account mAccount; + private static GTaskClient mInstance = null; // 单例实例 - private JSONArray mUpdateArray; + private DefaultHttpClient mHttpClient; // HTTP客户端 + private String mGetUrl; // GET请求URL + private String mPostUrl; // POST请求URL + 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 +93,7 @@ public class GTaskClient { mUpdateArray = null; } + // 获取单例实例 public static synchronized GTaskClient getInstance() { if (mInstance == null) { mInstance = new GTaskClient(); @@ -109,15 +101,18 @@ public class GTaskClient { return mInstance; } + // 登录Google账户 public boolean login(Activity activity) { // we suppose that the cookie would expire after 5 minutes // then we need to re-login + // 检查是否需要重新登录(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))) { @@ -137,6 +132,7 @@ public class GTaskClient { } // login with custom domain if necessary + // 处理自定义域名账户 if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() .endsWith("googlemail.com"))) { StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); @@ -152,6 +148,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 +161,7 @@ public class GTaskClient { return true; } + // 登录Google账户并获取认证令牌 private String loginGoogleAccount(Activity activity, boolean invalidateToken) { String authToken; AccountManager accountManager = AccountManager.get(activity); @@ -174,6 +172,7 @@ public class GTaskClient { return null; } + // 获取同步账户 String accountName = NotesPreferenceActivity.getSyncAccountName(activity); Account account = null; for (Account a : accounts) { @@ -190,6 +189,7 @@ public class GTaskClient { } // get the token now + // 获取认证令牌 AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, "goanna_mobile", null, activity, null, null); try { @@ -207,10 +207,12 @@ public class GTaskClient { return authToken; } + // 尝试登录Google Tasks 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 +227,9 @@ public class GTaskClient { return true; } + // 登录Google Tasks服务 private boolean loginGtask(String authToken) { + // 设置HTTP客户端参数 int timeoutConnection = 10000; int timeoutSocket = 15000; HttpParams httpParameters = new BasicHttpParams(); @@ -237,6 +241,7 @@ public class GTaskClient { HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); // login gtask + // 登录Google Tasks try { String loginUrl = mGetUrl + "?auth=" + authToken; HttpGet httpGet = new HttpGet(loginUrl); @@ -244,6 +249,7 @@ public class GTaskClient { response = mHttpClient.execute(httpGet); // get the cookie now + // 检查认证Cookie List cookies = mHttpClient.getCookieStore().getCookies(); boolean hasAuthCookie = false; for (Cookie cookie : cookies) { @@ -256,6 +262,7 @@ public class GTaskClient { } // get the client version + // 获取客户端版本 String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -280,10 +287,12 @@ 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 +300,7 @@ public class GTaskClient { return httpPost; } + // 处理HTTP响应内容 private String getResponseContent(HttpEntity entity) throws IOException { String contentEncoding = null; if (entity.getContentEncoding() != null) { @@ -298,6 +308,7 @@ public class GTaskClient { Log.d(TAG, "encoding: " + contentEncoding); } + // 处理压缩响应 InputStream input = entity.getContent(); if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { input = new GZIPInputStream(entity.getContent()); @@ -323,6 +334,7 @@ public class GTaskClient { } } + // 发送POST请求 private JSONObject postRequest(JSONObject js) throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); @@ -337,6 +349,7 @@ public class GTaskClient { httpPost.setEntity(entity); // execute the post + // 执行POST请求 HttpResponse response = mHttpClient.execute(httpPost); String jsString = getResponseContent(response.getEntity()); return new JSONObject(jsString); @@ -360,6 +373,7 @@ public class GTaskClient { } } + // 创建任务 public void createTask(Task task) throws NetworkFailureException { commitUpdate(); try { @@ -367,6 +381,7 @@ public class GTaskClient { JSONArray actionList = new JSONArray(); // action_list + // 添加创建任务的操作 actionList.put(task.getCreateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); @@ -374,6 +389,7 @@ public class GTaskClient { jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); // post + // 发送请求并获取新任务ID JSONObject jsResponse = postRequest(jsPost); JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( GTaskStringUtils.GTASK_JSON_RESULTS).get(0); @@ -386,6 +402,7 @@ public class GTaskClient { } } + // 创建任务列表 public void createTaskList(TaskList tasklist) throws NetworkFailureException { commitUpdate(); try { @@ -393,6 +410,7 @@ public class GTaskClient { JSONArray actionList = new JSONArray(); // action_list + // 添加创建任务列表的操作 actionList.put(tasklist.getCreateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); @@ -400,6 +418,7 @@ public class GTaskClient { jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); // post + // 发送请求并获取新任务列表ID JSONObject jsResponse = postRequest(jsPost); JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( GTaskStringUtils.GTASK_JSON_RESULTS).get(0); @@ -412,6 +431,7 @@ public class GTaskClient { } } + // 提交更新操作 public void commitUpdate() throws NetworkFailureException { if (mUpdateArray != null) { try { @@ -433,10 +453,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 +469,8 @@ public class GTaskClient { } } + + // 移动任务 public void moveTask(Task task, TaskList preParent, TaskList curParent) throws NetworkFailureException { commitUpdate(); @@ -456,10 +480,12 @@ public class GTaskClient { 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()); + // 设置前置兄弟任务ID,如果在同一任务列表中移动且不是第一个任务 if (preParent == curParent && task.getPriorSibling() != null) { // put prioring_sibing_id only if moving within the tasklist and // it is not the first one @@ -467,6 +493,8 @@ public class GTaskClient { } action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); + + // 设置目标任务列表ID(如果在不同任务列表之间移动) if (preParent != curParent) { // put the dest_list only if moving between tasklists action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid()); @@ -486,6 +514,7 @@ public class GTaskClient { } } + // 删除节点 public void deleteNode(Node node) throws NetworkFailureException { commitUpdate(); try { @@ -493,6 +522,7 @@ public class GTaskClient { JSONArray actionList = new JSONArray(); // action_list + // 设置节点为已删除并添加更新操作 node.setDeleted(true); actionList.put(node.getUpdateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); @@ -509,6 +539,7 @@ public class GTaskClient { } } + // 获取任务列表 public JSONArray getTaskLists() throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); @@ -521,6 +552,7 @@ public class GTaskClient { response = mHttpClient.execute(httpGet); // get the task list + // 解析响应内容获取任务列表 String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -547,6 +579,7 @@ public class GTaskClient { } } + // 获取特定任务列表中的任务 public JSONArray getTaskList(String listGid) throws NetworkFailureException { commitUpdate(); try { @@ -555,6 +588,7 @@ public class GTaskClient { 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()); @@ -575,10 +609,12 @@ public class GTaskClient { } } + // 获取同步账户 public Account getSyncAccount() { return mAccount; } + // 重置更新数组 public void resetUpdateArray() { mUpdateArray = null; }