pbg7l8cy5 1 month ago
parent ada8cdece0
commit 449aab321a

@ -28,89 +28,99 @@ import net.micode.notes.R;
import net.micode.notes.ui.NotesListActivity; import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity; import net.micode.notes.ui.NotesPreferenceActivity;
// GTaskASyncTask类继承自AsyncTask用于在后台执行Google任务同步操作
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> { public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
// 定义一个静态常量用于标识同步任务的通知ID
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235; private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
// 定义一个接口,用于在异步任务完成时回调
public interface OnCompleteListener { public interface OnCompleteListener {
// 定义一个方法,在异步任务完成时被调用
void onComplete(); void onComplete();
} }
// 应用上下文对象
private Context mContext; private Context mContext;
// 通知管理器,用于显示和取消通知
private NotificationManager mNotifiManager; private NotificationManager mNotifiManager;
// 任务管理器,用于处理同步任务
private GTaskManager mTaskManager; private GTaskManager mTaskManager;
// 异步任务完成时的回调监听器
private OnCompleteListener mOnCompleteListener; private OnCompleteListener mOnCompleteListener;
// 构造方法,初始化上下文、回调监听器、通知管理器和任务管理器
public GTaskASyncTask(Context context, OnCompleteListener listener) { public GTaskASyncTask(Context context, OnCompleteListener listener) {
mContext = context; mContext = context;
mOnCompleteListener = listener; mOnCompleteListener = listener;
mNotifiManager = (NotificationManager) mContext mNotifiManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE); .getSystemService(Context.NOTIFICATION_SERVICE);// 从系统服务获取通知管理器
mTaskManager = GTaskManager.getInstance(); mTaskManager = GTaskManager.getInstance();// 获取任务管理器的实例
} }
// 取消同步操作
public void cancelSync() { public void cancelSync() {
mTaskManager.cancelSync(); mTaskManager.cancelSync();// 调用任务管理器的取消同步方法
} }
// 发布进度更新
public void publishProgess(String message) { public void publishProgess(String message) {
publishProgress(new String[] { publishProgress(new String[] {
message message
}); });// 调用AsyncTask的publishProgress方法来更新进度
} }
// 显示通知
private void showNotification(int tickerId, String content) { private void showNotification(int tickerId, String content) { // 创建一个新的通知对象
Notification notification = new Notification(R.drawable.notification, mContext Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis()); .getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS; notification.defaults = Notification.DEFAULT_LIGHTS;// 设置通知的默认灯
notification.flags = Notification.FLAG_AUTO_CANCEL; notification.flags = Notification.FLAG_AUTO_CANCEL;// 设置通知标志为自动取消
// 根据通知类型设置不同的PendingIntent
PendingIntent pendingIntent; PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) { if (tickerId != R.string.ticker_success) {
// 如果不是成功通知则点击通知后打开NotesPreferenceActivity
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), 0); NotesPreferenceActivity.class), 0);
} else { } else {
// 如果是成功通知则点击通知后打开NotesListActivity
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), 0); NotesListActivity.class), 0);
} }
// 设置通知的内容
notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content, notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
pendingIntent); pendingIntent);
// 通过通知管理器显示通知
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification); mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
} }
@Override @Override
protected Integer doInBackground(Void... unused) { protected Integer doInBackground(Void... unused) {
// 发布登录进度的通知
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext))); .getSyncAccountName(mContext)));
// 执行同步操作,并返回同步结果
return mTaskManager.sync(mContext, this); return mTaskManager.sync(mContext, this);
} }
@Override @Override
protected void onProgressUpdate(String... progress) { protected void onProgressUpdate(String... progress) { // 显示同步进行中的通知
showNotification(R.string.ticker_syncing, progress[0]); showNotification(R.string.ticker_syncing, progress[0]);// 如果mContext是GTaskSyncService的实例则通过它发送广播广播的内容是progress数组的第一个元素
if (mContext instanceof GTaskSyncService) { if (mContext instanceof GTaskSyncService) {
((GTaskSyncService) mContext).sendBroadcast(progress[0]); ((GTaskSyncService) mContext).sendBroadcast(progress[0]);
} }
} }
@Override @Override
protected void onPostExecute(Integer result) { protected void onPostExecute(Integer result) {// 根据同步结果result执行不同的操作
if (result == GTaskManager.STATE_SUCCESS) { if (result == GTaskManager.STATE_SUCCESS) { // 如果同步成功,显示成功的通知,并更新最后同步时间
showNotification(R.string.ticker_success, mContext.getString( showNotification(R.string.ticker_success, mContext.getString(
R.string.success_sync_account, mTaskManager.getSyncAccount())); R.string.success_sync_account, mTaskManager.getSyncAccount()));
NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis());
} else if (result == GTaskManager.STATE_NETWORK_ERROR) { } else if (result == GTaskManager.STATE_NETWORK_ERROR) {// 如果发生网络错误,显示网络错误的通知
showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network)); showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network));
} else if (result == GTaskManager.STATE_INTERNAL_ERROR) { } else if (result == GTaskManager.STATE_INTERNAL_ERROR) {// 如果发生内部错误,显示内部错误的通知
showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal)); showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal));
} else if (result == GTaskManager.STATE_SYNC_CANCELLED) { } else if (result == GTaskManager.STATE_SYNC_CANCELLED) { // 如果同步被取消,显示取消的通知
showNotification(R.string.ticker_cancel, mContext showNotification(R.string.ticker_cancel, mContext
.getString(R.string.error_sync_cancelled)); .getString(R.string.error_sync_cancelled));
} }
// 如果mOnCompleteListener不为null启动一个新线程来调用它的onComplete方法
if (mOnCompleteListener != null) { if (mOnCompleteListener != null) {
new Thread(new Runnable() { new Thread(new Runnable() {

@ -62,35 +62,37 @@ import java.util.zip.InflaterInputStream;
public class GTaskClient { public class GTaskClient {
// 类标签,用于日志输出
private static final String TAG = GTaskClient.class.getSimpleName(); private static final String TAG = GTaskClient.class.getSimpleName();
// Google Tasks服务的基URL
private static final String GTASK_URL = "https://mail.google.com/tasks/"; 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"; 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 final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig";
// GTaskClient的单例实例
private static GTaskClient mInstance = null; private static GTaskClient mInstance = null;
// HTTP客户端用于发送请求
private DefaultHttpClient mHttpClient; private DefaultHttpClient mHttpClient;
// 当前使用的获取数据的URL
private String mGetUrl; private String mGetUrl;
// 当前使用的提交数据的URL
private String mPostUrl; private String mPostUrl;
// 客户端版本号
private long mClientVersion; private long mClientVersion;
// 登录状态
private boolean mLoggedin; private boolean mLoggedin;
// 最后一次登录时间
private long mLastLoginTime; private long mLastLoginTime;
// 操作ID用于标识不同的操作
private int mActionId; private int mActionId;
// 当前登录的账户
private Account mAccount; private Account mAccount;
// 更新数据数组
private JSONArray mUpdateArray; private JSONArray mUpdateArray;
private GTaskClient() { private GTaskClient() {
mHttpClient = null; mHttpClient = null;
mGetUrl = GTASK_GET_URL; mGetUrl = GTASK_GET_URL;
mPostUrl = GTASK_POST_URL; mPostUrl = GTASK_POST_URL;
@ -109,15 +111,17 @@ public class GTaskClient {
return mInstance; return mInstance;
} }
public boolean login(Activity activity) { public boolean login(Activity activity) { // 假设cookie在5分钟后过期需要重新登录
// we suppose that the cookie would expire after 5 minutes // we suppose that the cookie would expire after 5 minutes
// then we need to re-login // then we need to re-login
final long interval = 1000 * 60 * 5; final long interval = 1000 * 60 * 5;
// 切换账户后需要重新登录
if (mLastLoginTime + interval < System.currentTimeMillis()) { if (mLastLoginTime + interval < System.currentTimeMillis()) {
mLoggedin = false; mLoggedin = false;
} }
// need to re-login after account switch // need to re-login after account switch
// 如果已经登录直接返回true
if (mLoggedin if (mLoggedin
&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity && !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity
.getSyncAccountName(activity))) { .getSyncAccountName(activity))) {
@ -128,14 +132,15 @@ public class GTaskClient {
Log.d(TAG, "already logged in"); Log.d(TAG, "already logged in");
return true; return true;
} }
// 更新最后一次登录时间
mLastLoginTime = System.currentTimeMillis(); mLastLoginTime = System.currentTimeMillis();
// 获取Google账户的认证令牌
String authToken = loginGoogleAccount(activity, false); String authToken = loginGoogleAccount(activity, false);
if (authToken == null) { if (authToken == null) {
Log.e(TAG, "login google account failed"); Log.e(TAG, "login google account failed");
return false; return false;
} }
// 如果账户不是gmail.com或googlemail.com使用自定义域名登录
// login with custom domain if necessary // login with custom domain if necessary
if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase()
.endsWith("googlemail.com"))) { .endsWith("googlemail.com"))) {
@ -159,29 +164,33 @@ public class GTaskClient {
return false; return false;
} }
} }
// 设置登录状态为true并返回true表示登录成功
mLoggedin = true; mLoggedin = true;
return true; return true;
} }
// 登录Google账户的函数接收一个Activity实例和一个标志位来决定是否使当前的token无效
private String loginGoogleAccount(Activity activity, boolean invalidateToken) { private String loginGoogleAccount(Activity activity, boolean invalidateToken) {
String authToken; String authToken;// 用于存储获取到的认证token
AccountManager accountManager = AccountManager.get(activity); AccountManager accountManager = AccountManager.get(activity);// 获取AccountManager实例
Account[] accounts = accountManager.getAccountsByType("com.google"); Account[] accounts = accountManager.getAccountsByType("com.google");// 获取所有Google类型的账户
// 如果没有可用的Google账户则记录错误日志并返回null
if (accounts.length == 0) { if (accounts.length == 0) {
Log.e(TAG, "there is no available google account"); Log.e(TAG, "there is no available google account");
return null; return null;
} }
// 从设置中获取同步账户的名称
String accountName = NotesPreferenceActivity.getSyncAccountName(activity); String accountName = NotesPreferenceActivity.getSyncAccountName(activity);
Account account = null; Account account = null;
// 遍历所有账户,找到与设置中的账户名匹配的账户
for (Account a : accounts) { for (Account a : accounts) {
if (a.name.equals(accountName)) { if (a.name.equals(accountName)) {
account = a; account = a;
break; break;
} }
} }
// 如果找到了匹配的账户则将其存储在mAccount变量中否则记录错误日志并返回null
if (account != null) { if (account != null) {
mAccount = account; mAccount = account;
} else { } else {
@ -190,60 +199,66 @@ public class GTaskClient {
} }
// get the token now // get the token now
// 获取认证token
AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthToken(account, AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthToken(account,
"goanna_mobile", null, activity, null, null); "goanna_mobile", null, activity, null, null);
try { try {
Bundle authTokenBundle = accountManagerFuture.getResult(); Bundle authTokenBundle = accountManagerFuture.getResult();// 获取结果
authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN); authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN);// 从结果中获取token
// 如果需要使token无效则调用invalidateAuthToken并递归调用loginGoogleAccount以获取新的token
if (invalidateToken) { if (invalidateToken) {
accountManager.invalidateAuthToken("com.google", authToken); accountManager.invalidateAuthToken("com.google", authToken);
loginGoogleAccount(activity, false); loginGoogleAccount(activity, false);
} }
} catch (Exception e) { } catch (Exception e) {
// 如果获取token失败则记录错误日志并将authToken设置为null
Log.e(TAG, "get auth token failed"); Log.e(TAG, "get auth token failed");
authToken = null; authToken = null;
} }
return authToken; return authToken;// 返回获取到的token
} }
// 尝试使用Google账户登录Google Tasks的函数
private boolean tryToLoginGtask(Activity activity, String authToken) { private boolean tryToLoginGtask(Activity activity, String authToken) {
// 尝试使用提供的token登录Google Tasks
if (!loginGtask(authToken)) { if (!loginGtask(authToken)) {
// 如果登录失败可能是因为token已过期因此使token无效并尝试重新登录
// maybe the auth token is out of date, now let's invalidate the // maybe the auth token is out of date, now let's invalidate the
// token and try again // token and try again
authToken = loginGoogleAccount(activity, true); authToken = loginGoogleAccount(activity, true);
if (authToken == null) { if (authToken == null) {// 如果重新登录失败则记录错误日志并返回false
Log.e(TAG, "login google account failed"); Log.e(TAG, "login google account failed");
return false; return false;
} }
// 使用新的token再次尝试登录Google Tasks
if (!loginGtask(authToken)) { if (!loginGtask(authToken)) {
Log.e(TAG, "login gtask failed"); Log.e(TAG, "login gtask failed");
return false; return false;
} }
} }
return true; return true;// 登录成功返回true
} }
// 使用提供的token登录Google Tasks的函数
private boolean loginGtask(String authToken) { private boolean loginGtask(String authToken) {
// 设置HTTP连接的超时时间
int timeoutConnection = 10000; int timeoutConnection = 10000;
int timeoutSocket = 15000; int timeoutSocket = 15000;
HttpParams httpParameters = new BasicHttpParams(); HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
mHttpClient = new DefaultHttpClient(httpParameters); mHttpClient = new DefaultHttpClient(httpParameters);// 创建HttpClient实例
BasicCookieStore localBasicCookieStore = new BasicCookieStore(); BasicCookieStore localBasicCookieStore = new BasicCookieStore();// 创建Cookie存储实例
mHttpClient.setCookieStore(localBasicCookieStore); mHttpClient.setCookieStore(localBasicCookieStore);// 设置HttpClient的Cookie存储
HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false);// 禁用Expect-Continue握手
// login gtask // 构造登录Google Tasks的URL
try { try {
String loginUrl = mGetUrl + "?auth=" + authToken; String loginUrl = mGetUrl + "?auth=" + authToken;
HttpGet httpGet = new HttpGet(loginUrl); HttpGet httpGet = new HttpGet(loginUrl);// 创建HttpGet请求
HttpResponse response = null; HttpResponse response = null;
response = mHttpClient.execute(httpGet); response = mHttpClient.execute(httpGet);// 执行HttpGet请求
// get the cookie now // 检查响应中的Cookie看是否有认证Cookie
List<Cookie> cookies = mHttpClient.getCookieStore().getCookies(); List<Cookie> cookies = mHttpClient.getCookieStore().getCookies();
boolean hasAuthCookie = false; boolean hasAuthCookie = false;
for (Cookie cookie : cookies) { for (Cookie cookie : cookies) {
@ -255,7 +270,7 @@ public class GTaskClient {
Log.w(TAG, "it seems that there is no auth cookie"); Log.w(TAG, "it seems that there is no auth cookie");
} }
// get the client version // 解析响应内容,获取客户端版本信息
String resString = getResponseContent(response.getEntity()); String resString = getResponseContent(response.getEntity());
String jsBegin = "_setup("; String jsBegin = "_setup(";
String jsEnd = ")}</script>"; String jsEnd = ")}</script>";
@ -265,25 +280,25 @@ public class GTaskClient {
if (begin != -1 && end != -1 && begin < end) { if (begin != -1 && end != -1 && begin < end) {
jsString = resString.substring(begin + jsBegin.length(), end); jsString = resString.substring(begin + jsBegin.length(), end);
} }
JSONObject js = new JSONObject(jsString); JSONObject js = new JSONObject(jsString);// 解析JSON字符串
mClientVersion = js.getLong("v"); mClientVersion = js.getLong("v");// 获取客户端版本
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());// 如果解析JSON时出错则记录错误日志并返回false
e.printStackTrace(); e.printStackTrace();
return false; return false;
} catch (Exception e) { } catch (Exception e) { // 捕获所有异常并记录错误日志返回false
// simply catch all exceptions // simply catch all exceptions
Log.e(TAG, "httpget gtask_url failed"); Log.e(TAG, "httpget gtask_url failed");
return false; return false;
} }
return true; return true;// 登录成功返回true
} }
// 获取一个唯一的动作ID的函数
private int getActionId() { private int getActionId() {
return mActionId++; return mActionId++;
} }
// 创建一个HttpPost请求的函数
private HttpPost createHttpPost() { private HttpPost createHttpPost() {
HttpPost httpPost = new HttpPost(mPostUrl); HttpPost httpPost = new HttpPost(mPostUrl);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
@ -292,89 +307,112 @@ public class GTaskClient {
} }
private String getResponseContent(HttpEntity entity) throws IOException { private String getResponseContent(HttpEntity entity) throws IOException {
// 初始化内容编码变量
// 获取内容编码,如果存在的话
String contentEncoding = null; String contentEncoding = null;
if (entity.getContentEncoding() != null) { if (entity.getContentEncoding() != null) {
contentEncoding = entity.getContentEncoding().getValue(); contentEncoding = entity.getContentEncoding().getValue();
// 打印内容编码
Log.d(TAG, "encoding: " + contentEncoding); Log.d(TAG, "encoding: " + contentEncoding);
} }
// 获取输入流
InputStream input = entity.getContent(); InputStream input = entity.getContent();
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { // 根据内容编码进行解压缩
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { // 如果是gzip编码使用GZIPInputStream解压缩
input = new GZIPInputStream(entity.getContent()); input = new GZIPInputStream(entity.getContent());
} else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) { } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) {// 如果是deflate编码使用InflaterInputStream解压缩
Inflater inflater = new Inflater(true); Inflater inflater = new Inflater(true);
input = new InflaterInputStream(entity.getContent(), inflater); input = new InflaterInputStream(entity.getContent(), inflater);
} }
// 读取输入流并转换为字符串
try { try {
// 创建InputStreamReader指定UTF-8编码
InputStreamReader isr = new InputStreamReader(input); InputStreamReader isr = new InputStreamReader(input);
// 创建BufferedReader以高效读取文本
BufferedReader br = new BufferedReader(isr); BufferedReader br = new BufferedReader(isr);
// 创建StringBuilder以构建响应内容字符串·
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
while (true) { while (true) {
String buff = br.readLine(); String buff = br.readLine();
if (buff == null) { if (buff == null) {
return sb.toString(); return sb.toString();
} } // 将读取的行追加到StringBuilder
sb = sb.append(buff); sb = sb.append(buff);
} }
} finally { } finally { // 确保输入流在完成后被关闭
input.close(); input.close();
} }
} }
private JSONObject postRequest(JSONObject js) throws NetworkFailureException { private JSONObject postRequest(JSONObject js) throws NetworkFailureException { // 检查用户是否已登录,如果未登录,则抛出异常
if (!mLoggedin) { if (!mLoggedin) {
Log.e(TAG, "please login first"); Log.e(TAG, "please login first");
throw new ActionFailureException("not logged in"); throw new ActionFailureException("not logged in");
} }
// 创建HTTP POST请求对象
HttpPost httpPost = createHttpPost(); HttpPost httpPost = createHttpPost();
try { try { // 创建参数列表,用于存储请求参数
LinkedList<BasicNameValuePair> list = new LinkedList<BasicNameValuePair>(); LinkedList<BasicNameValuePair> list = new LinkedList<BasicNameValuePair>();
// 将JSON对象转换为字符串并作为参数添加到列表
list.add(new BasicNameValuePair("r", js.toString())); list.add(new BasicNameValuePair("r", js.toString()));
// 创建UrlEncodedFormEntity对象用于封装请求参数
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
// 设置请求的实体内容
httpPost.setEntity(entity); httpPost.setEntity(entity);
// execute the post // 执行HTTP POST请求获取响应
HttpResponse response = mHttpClient.execute(httpPost); HttpResponse response = mHttpClient.execute(httpPost);
// 获取响应内容,并将其转换为字符串
String jsString = getResponseContent(response.getEntity()); String jsString = getResponseContent(response.getEntity());
// 将响应字符串转换为JSON对象
return new JSONObject(jsString); return new JSONObject(jsString);
} catch (ClientProtocolException e) { } catch (ClientProtocolException e) {
// 处理HTTP协议异常
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace();
throw new NetworkFailureException("postRequest failed"); throw new NetworkFailureException("postRequest failed");
} catch (IOException e) { } catch (IOException e) {
// 处理I/O异常
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace();
throw new NetworkFailureException("postRequest failed"); throw new NetworkFailureException("postRequest failed");
} catch (JSONException e) { } catch (JSONException e) {
// 处理JSON解析异常
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace();
throw new ActionFailureException("unable to convert response content to jsonobject"); throw new ActionFailureException("unable to convert response content to jsonobject");
} catch (Exception e) { } catch (Exception e) {
// 处理其他异常
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace();
throw new ActionFailureException("error occurs when posting request"); throw new ActionFailureException("error occurs when posting request");
} }
} }
// 创建任务的方法
public void createTask(Task task) throws NetworkFailureException { public void createTask(Task task) throws NetworkFailureException {
// 提交之前的更新
commitUpdate(); commitUpdate();
try { try {
// 创建用于POST请求的JSON对象
JSONObject jsPost = new JSONObject(); JSONObject jsPost = new JSONObject();
// 创建动作列表
JSONArray actionList = new JSONArray(); JSONArray actionList = new JSONArray();
// action_list
// 获取任务的创建动作,并添加到动作列表
actionList.put(task.getCreateAction(getActionId())); actionList.put(task.getCreateAction(getActionId()));
// 将动作列表添加到POST请求的JSON对象
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version // 设置客户端版本信息
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
// post // 发送POST请求并获取响应
JSONObject jsResponse = postRequest(jsPost); JSONObject jsResponse = postRequest(jsPost);
// 从响应中获取结果并设置任务的GID
JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( JSONObject jsResult = (JSONObject) jsResponse.getJSONArray(
GTaskStringUtils.GTASK_JSON_RESULTS).get(0); GTaskStringUtils.GTASK_JSON_RESULTS).get(0);
task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID));
@ -387,10 +425,10 @@ public class GTaskClient {
} }
public void createTaskList(TaskList tasklist) throws NetworkFailureException { public void createTaskList(TaskList tasklist) throws NetworkFailureException {
commitUpdate(); commitUpdate(); // 提交之前的更新
try { try {
JSONObject jsPost = new JSONObject(); JSONObject jsPost = new JSONObject(); // 创建用于POST请求的JSON对象
JSONArray actionList = new JSONArray(); JSONArray actionList = new JSONArray(); // 创建动作列表
// action_list // action_list
actionList.put(tasklist.getCreateAction(getActionId())); actionList.put(tasklist.getCreateAction(getActionId()));
@ -413,19 +451,21 @@ public class GTaskClient {
} }
public void commitUpdate() throws NetworkFailureException { public void commitUpdate() throws NetworkFailureException {
// 检查是否有更新数组
if (mUpdateArray != null) { if (mUpdateArray != null) {
try { try { // 创建用于POST请求的JSON对象
JSONObject jsPost = new JSONObject(); JSONObject jsPost = new JSONObject();
// action_list // 将更新数组添加到POST请求的JSON对象
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray);
// 设置客户端版本信息
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
// 发送POST请求
postRequest(jsPost); postRequest(jsPost);
// 清空更新数组
mUpdateArray = null; mUpdateArray = null;
} catch (JSONException e) { } catch (JSONException e) {
// 处理JSON解析异常
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace();
throw new ActionFailureException("commit update: handing jsonobject failed"); throw new ActionFailureException("commit update: handing jsonobject failed");
@ -433,40 +473,41 @@ public class GTaskClient {
} }
} }
public void addUpdateNode(Node node) throws NetworkFailureException { public void addUpdateNode(Node node) throws NetworkFailureException { // 检查节点是否为空
if (node != null) { if (node != null) {
// too many update items may result in an error // 检查更新数组中的项目数量超过10个则先提交更新
// set max to 10 items
if (mUpdateArray != null && mUpdateArray.length() > 10) { if (mUpdateArray != null && mUpdateArray.length() > 10) {
commitUpdate(); commitUpdate();
} }
// 如果更新数组为空,则初始化
if (mUpdateArray == null) if (mUpdateArray == null)
mUpdateArray = new JSONArray(); mUpdateArray = new JSONArray(); // 将节点的更新动作添加到更新数组
mUpdateArray.put(node.getUpdateAction(getActionId())); mUpdateArray.put(node.getUpdateAction(getActionId()));
} }
} }
public void moveTask(Task task, TaskList preParent, TaskList curParent) public void moveTask(Task task, TaskList preParent, TaskList curParent)
throws NetworkFailureException { throws NetworkFailureException {
commitUpdate(); commitUpdate(); // 提交之前的更新
try { try {
JSONObject jsPost = new JSONObject(); JSONObject jsPost = new JSONObject();
JSONArray actionList = new JSONArray(); // 创建动作列表
JSONObject action = new JSONObject(); JSONArray actionList = new JSONArray();
// 创建动作对象
JSONObject action = new JSONObject();
// action_list // 设置动作类型为移动
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE); GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE);
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); // 设置动作ID
action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid()); action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid()); // 设置任务ID
if (preParent == curParent && task.getPriorSibling() != null) { if (preParent == curParent && task.getPriorSibling() != null) { // 如果在同一个任务列表内移动且不是第一个任务则设置前一个兄弟任务的ID
// put prioring_sibing_id only if moving within the tasklist and // put prioring_sibing_id only if moving within the tasklist and
// it is not the first one // it is not the first one
action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling()); action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling());
} } // 设置源任务列表的GID
action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); // 设置目标父任务的GID
action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); // 如果在不同任务列表间移动则设置目标任务列表的GID
if (preParent != curParent) { if (preParent != curParent) {
// put the dest_list only if moving between tasklists // put the dest_list only if moving between tasklists
action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid()); action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid());
@ -487,91 +528,99 @@ public class GTaskClient {
} }
public void deleteNode(Node node) throws NetworkFailureException { public void deleteNode(Node node) throws NetworkFailureException {
commitUpdate(); commitUpdate();// 先提交之前的所有更新
try { try {
JSONObject jsPost = new JSONObject(); JSONObject jsPost = new JSONObject(); // 创建用于POST请求的JSON对象
JSONArray actionList = new JSONArray(); JSONArray actionList = new JSONArray(); // 创建动作列表的JSONArray
// action_list // action_list
// 将节点标记为已删除,并获取更新动作,添加到动作列表中
node.setDeleted(true); node.setDeleted(true);
actionList.put(node.getUpdateAction(getActionId())); actionList.put(node.getUpdateAction(getActionId())); // 将动作列表添加到POST请求的JSON对象中
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// 添加客户端版本信息到POST请求的JSON对象中
// client_version // client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
// 发送POST请求
postRequest(jsPost); postRequest(jsPost);
mUpdateArray = null; mUpdateArray = null; // 清空更新数组
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); // 如果处理JSON时发生异常记录错误日志
e.printStackTrace(); e.printStackTrace(); // 打印异常堆栈信息
throw new ActionFailureException("delete node: handing jsonobject failed"); throw new ActionFailureException("delete node: handing jsonobject failed"); // 抛出动作失败异常
} }
} }
public JSONArray getTaskLists() throws NetworkFailureException { public JSONArray getTaskLists() throws NetworkFailureException { // 检查是否已登录
if (!mLoggedin) { if (!mLoggedin) {
Log.e(TAG, "please login first"); Log.e(TAG, "please login first"); // 如果未登录,记录错误日志
throw new ActionFailureException("not logged in"); throw new ActionFailureException("not logged in"); // 抛出动作失败异常
} }
try { try { // 创建HTTP GET请求
HttpGet httpGet = new HttpGet(mGetUrl); HttpGet httpGet = new HttpGet(mGetUrl);
HttpResponse response = null; HttpResponse response = null; // 执行HTTP GET请求获取响应
response = mHttpClient.execute(httpGet); response = mHttpClient.execute(httpGet);
// 获取响应内容
// get the task list // get the task list
String resString = getResponseContent(response.getEntity()); String resString = getResponseContent(response.getEntity());
// 定义JSON字符串的开始和结束标记
String jsBegin = "_setup("; String jsBegin = "_setup(";
String jsEnd = ")}</script>"; String jsEnd = ")}</script>";
// 查找JSON字符串的开始和结束位置
int begin = resString.indexOf(jsBegin); int begin = resString.indexOf(jsBegin);
int end = resString.lastIndexOf(jsEnd); int end = resString.lastIndexOf(jsEnd);
String jsString = null; String jsString = null; // 提取JSON字符串
if (begin != -1 && end != -1 && begin < end) { if (begin != -1 && end != -1 && begin < end) {
jsString = resString.substring(begin + jsBegin.length(), end); jsString = resString.substring(begin + jsBegin.length(), end);
} } // 将提取的JSON字符串转换为JSONObject.
JSONObject js = new JSONObject(jsString); JSONObject js = new JSONObject(jsString);
// 从JSONObject中获取任务列表的JSONArray
return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS); return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS);
} catch (ClientProtocolException e) { } catch (ClientProtocolException e) { // 如果HTTP协议错误记录错误日志
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace();
throw new NetworkFailureException("gettasklists: httpget failed"); throw new NetworkFailureException("gettasklists: httpget failed");
} catch (IOException e) { } catch (IOException e) {
Log.e(TAG, e.toString()); Log.e(TAG, e.toString());
e.printStackTrace(); e.printStackTrace(); // 打印异常堆栈信息
throw new NetworkFailureException("gettasklists: httpget failed"); throw new NetworkFailureException("gettasklists: httpget failed"); // 抛出网络失败异常
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); // 如果I/O错误记录错误日志
e.printStackTrace(); e.printStackTrace(); // 打印异常堆栈信息
throw new ActionFailureException("get task lists: handing jasonobject failed"); throw new ActionFailureException("get task lists: handing jasonobject failed"); // 抛出网络失败异常
} }
} }
public JSONArray getTaskList(String listGid) throws NetworkFailureException { public JSONArray getTaskList(String listGid) throws NetworkFailureException {
commitUpdate(); commitUpdate(); // 先提交之前的所有更新
try { try {
JSONObject jsPost = new JSONObject(); // 创建用于POST请求的JSON对象
JSONArray actionList = new JSONArray(); JSONObject jsPost = new JSONObject();
JSONObject action = new JSONObject(); // 创建动作列表的JSONArray
JSONArray actionList = new JSONArray();
// action_list // 创建动作的JSONObject
JSONObject action = new JSONObject();
// action_list // 设置动作类型为获取所有任务
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL); GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL); // 设置动作ID
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); // 设置任务列表ID
action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid); action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid); // 设置是否获取已删除任务,此处为否
action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false); action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false); // 将动作添加到动作列表中
actionList.put(action); actionList.put(action); // 将动作列表添加到POST请求的JSON对象中
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version // 添加客户端版本信息
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
// 发送POST请求并获取响应
JSONObject jsResponse = postRequest(jsPost); JSONObject jsResponse = postRequest(jsPost); // 从响应中获取任务数组
return jsResponse.getJSONArray(GTaskStringUtils.GTASK_JSON_TASKS); return jsResponse.getJSONArray(GTaskStringUtils.GTASK_JSON_TASKS);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, e.toString()); Log.e(TAG, e.toString()); // 记录JSON异常
e.printStackTrace(); e.printStackTrace(); // 打印异常堆栈信息
throw new ActionFailureException("get task list: handing jsonobject failed"); throw new ActionFailureException("get task list: handing jsonobject failed"); // 抛出操作失败异常
} }
} }

@ -42,17 +42,31 @@ public class GTaskSyncService extends Service {
private static String mSyncProgress = ""; private static String mSyncProgress = "";
public class GTaskSyncService extends Service {
// 定义广播动作和 extras 的键
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 String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.sync_broadcast";
public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "is_syncing";
public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg";
// 同步任务和进度信息
private static GTaskASyncTask mSyncTask = null;
private static String mSyncProgress = "";
private void startSync() { private void startSync() {
if (mSyncTask == null) { if (mSyncTask == null) {
mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() { mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() {
public void onComplete() { public void onComplete() {
mSyncTask = null; mSyncTask = null;
sendBroadcast(""); sendBroadcast(""); // 发送同步完成广播
stopSelf(); stopSelf(); // 停止服务
} }
}); });
sendBroadcast(""); sendBroadcast(""); // 发送同步开始广播
mSyncTask.execute(); mSyncTask.execute(); // 执行同步任务
} }
} }
@ -64,7 +78,7 @@ public class GTaskSyncService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
mSyncTask = null; mSyncTask = null; // 初始化同步任务为空
} }
@Override @Override
@ -73,15 +87,15 @@ public class GTaskSyncService extends Service {
if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) { if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) {
switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) { switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) {
case ACTION_START_SYNC: case ACTION_START_SYNC:
startSync(); startSync(); // 处理开始同步动作
break; break;
case ACTION_CANCEL_SYNC: case ACTION_CANCEL_SYNC:
cancelSync(); cancelSync(); // 处理取消同步动作
break; break;
default: default:
break; break;
} }
return START_STICKY; return START_STICKY; // 确保服务被持续运行
} }
return super.onStartCommand(intent, flags, startId); return super.onStartCommand(intent, flags, startId);
} }
@ -89,40 +103,62 @@ public class GTaskSyncService extends Service {
@Override @Override
public void onLowMemory() { public void onLowMemory() {
if (mSyncTask != null) { if (mSyncTask != null) {
mSyncTask.cancelSync(); mSyncTask.cancelSync(); // 低内存时取消同步任务
} }
} }
@Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return null; // 不支持绑定
} }
/**
* 广
* @param msg
*/
public void sendBroadcast(String msg) { public void sendBroadcast(String msg) {
mSyncProgress = msg; mSyncProgress = msg;
Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME); Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME);
intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null);
intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg);
sendBroadcast(intent); sendBroadcast(intent); // 发送广播
} }
/**
* Activity
* @param activity Activity
*/
public static void startSync(Activity activity) { public static void startSync(Activity activity) {
GTaskManager.getInstance().setActivityContext(activity); GTaskManager.getInstance().setActivityContext(activity);
Intent intent = new Intent(activity, GTaskSyncService.class); Intent intent = new Intent(activity, GTaskSyncService.class);
intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC); intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC);
activity.startService(intent); activity.startService(intent); // 启动服务
} }
/**
* Context
* @param context Context
*/
public static void cancelSync(Context context) { public static void cancelSync(Context context) {
Intent intent = new Intent(context, GTaskSyncService.class); Intent intent = new Intent(context, GTaskSyncService.class);
intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC); intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC);
context.startService(intent); context.startService(intent); // 启动服务以发送取消动作
} }
/**
*
* @return true false
*/
public static boolean isSyncing() { public static boolean isSyncing() {
return mSyncTask != null; return mSyncTask != null;
} }
/**
*
* @return
*/
public static String getProgressString() { public static String getProgressString() {
return mSyncProgress; return mSyncProgress;
} }
} }

Loading…
Cancel
Save