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;
}
}
```

@ -0,0 +1,23 @@
[中文]
1. MiCode便签是小米便签的社区开源版由MIUI团队(www.miui.com) 发起并贡献第一批代码遵循NOTICE文件所描述的开源协议
今后为MiCode社区(www.micode.net) 拥有,并由社区发布和维护。
2. Bug反馈和跟踪请访问Github,
https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
3. 功能建议和综合讨论请访问MiCode,
http://micode.net/forum.php?mod=forumdisplay&fid=38
[English]
1. MiCode Notes is open source edition of XM notepad, it's first initiated and sponsored by MIUI team (www.miui.com).
It's opened under license described by NOTICE file. It's owned by the MiCode community (www.micode.net). In future,
the MiCode community will release and maintain this project.
2. Regarding issue tracking, please visit Github,
https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
3. Regarding feature request and general discussion, please visit Micode forum,
http://micode.net/forum.php?mod=forumdisplay&fid=38
Loading…
Cancel
Save