Compare commits

...

10 Commits

Binary file not shown.

Binary file not shown.

@ -0,0 +1,43 @@
`ActionFailureException` Java `RuntimeException`
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.exception;
// ActionFailureException类是一个未受检查的异常用于表示操作失败的情况。
public class ActionFailureException extends RuntimeException {
// 序列化ID用于Java对象的序列化机制。
private static final long serialVersionUID = 4425249765923293627L;
// 无参构造函数初始化ActionFailureException异常。
public ActionFailureException() {
super();
}
// 构造函数,接受一个字符串参数,用于提供异常的详细信息。
public ActionFailureException(String paramString) {
super(paramString);
}
// 构造函数接受一个字符串参数和一个Throwable对象用于提供异常的详细信息和原因。
public ActionFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}
}
```

@ -0,0 +1,70 @@
import android.content.Context;
import android.database.Cursor;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import java.util.HashMap;
public class Contact {
// 创建一个静态的HashMap用于缓存联系人信息避免重复查询
private static HashMap<String, String> sContactCache;
// 定义一个常量TAG用于日志输出
private static final String TAG = "Contact";
// 定义一个查询条件字符串,用于在联系人数据库中查找匹配的电话号码
private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER
+ ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
+ " AND " + Data.RAW_CONTACT_ID + " IN "
+ "(SELECT raw_contact_id "
+ " FROM phone_lookup"
+ " WHERE min_match = '+')";
// 定义一个静态方法getContact接收一个Context对象和一个电话号码字符串返回该电话号码对应的联系人姓名
public static String getContact(Context context, String phoneNumber) {
// 如果缓存为空,则初始化缓存
if(sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
// 如果缓存中已经有该电话号码对应的联系人姓名,则直接返回缓存中的值
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
// 替换查询条件中的占位符,使其能够匹配给定的电话号码
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
// 使用ContentResolver查询联系人数据库获取匹配给定电话号码的联系人姓名
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String [] { Phone.DISPLAY_NAME },
selection,
new String[] { phoneNumber },
null);
// 如果查询结果不为空,且至少有一条记录,则处理查询结果
if (cursor != null && cursor.moveToFirst()) {
try {
// 从查询结果中获取联系人姓名
String name = cursor.getString(0);
// 将电话号码和联系人姓名存入缓存
sContactCache.put(phoneNumber, name);
// 返回联系人姓名
return name;
} catch (IndexOutOfBoundsException e) {
// 如果发生异常记录日志并返回null
Log.e(TAG, " Cursor get string error " + e.toString());
return null;
} finally {
// 关闭Cursor
cursor.close();
}
} else {
// 如果没有找到匹配的联系人记录日志并返回null
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}
}
}

@ -0,0 +1,135 @@
AndroidJava`GTaskASyncTask``AsyncTask`Google
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.remote;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import net.micode.notes.R;
import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;
// GTaskASyncTask类继承自AsyncTask用于执行异步的Google任务同步操作
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
// 定义同步通知的ID
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
// 定义回调接口,用于在同步操作完成后通知
public interface OnCompleteListener {
void onComplete();
}
// 成员变量
private Context mContext; // 上下文对象
private NotificationManager mNotifiManager; // 通知管理器
private GTaskManager mTaskManager; // 任务管理器
private OnCompleteListener mOnCompleteListener; // 完成监听器
// 构造函数初始化GTaskASyncTask对象
public GTaskASyncTask(Context context, OnCompleteListener listener) {
mContext = context;
mOnCompleteListener = listener;
mNotifiManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
mTaskManager = GTaskManager.getInstance();
}
// 取消同步操作的方法
public void cancelSync() {
mTaskManager.cancelSync();
}
// 发布进度消息的方法
public void publishProgess(String message) {
publishProgress(new String[] {
message
});
}
// 显示通知的方法
private void showNotification(int tickerId, String content) {
// 创建通知对象
Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS;
notification.flags = Notification.FLAG_AUTO_CANCEL;
// 创建PendingIntent
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), 0);
} else {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), 0);
}
// 设置通知信息
notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
pendingIntent);
// 发送通知
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
// 后台线程执行的方法,执行同步操作
@Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext)));
return mTaskManager.sync(mContext, this);
}
// 更新进度的方法,显示进度通知
@Override
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);
if (mContext instanceof GTaskSyncService) {
((GTaskSyncService) mContext).sendBroadcast(progress[0]);
}
}
// 执行完毕后的方法,根据结果显示不同的通知
@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));
} else if (result == GTaskManager.STATE_INTERNAL_ERROR) {
showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal));
} else if (result == GTaskManager.STATE_SYNC_CANCELLED) {
showNotification(R.string.ticker_cancel, mContext
.getString(R.string.error_sync_cancelled));
}
if (mOnCompleteListener != null) {
new Thread(new Runnable() {
public void run() {
mOnCompleteListener.onComplete();
}
}).start();
}
}
}
```

@ -0,0 +1,204 @@
AndroidJava`GTaskClient`Google Tasks
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.remote;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.gtask.data.Node;
import net.micode.notes.gtask.data.Task;
import net.micode.notes.gtask.data.TaskList;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.gtask.exception.NetworkFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import net.micode.notes.ui.NotesPreferenceActivity;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
// GTaskClient类用于与Google Tasks服务进行交互
public class GTaskClient {
// 类的标签,用于日志记录
private static final String TAG = GTaskClient.class.getSimpleName();
// Google Tasks的URL
private static final String GTASK_URL = "https://mail.google.com/tasks/&#34;;
private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig&#34;;
private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig&#34;;
// GTaskClient的单例
private static GTaskClient mInstance = null;
// 成员变量
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;
mPostUrl = GTASK_POST_URL;
mClientVersion = -1;
mLoggedin = false;
mLastLoginTime = 0;
mActionId = 1;
mAccount = null;
mUpdateArray = null;
}
// 获取GTaskClient单例的方法
public static synchronized GTaskClient getInstance() {
if (mInstance == null) {
mInstance = new GTaskClient();
}
return mInstance;
}
// 登录方法
public boolean login(Activity activity) {
// ... 登录逻辑
}
// 登录Google账户的方法
private String loginGoogleAccount(Activity activity, boolean invalidateToken) {
// ... 登录Google账户逻辑
}
// 尝试登录Google Tasks的方法
private boolean tryToLoginGtask(Activity activity, String authToken) {
// ... 尝试登录Google Tasks逻辑
}
// 登录Google Tasks的方法
private boolean loginGtask(String authToken) {
// ... 登录Google Tasks逻辑
}
// 获取操作ID的方法
private int getActionId() {
return mActionId++;
}
// 创建HttpPost对象的方法
private HttpPost createHttpPost() {
// ... 创建HttpPost对象逻辑
}
// 获取响应内容的方法
private String getResponseContent(HttpEntity entity) throws IOException {
// ... 获取响应内容逻辑
}
// 发送POST请求的方法
private JSONObject postRequest(JSONObject js) throws NetworkFailureException {
// ... 发送POST请求逻辑
}
// 创建任务的方法
public void createTask(Task task) throws NetworkFailureException {
// ... 创建任务逻辑
}
// 创建任务列表的方法
public void createTaskList(TaskList tasklist) throws NetworkFailureException {
// ... 创建任务列表逻辑
}
// 提交更新的方法
public void commitUpdate() throws NetworkFailureException {
// ... 提交更新逻辑
}
// 添加更新节点的方法
public void addUpdateNode(Node node) throws NetworkFailureException {
// ... 添加更新节点逻辑
}
// 移动任务的方法
public void moveTask(Task task, TaskList preParent, TaskList curParent)
throws NetworkFailureException {
// ... 移动任务逻辑
}
// 删除节点的方法
public void deleteNode(Node node) throws NetworkFailureException {
// ... 删除节点逻辑
}
// 获取任务列表的方法
public JSONArray getTaskLists() throws NetworkFailureException {
// ... 获取任务列表逻辑
}
// 获取任务列表中的任务的方法
public JSONArray getTaskList(String listGid) throws NetworkFailureException {
// ... 获取任务列表中的任务逻辑
}
// 获取同步账户的方法
public Account getSyncAccount() {
return mAccount;
}
// 重置更新数组的方法
public void resetUpdateArray() {
mUpdateArray = null;
}
}
```
`GTaskClient`Google Tasks使HTTPJSON

@ -0,0 +1,176 @@
AndroidJava`GTaskManager`Google Tasks
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.remote;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.data.MetaData;
import net.micode.notes.gtask.data.Node;
import net.micode.notes.gtask.data.SqlNote;
import net.micode.notes.gtask.data.Task;
import net.micode.notes.gtask.data.TaskList;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.gtask.exception.NetworkFailureException;
import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
// GTaskManager类用于管理与Google Tasks的同步操作
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;
// GTaskManager的单例
private static GTaskManager mInstance = null;
// 成员变量
private Activity mActivity; // 活动
private Context mContext; // 上下文
private ContentResolver mContentResolver; // 内容解析器
private boolean mSyncing; // 是否正在同步
private boolean mCancelled; // 是否已取消同步
private HashMap<String, TaskList> mGTaskListHashMap; // 任务列表哈希映射
private HashMap<String, Node> mGTaskHashMap; // 任务哈希映射
private HashMap<String, MetaData> mMetaHashMap; // 元数据哈希映射
private TaskList mMetaList; // 元数据列表
private HashSet<Long> mLocalDeleteIdMap; // 本地删除ID集合
private HashMap<String, Long> mGidToNid; // GID到NID的映射
private HashMap<Long, String> mNidToGid; // NID到GID的映射
// 私有构造函数,确保单例
private GTaskManager() {
mSyncing = false;
mCancelled = false;
mGTaskListHashMap = new HashMap<String, TaskList>();
mGTaskHashMap = new HashMap<String, Node>();
mMetaHashMap = new HashMap<String, MetaData>();
mMetaList = null;
mLocalDeleteIdMap = new HashSet<Long>();
mGidToNid = new HashMap<String, Long>();
mNidToGid = new HashMap<Long, String>();
}
// 获取GTaskManager单例的方法
public static synchronized GTaskManager getInstance() {
if (mInstance == null) {
mInstance = new GTaskManager();
}
return mInstance;
}
// 设置活动上下文的方法
public synchronized void setActivityContext(Activity activity) {
mActivity = activity;
}
// 同步方法
public int sync(Context context, GTaskASyncTask asyncTask) {
// ... 同步逻辑
return STATE_SUCCESS;
}
// 初始化Google任务列表的方法
private void initGTaskList() throws NetworkFailureException {
// ... 初始化Google任务列表逻辑
}
// 同步内容的方法
private void syncContent() throws NetworkFailureException {
// ... 同步内容逻辑
}
// 同步文件夹的方法
private void syncFolder() throws NetworkFailureException {
// ... 同步文件夹逻辑
}
// 执行内容同步的方法
private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException {
// ... 执行内容同步逻辑
}
// 本地添加节点的方法
private void addLocalNode(Node node) throws NetworkFailureException {
// ... 本地添加节点逻辑
}
// 本地更新节点的方法
private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException {
// ... 本地更新节点逻辑
}
// 远程添加节点的方法
private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException {
// ... 远程添加节点逻辑
}
// 远程更新节点的方法
private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException {
// ... 远程更新节点逻辑
}
// 更新远程元数据的方法
private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException {
// ... 更新远程元数据逻辑
}
// 刷新本地同步ID的方法
private void refreshLocalSyncId() throws NetworkFailureException {
// ... 刷新本地同步ID逻辑
}
// 获取同步账户的方法
public String getSyncAccount() {
return GTaskClient.getInstance().getSyncAccount().name;
}
// 取消同步的方法
public void cancelSync() {
mCancelled = true;
}
}
```
`GTaskManager`Google Tasks使`GTaskClient`Google Tasks

@ -0,0 +1,163 @@
AndroidJava`GTaskSyncService``Service`Google Tasks
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.remote;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
// GTaskSyncService类继承自Service类用于执行Google Tasks的同步操作
public class GTaskSyncService extends Service {
// 定义同步操作的Action字符串常量
public final static String ACTION_STRING_NAME = "sync_action_type";
// 定义开始同步的Action常量
public final static int ACTION_START_SYNC = 0;
// 定义取消同步的Action常量
public final static int ACTION_CANCEL_SYNC = 1;
// 定义无效的Action常量
public final static int ACTION_INVALID = 2;
// 定义服务广播的名称
public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service";
// 定义服务广播是否正在同步的Key
public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing";
// 定义服务广播同步进度消息的Key
public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg";
// GTaskASyncTask的单例
private static GTaskASyncTask mSyncTask = null;
// 同步进度字符串
private static String mSyncProgress = "";
// 开始同步的方法
private void startSync() {
// 如果mSyncTask为空则创建新的GTaskASyncTask实例并执行
if (mSyncTask == null) {
mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() {
public void onComplete() {
// 同步完成后将mSyncTask设置为null并停止服务
mSyncTask = null;
sendBroadcast("");
stopSelf();
}
});
sendBroadcast("");
mSyncTask.execute();
}
}
// 取消同步的方法
private void cancelSync() {
// 如果mSyncTask不为空则调用其cancelSync方法
if (mSyncTask != null) {
mSyncTask.cancelSync();
}
}
// onCreate方法在服务创建时被调用
@Override
public void onCreate() {
mSyncTask = null;
}
// onStartCommand方法在服务启动时被调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 获取Intent的extras并根据Action执行相应的同步操作
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();
break;
case ACTION_CANCEL_SYNC:
cancelSync();
break;
default:
break;
}
return START_STICKY;
}
return super.onStartCommand(intent, flags, startId);
}
// onLowMemory方法在系统内存不足时被调用
@Override
public void onLowMemory() {
// 如果mSyncTask不为空则调用其cancelSync方法
if (mSyncTask != null) {
mSyncTask.cancelSync();
}
}
// onBind方法服务绑定时被调用
public IBinder onBind(Intent intent) {
return 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);
}
// 开始同步的静态方法
public static void startSync(Activity activity) {
// 设置GTaskManager的上下文并启动同步服务
GTaskManager.getInstance().setActivityContext(activity);
Intent intent = new Intent(activity, GTaskSyncService.class);
intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.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);
}
// 判断是否正在同步的静态方法
public static boolean isSyncing() {
return mSyncTask != null;
}
// 获取同步进度字符串的静态方法
public static String getProgressString() {
return mSyncProgress;
}
}
```
`GTaskSyncService`Google Tasks广`startSync``cancelSync``isSyncing``getProgressString`

@ -0,0 +1,85 @@
// 定义包名和导入所需的类
package net.micode.notes.gtask.data;
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
// MetaData类继承自Task类用于处理与Google Tasks相关的元数据
public class MetaData extends Task {
// 类的标签,用于日志记录
private final static String TAG = MetaData.class.getSimpleName();
// 用于存储与Google Tasks相关的全局ID
private String mRelatedGid = null;
// 设置元数据信息
public void setMeta(String gid, JSONObject metaInfo) {
try {
// 将全局ID添加到元数据信息中
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
// 如果发生异常,记录错误日志
Log.e(TAG, "failed to put related gid");
}
// 将元数据信息设置为笔记内容
setNotes(metaInfo.toString());
// 设置元数据的名称
setName(GTaskStringUtils.META_NOTE_NAME);
}
// 获取与Google Tasks相关的全局ID
public String getRelatedGid() {
return mRelatedGid;
}
// 重写isWorthSaving方法判断是否有值得保存的笔记内容
@Override
public boolean isWorthSaving() {
return getNotes() != null;
}
// 根据远程JSON对象设置内容
@Override
public void setContentByRemoteJSON(JSONObject js) {
// 首先调用父类的同名方法
super.setContentByRemoteJSON(js);
// 如果笔记内容不为空尝试解析JSON对象
if (getNotes() != null) {
try {
JSONObject metaInfo = new JSONObject(getNotes().trim());
// 从JSON对象中获取全局ID
mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
} catch (JSONException e) {
// 如果解析失败记录警告日志并将全局ID设置为null
Log.w(TAG, "failed to get related gid");
mRelatedGid = null;
}
}
}
// 根据本地JSON对象设置内容这个方法不应该被调用
@Override
public void setContentByLocalJSON(JSONObject js) {
// 抛出异常,表示这个方法不应该被调用
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
// 从内容中获取本地JSON对象这个方法不应该被调用
@Override
public JSONObject getLocalJSONFromContent() {
// 抛出异常,表示这个方法不应该被调用
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
}
// 获取同步操作,这个方法不应该被调用
@Override
public int getSyncAction(Cursor c) {
// 抛出异常,表示这个方法不应该被调用
throw new IllegalAccessError("MetaData:getSyncAction should not be called");
}
}

@ -0,0 +1,43 @@
`NetworkFailureException` Java `Exception`
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.exception;
// NetworkFailureException类是一个受检查的异常用于表示网络相关的失败情况。
public class NetworkFailureException extends Exception {
// 序列化ID用于Java对象的序列化机制。
private static final long serialVersionUID = 2107610287180234136L;
// 无参构造函数初始化NetworkFailureException异常。
public NetworkFailureException() {
super();
}
// 构造函数,接受一个字符串参数,用于提供异常的详细信息。
public NetworkFailureException(String paramString) {
super(paramString);
}
// 构造函数接受一个字符串参数和一个Throwable对象用于提供异常的详细信息和原因。
public NetworkFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}
}
```

@ -0,0 +1,100 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.database.Cursor;
import org.json.JSONObject;
// 抽象类Node用于表示与Google Tasks同步的数据节点
public abstract class Node {
// 定义同步操作的常量
public static final int SYNC_ACTION_NONE = 0;
public static final int SYNC_ACTION_ADD_REMOTE = 1;
public static final int SYNC_ACTION_ADD_LOCAL = 2;
public static final int SYNC_ACTION_DEL_REMOTE = 3;
public static final int SYNC_ACTION_DEL_LOCAL = 4;
public static final int SYNC_ACTION_UPDATE_REMOTE = 5;
public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
public static final int SYNC_ACTION_ERROR = 8;
// 成员变量
private String mGid; // Google Tasks的全局ID
private String mName; // 节点名称
private long mLastModified; // 最后修改时间
private boolean mDeleted; // 是否被删除
// 构造函数,初始化成员变量
public Node() {
mGid = null;
mName = "";
mLastModified = 0;
mDeleted = false;
}
// 获取创建操作的JSON对象
public abstract JSONObject getCreateAction(int actionId);
// 获取更新操作的JSON对象
public abstract JSONObject getUpdateAction(int actionId);
// 根据远程JSON对象设置内容
public abstract void setContentByRemoteJSON(JSONObject js);
// 根据本地JSON对象设置内容
public abstract void setContentByLocalJSON(JSONObject js);
// 从内容中获取本地JSON对象
public abstract JSONObject getLocalJSONFromContent();
// 获取同步操作
public abstract int getSyncAction(Cursor c);
// 设置和获取方法
public void setGid(String gid) {
this.mGid = gid;
}
public void setName(String name) {
this.mName = name;
}
public void setLastModified(long lastModified) {
this.mLastModified = lastModified;
}
public void setDeleted(boolean deleted) {
this.mDeleted = deleted;
}
public String getGid() {
return this.mGid;
}
public String getName() {
return this.mName;
}
public long getLastModified() {
return this.mLastModified;
}
public boolean getDeleted() {
return this.mDeleted;
}
}

@ -0,0 +1,91 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.data;
import android.net.Uri;
public class Notes {
// 定义常量,包括权限、标签、类型等
public static final String AUTHORITY = "micode_notes";
public static final String TAG = "Notes";
public static final int TYPE_NOTE = 0;
public static final int TYPE_FOLDER = 1;
public static final int TYPE_SYSTEM = 2;
// 系统文件夹的ID
public static final int ID_ROOT_FOLDER = 0;
public static final int ID_TEMPARAY_FOLDER = -1;
public static final int ID_CALL_RECORD_FOLDER = -2;
public static final int ID_TRASH_FOLER = -3;
// Intent额外数据的键名
public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";
public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";
public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id";
public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type";
public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id";
public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date";
// Widget类型
public static final int TYPE_WIDGET_INVALIDE = -1;
public static final int TYPE_WIDGET_2X = 0;
public static final int TYPE_WIDGET_4X = 1;
// 数据常量类
public static class DataConstants {
public static final String NOTE = TextNote.CONTENT_ITEM_TYPE;
public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE;
}
// Uri查询所有笔记和文件夹
public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");
// Uri查询数据
public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");
// NoteColumns接口定义了笔记或文件夹的属性
public interface NoteColumns {
public static final String ID = "_id";
public static final String PARENT_ID = "parent_id";
public static final String CREATED_DATE = "created_date";
public static final String MODIFIED_DATE = "modified_date";
public static final String ALERTED_DATE = "_date";
public static final String SNIPPET = "snippet";
public static final String WIDGET_ID = "widget_id";
public static final String WIDGET_TYPE = "widget_type";
public static final String BG_COLOR_ID = "bg_color_id";
public static final String HAS_ATTACHMENT = "has_attachment";
public static final String NOTES_COUNT = "notes_count";
public static final String TYPE = "type";
public static final String SYNC_ID = "sync_id";
public static final String LOCAL_MODIFIED = "local_modified";
public static final String ORIGIN_PARENT_ID = "origin_parent_id";
public static final String GTASK_ID = "gtask_id";
public static final String VERSION = "version";
}
// DataColumns接口定义了笔记的数据属性
public interface DataColumns {
public static final String ID = "_id";
public static final String MIME_TYPE = "mime_type";
public static final String NOTE_ID = "note_id";
public static final String CREATED_DATE = "created_date";
public static final String MODIFIED_DATE = "modified_date";
public static final String CONTENT = "content";
public static final String DATA1 = "data1";
public static final String DATA2 = "data2";
}
}

@ -0,0 +1,116 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.data;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
public class NotesDatabaseHelper extends SQLiteOpenHelper {
// 数据库名称
private static final String DB_NAME = "note.db";
// 数据库版本号
private static final int DB_VERSION = 4;
// 表名常量
public interface TABLE {
String NOTE = "note";
String DATA = "data";
}
// 日志标签
private static final String TAG = "NotesDatabaseHelper";
// 单例实例
private static NotesDatabaseHelper mInstance;
// 创建笔记表的SQL语句
private static final String CREATE_NOTE_TABLE_SQL =
"CREATE TABLE " + TABLE.NOTE + "(" +
NoteColumns.ID + " INTEGER PRIMARY KEY," +
NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," +
NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," +
NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," +
NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" +
")";
// 创建数据表的SQL语句
private static final String CREATE_DATA_TABLE_SQL =
"CREATE TABLE " + TABLE.DATA + "(" +
DataColumns.ID + " INTEGER PRIMARY KEY," +
DataColumns.MIME_TYPE + " TEXT NOT NULL," +
DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA1 + " INTEGER," +
DataColumns.DATA2 + " INTEGER," +
DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" +
")";
// 创建索引的SQL语句用于提高查询效率
private static final String CREATE_DATA_NOTE_ID_INDEX_SQL =
"CREATE INDEX IF NOT EXISTS note_id_index ON " +
TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
// ...省略其他触发器的定义...
// 构造函数私有化,实现单例模式
private NotesDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
// 获取单例实例的方法
public static synchronized NotesDatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new NotesDatabaseHelper(context);
}
return mInstance;
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "onCreate");
db.execSQL(CREATE_NOTE_TABLE_SQL);
db.execSQL(CREATE_DATA_TABLE_SQL);
db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL);
// ...执行其他触发器的创建...
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "onUpgrade from version " + oldVersion + " to " + newVersion);
// ...根据需要处理数据库升级逻辑...
}
}

@ -0,0 +1,127 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.data;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.R;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE;
public class NotesProvider extends ContentProvider {
// 定义一个静态的UriMatcher对象用于匹配URI
private static final UriMatcher mMatcher;
// 创建一个NotesDatabaseHelper实例
private NotesDatabaseHelper mHelper;
// 定义一个常量TAG用于日志记录
private static final String TAG = "NotesProvider";
// 定义一些常量URI用于匹配不同的数据表或操作
private static final int URI_NOTE = 1;
private static final int URI_NOTE_ITEM = 2;
private static final int URI_DATA = 3;
private static final int URI_DATA_ITEM = 4;
private static final int URI_SEARCH = 5;
private static final int URI_SEARCH_SUGGEST = 6;
// 在静态代码块中初始化mMatcher添加匹配规则
static {
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM);
mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM);
mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH);
mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST);
mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST);
}
// 定义一个常量字符串,用于搜索结果的投影
private static final String NOTES_SEARCH_PROJECTION = ... //省略具体实现
// 定义一个常量字符串,用于搜索查询语句
private static final String NOTES_SNIPPET_SEARCH_QUERY = ... //省略具体实现
@Override
public boolean onCreate() {
// 创建NotesDatabaseHelper实例并返回true
mHelper = NotesDatabaseHelper.getInstance(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// 根据传入的URI进行匹配执行相应的数据库查询操作
Cursor c = null;
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
switch (mMatcher.match(uri)) {
// ...省略其他case的处理逻辑...
}
// 如果Cursor不为空设置通知URI并返回Cursor
if (c != null) {
c.setNotificationUri(getContext().getContentResolver(), uri);
}
return c;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// 根据传入的URI进行匹配执行相应的数据库插入操作
SQLiteDatabase db = mHelper.getWritableDatabase();
long dataId = 0, noteId = 0, insertedId = 0;
switch (mMatcher.match(uri)) {
// ...省略其他case的处理逻辑...
}
// 如果有对应的noteId或dataId通知相应的URI变化
// ...省略通知逻辑...
// 返回新插入数据的URI
return ContentUris.withAppendedId(uri, insertedId);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// 根据传入的URI进行匹配执行相应的数据库删除操作
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean deleteData = false;
switch (mMatcher.match(uri)) {
// ...省略其他case的处理逻辑...
}
// 返回删除的数据条数
return count;
}
// ...省略其他方法的实现...
}

@ -0,0 +1,119 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE;
import net.micode.notes.gtask.exception.ActionFailureException;
import org.json.JSONException;
import org.json.JSONObject;
// SqlData类用于管理数据库中的笔记数据
public class SqlData {
// 类的标签,用于日志记录
private static final String TAG = SqlData.class.getSimpleName();
// 无效的ID常量
private static final int INVALID_ID = -99999;
// 数据库查询的列
public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
// 数据库列的索引
public static final int DATA_ID_COLUMN = 0;
public static final int DATA_MIME_TYPE_COLUMN = 1;
public static final int DATA_CONTENT_COLUMN = 2;
public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
// 成员变量
private ContentResolver mContentResolver; // 内容解析器
private boolean mIsCreate; // 是否为创建状态
private long mDataId; // 数据ID
private String mDataMimeType; // 数据MIME类型
private String mDataContent; // 数据内容
private long mDataContentData1; // 数据内容DATA1
private String mDataContentData3; // 数据内容DATA3
private ContentValues mDiffDataValues; // 差异数据值
// 构造函数初始化SqlData对象
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
mDataContentData1 = 0;
mDataContentData3 = "";
mDiffDataValues = new ContentValues();
}
// 从Cursor构造SqlData对象
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
// 从Cursor加载数据
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
mDataContent = c.getString(DATA_CONTENT_COLUMN);
mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN);
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
// 设置内容
public void setContent(JSONObject js) throws JSONException {
// 根据JSON对象设置数据
// ...
}
// 获取内容
public JSONObject getContent() throws JSONException {
// 根据当前数据创建JSON对象
// ...
}
// 提交数据到数据库
public void commit(long noteId, boolean validateVersion, long version) {
// 根据创建状态和差异数据值,将数据插入或更新到数据库
// ...
}
// 获取数据ID
public long getId() {
return mDataId;
}
}

@ -0,0 +1,165 @@
AndroidJava`SqlNote`
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import net.micode.notes.tool.ResourceParser;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
// SqlNote类用于管理数据库中的笔记数据
public class SqlNote {
// 类的标签,用于日志记录
private static final String TAG = SqlNote.class.getSimpleName();
// 无效的ID常量
private static final int INVALID_ID = -99999;
// 数据库查询的列
public static final String[] PROJECTION_NOTE = new String[] {
// ... 省略其他列定义
};
// 数据库列的索引
public static final int ID_COLUMN = 0;
// ... 省略其他列索引定义
// 成员变量
private Context mContext; // 上下文对象
private ContentResolver mContentResolver; // 内容解析器
private boolean mIsCreate; // 是否为创建状态
private long mId; // 笔记ID
// ... 省略其他成员变量定义
private ArrayList<SqlData> mDataList; // 笔记关联的数据列表
// 构造函数初始化SqlNote对象
public SqlNote(Context context) {
// ... 初始化成员变量
}
// 从Cursor构造SqlNote对象
public SqlNote(Context context, Cursor c) {
// ... 初始化成员变量并从Cursor加载数据
}
// 从ID构造SqlNote对象
public SqlNote(Context context, long id) {
// ... 初始化成员变量并从ID加载数据
}
// 从Cursor加载数据
private void loadFromCursor(Cursor c) {
// ... 从Cursor对象加载笔记数据
}
// 从ID加载数据
private void loadFromCursor(long id) {
// ... 从ID加载笔记数据
}
// 加载笔记内容数据
private void loadDataContent() {
// ... 加载笔记关联的数据
}
// 设置笔记内容
public boolean setContent(JSONObject js) {
try {
// ... 从JSONObject设置笔记内容
} catch (JSONException e) {
// ... 异常处理
}
return true;
}
// 获取笔记内容
public JSONObject getContent() {
try {
// ... 从当前对象创建JSONObject
} catch (JSONException e) {
// ... 异常处理
}
return null;
}
// 设置父ID
public void setParentId(long id) {
// ... 设置父ID并更新差异值
}
// 设置GTask ID
public void setGtaskId(String gid) {
// ... 设置GTask ID并更新差异值
}
// 设置同步ID
public void setSyncId(long syncId) {
// ... 设置同步ID并更新差异值
}
// 重置本地修改标记
public void resetLocalModified() {
// ... 重置本地修改标记
}
// 获取笔记ID
public long getId() {
return mId;
}
// 获取父ID
public long getParentId() {
return mParentId;
}
// 获取笔记摘要
public String getSnippet() {
return mSnippet;
}
// 判断是否为笔记类型
public boolean isNoteType() {
return mType == Notes.TYPE_NOTE;
}
// 提交笔记数据
public void commit(boolean validateVersion) {
// ... 提交笔记数据到数据库
}
}
```

@ -0,0 +1,133 @@
AndroidJava`Task``Node`Google Tasks
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
// Task类继承自Node类用于表示一个任务
public class Task extends Node {
// 类的标签,用于日志记录
private static final String TAG = Task.class.getSimpleName();
// 成员变量
private boolean mCompleted; // 是否完成
private String mNotes; // 任务笔记
private JSONObject mMetaInfo; // 元数据信息
private Task mPriorSibling; // 前一个任务
private TaskList mParent; // 父任务列表
// 构造函数初始化Task对象
public Task() {
super();
mCompleted = false;
mNotes = null;
mPriorSibling = null;
mParent = null;
mMetaInfo = null;
}
// 获取创建任务的JSON对象
public JSONObject getCreateAction(int actionId) {
// ... 创建任务的JSON对象
}
// 获取更新任务的JSON对象
public JSONObject getUpdateAction(int actionId) {
// ... 更新任务的JSON对象
}
// 根据远程JSON对象设置任务内容
public void setContentByRemoteJSON(JSONObject js) {
// ... 从远程JSON对象设置任务内容
}
// 根据本地JSON对象设置任务内容
public void setContentByLocalJSON(JSONObject js) {
// ... 从本地JSON对象设置任务内容
}
// 从任务内容获取本地JSON对象
public JSONObject getLocalJSONFromContent() {
// ... 从任务内容获取本地JSON对象
}
// 设置元数据信息
public void setMetaInfo(MetaData metaData) {
// ... 设置元数据信息
}
// 获取同步操作
public int getSyncAction(Cursor c) {
// ... 根据数据库游标获取同步操作
}
// 判断任务是否值得保存
public boolean isWorthSaving() {
// ... 判断任务是否值得保存
}
// 设置和获取方法
public void setCompleted(boolean completed) {
this.mCompleted = completed;
}
public void setNotes(String notes) {
this.mNotes = notes;
}
public void setPriorSibling(Task priorSibling) {
this.mPriorSibling = priorSibling;
}
public void setParent(TaskList parent) {
this.mParent = parent;
}
public boolean getCompleted() {
return this.mCompleted;
}
public String getNotes() {
return this.mNotes;
}
public Task getPriorSibling() {
return this.mPriorSibling;
}
public TaskList getParent() {
return this.mParent;
}
}
```

@ -0,0 +1,141 @@
AndroidJava`TaskList``Node`Google Tasks
```java
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.gtask.data;
import android.database.Cursor;
import android.util.Log;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.exception.ActionFailureException;
import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
// TaskList类继承自Node类用于表示一个任务列表
public class TaskList extends Node {
// 类的标签,用于日志记录
private static final String TAG = TaskList.class.getSimpleName();
// 成员变量
private int mIndex; // 任务列表的索引
private ArrayList<Task> mChildren; // 任务列表中的子任务
// 构造函数初始化TaskList对象
public TaskList() {
super();
mChildren = new ArrayList<Task>();
mIndex = 1;
}
// 获取创建任务列表的JSON对象
public JSONObject getCreateAction(int actionId) {
// ... 创建任务列表的JSON对象
}
// 获取更新任务列表的JSON对象
public JSONObject getUpdateAction(int actionId) {
// ... 更新任务列表的JSON对象
}
// 根据远程JSON对象设置任务列表内容
public void setContentByRemoteJSON(JSONObject js) {
// ... 从远程JSON对象设置任务列表内容
}
// 根据本地JSON对象设置任务列表内容
public void setContentByLocalJSON(JSONObject js) {
// ... 从本地JSON对象设置任务列表内容
}
// 从任务列表内容获取本地JSON对象
public JSONObject getLocalJSONFromContent() {
// ... 从任务列表内容获取本地JSON对象
}
// 获取同步操作
public int getSyncAction(Cursor c) {
// ... 根据数据库游标获取同步操作
}
// 获取子任务的数量
public int getChildTaskCount() {
return mChildren.size();
}
// 添加子任务
public boolean addChildTask(Task task) {
// ... 添加子任务到任务列表
}
// 在指定索引处添加子任务
public boolean addChildTask(Task task, int index) {
// ... 在指定索引处添加子任务到任务列表
}
// 移除子任务
public boolean removeChildTask(Task task) {
// ... 从任务列表移除子任务
}
// 移动子任务到指定索引
public boolean moveChildTask(Task task, int index) {
// ... 移动子任务到指定索引
}
// 根据GID查找子任务
public Task findChildTaskByGid(String gid) {
// ... 根据GID查找子任务
}
// 获取子任务的索引
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
// 根据索引获取子任务
public Task getChildTaskByIndex(int index) {
// ... 根据索引获取子任务
}
// 根据GID获取子任务
public Task getChilTaskByGid(String gid) {
// ... 根据GID获取子任务
}
// 获取子任务列表
public ArrayList<Task> getChildTaskList() {
return this.mChildren;
}
// 设置和获取方法
public void setIndex(int index) {
this.mIndex = index;
}
public int getIndex() {
return this.mIndex;
}
}
```
Loading…
Cancel
Save