();
}
- if(sContactCache.containsKey(phoneNumber)) {
+ if(sContactCache.containsKey(phoneNumber)) { //接下来,如果sContactCache中包含给定电话号码的键值对,则直接返回缓存中的联系人姓名。
return sContactCache.get(phoneNumber);
}
- String selection = CALLER_ID_SELECTION.replace("+",
+ String selection = CALLER_ID_SELECTION.replace("+", //首先将给定的电话号码转换为最小匹配形式,然后使用replace()方法将查询条件中的"+"替换为最小匹配的电话号码形式。
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
- Cursor cursor = context.getContentResolver().query(
- Data.CONTENT_URI,
- new String [] { Phone.DISPLAY_NAME },
- selection,
- new String[] { phoneNumber },
- null);
+ Cursor cursor = context.getContentResolver().query( //执行了一个查询操作,该方法会返回一个Cursor对象,用于遍历查询结果
+ Data.CONTENT_URI, //指定了要查询的数据表的URI,表示通讯录数据。
+ new String [] { Phone.DISPLAY_NAME }, //是要查询的列名,这里是查询联系人的显示名称。
+ selection, //是查询条件,根据前面处理过的最小匹配电话号码来查询匹配的联系人信息。
+ new String[] { phoneNumber }, //是查询条件中的参数值,用于替换查询条件中的"?"占位符。
+ null); //最后一个参数是排序方式,这里为空,表示不进行排序。
- if (cursor != null && cursor.moveToFirst()) {
+ if (cursor != null && cursor.moveToFirst()) { //这个条件语句检查Cursor对象是否不为空,并且能够将游标移动到第一行。如果满足条件,则表示查询结果非空且至少存在一个匹配项。
try {
- String name = cursor.getString(0);
- sContactCache.put(phoneNumber, name);
+ String name = cursor.getString(0); //获取查询结果中第一列(索引为0)的数据,即联系人的显示名称。
+ sContactCache.put(phoneNumber, name); //将此信息存储在sContactCache缓存中
return name;
- } catch (IndexOutOfBoundsException e) {
+ } catch (IndexOutOfBoundsException e) { //如果在获取查询结果的过程中发生异常,说明查询结果中没有有效数据,此时会打印错误日志并返回null
Log.e(TAG, " Cursor get string error " + e.toString());
return null;
- } finally {
+ } finally { //无论是否出现异常,最后都会通过cursor.close()方法关闭Cursor对象,释放资源。
cursor.close();
}
- } else {
+ } else { //如果查询结果为空或者没有匹配项,就会执行这个分支。它会打印调试日志,指示没有找到与给定电话号码匹配的联系人,并返回null。
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}
}
}
+
diff --git a/src/Notes2/src/net/micode/notes/data/Notes.java b/src/Notes2/src/net/micode/notes/data/Notes.java
index f240604..3820220 100644
--- a/src/Notes2/src/net/micode/notes/data/Notes.java
+++ b/src/Notes2/src/net/micode/notes/data/Notes.java
@@ -18,9 +18,9 @@ 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 String AUTHORITY = "micode_notes"; //定义了一个字符串常量AUTHORITY,代表了内容提供者的授权信息。
+ public static final String TAG = "Notes"; //定义了一个字符串常量TAG,可能用于在日志中进行标记或调试。
+ public static final int TYPE_NOTE = 0; //定义了三个整型常量,分别表示笔记、文件夹和系统类型。
public static final int TYPE_FOLDER = 1;
public static final int TYPE_SYSTEM = 2;
@@ -30,23 +30,23 @@ public class Notes {
* {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder
* {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records
*/
- 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;
-
- 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";
-
- 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 int ID_ROOT_FOLDER = 0; //定义了一些文件夹的标识符常量。ID_ROOT_FOLDER表示根文件夹的标识符为0
+ public static final int ID_TEMPARAY_FOLDER = -1; //表示临时文件夹的标识符为-1
+ public static final int ID_CALL_RECORD_FOLDER = -2; //表示通话记录文件夹的标识符为-2
+ public static final int ID_TRASH_FOLER = -3; //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";//小部件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";//文件夹ID
+ public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date";//通话日期
+
+ public static final int TYPE_WIDGET_INVALIDE = -1; //无效小部件类型
+ public static final int TYPE_WIDGET_2X = 0; //2x大小的小部件类型
+ public static final int TYPE_WIDGET_4X = 1; //4x
+
+ public static class DataConstants { //内部静态类(定义在一个类的内部,无法从内部静态类的实例中访问外部类的非静态成员)
public static final String NOTE = TextNote.CONTENT_ITEM_TYPE;
public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE;
}
@@ -54,12 +54,17 @@ public class Notes {
/**
* Uri to query all notes and folders
*/
- public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");
+ public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");//可以用于在应用程序中执行查询操作,以获取笔记和文件夹的数据。
/**
* Uri to query data
*/
- public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");
+ public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");//可以用于在应用程序中执行查询操作,以获取特定类型的数据。
+
+ /**
+ * 定义了一个Java接口NoteColumns,用于定义笔记或文件夹的列名常量。
+ */
+ //Uri(统一资源标识符)是用来唯一标识资源的字符串格式。在Android中,Uri经常被用于访问和操作应用程序中的数据
public interface NoteColumns {
/**
@@ -167,6 +172,9 @@ public class Notes {
public static final String VERSION = "version";
}
+ /**
+ * 定义了一个Java接口DataColumns,用于存储笔记和文件夹的相关信息。
+ */
public interface DataColumns {
/**
* The unique ID for a row
@@ -246,15 +254,15 @@ public class Notes {
* Mode to indicate the text in check list mode or not
* Type: Integer 1:check list mode 0: normal mode
*/
- public static final String MODE = DATA1;
+ public static final String MODE = DATA1; //模式
- public static final int MODE_CHECK_LIST = 1;
+ public static final int MODE_CHECK_LIST = 1; //1是检查模式,0是普通模式
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note";
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note";//MIME类型,指定返回的数据类型为目录类型
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note";
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note";//单个项类型
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");//标示URI,访问内容
}
public static final class CallNote implements DataColumns {
@@ -268,12 +276,12 @@ public class Notes {
* Phone number for this record
* Type: TEXT
*/
- public static final String PHONE_NUMBER = DATA3;
+ public static final String PHONE_NUMBER = DATA3; //通话记录的日期
- public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note";
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note";//电话号码
- public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note";
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note";//用于指定返回的数据类型为单个项类型。
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note");
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note");//表示通话记录的内容URI,用于访问通话记录的内容。
}
-}
+}
\ No newline at end of file
diff --git a/src/Notes2/src/net/micode/notes/data/NotesDatabaseHelper.java b/src/Notes2/src/net/micode/notes/data/NotesDatabaseHelper.java
index ffe5d57..744c9f3 100644
--- a/src/Notes2/src/net/micode/notes/data/NotesDatabaseHelper.java
+++ b/src/Notes2/src/net/micode/notes/data/NotesDatabaseHelper.java
@@ -27,50 +27,57 @@ 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";
+public class NotesDatabaseHelper extends SQLiteOpenHelper { //类的继承,前是后的子集
+ private static final String DB_NAME = "note.db"; //私有变量
- private static final int DB_VERSION = 4;
+ private static final int DB_VERSION = 4; //数据库版本号
- public interface TABLE {
- public static final String NOTE = "note";
+ public interface TABLE { //内部接口table
+ public static final String NOTE = "note"; //笔记本的名字叫note
- public static final String DATA = "data";
+ public static final String DATA = "data"; //数据表的名字叫data
}
- private static final String TAG = "NotesDatabaseHelper";
+ private static final String TAG = "NotesDatabaseHelper"; //日志标签,用于在日志中标记该类的信息
- private static NotesDatabaseHelper mInstance;
+ private static NotesDatabaseHelper mInstance; //mInstance会在NotesDatabaseHelper类中作为单例模式的实现,以确保在应用程序中只有一个NotesDatabaseHelper类的实例被创建并被全局范围内所使用。
+ /**
+ * 创建两个数据库表,分别存储笔记和与笔记相关的数据,以及相应的索引。
+ */
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" +
+ NoteColumns.ID + " INTEGER PRIMARY KEY," + //主键(保证表中的每一行都有唯一性)
+ NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + //父级的id
+ 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," + //关联的小部件的id
+ NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," + //小部件的类型
+ NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," + //用于同步的id,与远程同步服务有关
+ NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," + //笔记是否在本地被修改
+ NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + //原始父级的id
+ NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," + //google任务服务的id
+ NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" + //笔记的版本号
")";
+ /**
+ * 创建数据表的SQL语句创建数据表的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.ID + " INTEGER PRIMARY KEY," + //DataColumns.ID表示一个名为"ID"的列,数据类型为INTEGER(整数),并且被定义为主键。
+ 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 ''," +
@@ -206,10 +213,18 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
" END";
+ /**
+ * 接受cotext参数(包含了应用程序的运行环境信息),用于创建和打开数据库
+ * @param context
+ */
public NotesDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
+ /**
+ * (创建名为note的表,并且为该表重新创建触发器和创建系统文件夹。)
+ * @param db
+ */
public void createNoteTable(SQLiteDatabase db) {
db.execSQL(CREATE_NOTE_TABLE_SQL);
reCreateNoteTableTriggers(db);
@@ -235,6 +250,10 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER);
}
+ /**
+ * 在数据库中创建系统级别的文件夹。
+ * @param db
+ */
private void createSystemFolder(SQLiteDatabase db) {
ContentValues values = new ContentValues();
@@ -270,6 +289,10 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.insert(TABLE.NOTE, null, values);
}
+ /**
+ * 用于创建数据表,其中包括执行创建表的SQL语句、重新创建触发器以及创建索引,并在完成之后记录日志。
+ * @param db
+ */
public void createDataTable(SQLiteDatabase db) {
db.execSQL(CREATE_DATA_TABLE_SQL);
reCreateDataTableTriggers(db);
@@ -277,6 +300,10 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
Log.d(TAG, "data table has been created");
}
+ /**
+ * 用于重新创建数据表的触发器。首先,它会删除已存在的触发器,然后再重新创建触发器。
+ * @param db
+ */
private void reCreateDataTableTriggers(SQLiteDatabase db) {
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert");
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update");
@@ -287,37 +314,47 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER);
}
- static synchronized NotesDatabaseHelper getInstance(Context context) {
+ static synchronized NotesDatabaseHelper getInstance(Context context) { //static synchronized 是Java中的修饰符,用于同时指定一个方法或代码块为静态和同步。
if (mInstance == null) {
mInstance = new NotesDatabaseHelper(context);
}
return mInstance;
}
+ /**
+ * 系统的首次创建
+ * @param db
+ */
@Override
public void onCreate(SQLiteDatabase db) {
createNoteTable(db);
createDataTable(db);
}
+ /**
+ * 数据库升级
+ * @param db
+ * @param oldVersion
+ * @param newVersion
+ */
@Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- boolean reCreateTriggers = false;
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //db是要升级的数据库对象,oldVersion是当前数据库版本号,newVersion是要升级到的新版本号。
+ boolean reCreateTriggers = false; //是否重新创建触发器和是否跳过V2版本的升级。
boolean skipV2 = false;
- if (oldVersion == 1) {
+ if (oldVersion == 1) { //执行升级到V2版本的操作。
upgradeToV2(db);
skipV2 = true; // this upgrade including the upgrade from v2 to v3
oldVersion++;
}
- if (oldVersion == 2 && !skipV2) {
+ if (oldVersion == 2 && !skipV2) { //执行升级到V3版本的操作。
upgradeToV3(db);
reCreateTriggers = true;
oldVersion++;
}
- if (oldVersion == 3) {
+ if (oldVersion == 3) { //执行升级到V4版本的操作。
upgradeToV4(db);
oldVersion++;
}
@@ -327,36 +364,36 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
reCreateDataTableTriggers(db);
}
- if (oldVersion != newVersion) {
+ if (oldVersion != newVersion) { //判断升级后的数据库版本号是否与目标版本号相等。如果不相等,则抛出一个异常。
throw new IllegalStateException("Upgrade notes database to version " + newVersion
+ "fails");
}
}
private void upgradeToV2(SQLiteDatabase db) {
- db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); //删除名为Note和Data的表。
db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA);
- createNoteTable(db);
+ createNoteTable(db); //创建新的表
createDataTable(db);
}
private void upgradeToV3(SQLiteDatabase db) {
// drop unused triggers
- db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert");
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); //删除三个触发器
db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_delete");
db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_update");
// add a column for gtask id
- db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID
+ db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID //向Note表中添加一个名为gtask_id的列。该列的数据类型为TEXT,非空,并设置默认值为空字符串。
+ " TEXT NOT NULL DEFAULT ''");
// add a trash system folder
- ContentValues values = new ContentValues();
- values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER);
- values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ ContentValues values = new ContentValues(); //创建一个ContentValues对象,用于存储待插入到数据库的键值对。
+ values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); //系统级别的文件夹,用于存放已经删除的笔记。
+ values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); //表示向Note表中插入的记录类型为Notes.TYPE_SYSTEM,即系统级别的记录
db.insert(TABLE.NOTE, null, values);
}
private void upgradeToV4(SQLiteDatabase db) {
- db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION
+ db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION //向Note表中添加一个名为version的列。该列的数据类型为INTEGER
+ " INTEGER NOT NULL DEFAULT 0");
}
-}
+}
\ No newline at end of file
diff --git a/src/Notes2/src/net/micode/notes/gtask/remote/GTaskClient.java b/src/Notes2/src/net/micode/notes/gtask/remote/GTaskClient.java
index c67dfdf..cfdd529 100644
--- a/src/Notes2/src/net/micode/notes/gtask/remote/GTaskClient.java
+++ b/src/Notes2/src/net/micode/notes/gtask/remote/GTaskClient.java
@@ -60,6 +60,42 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
+<<<<<<< HEAD
+//标明了这个类的名字
+public class GTaskClient {
+ private static final String TAG = GTaskClient.class.getSimpleName(); //私有化一个用于日志输出的标签常量
+
+ private static final String GTASK_URL = "https://mail.google.com/tasks/"; //私有化Google Tasks 的基本 URL 地址
+
+ private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig";//私有化获取任务的 URL 地址
+
+ private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig";//私有化提交任务的 URL 地址
+
+ private static GTaskClient mInstance = null; //mInstance 是 GTaskClient 类的单例实例
+
+ private DefaultHttpClient mHttpClient;//mHttpClient 是一个 DefaultHttpClient 对象,用于发送 HTTP 请求
+
+ private String mGetUrl; //mGetUrl 和 mPostUrl 是用于存储获取任务和提交任务的 URL 地址
+
+ private String mPostUrl;//mGetUrl 和 mPostUrl 是用于存储获取任务和提交任务的 URL 地址
+
+ private long mClientVersion;//私有化客户端版本的长整型变量
+
+ private boolean mLoggedin;//表示是否已登录的布尔型变量
+
+ private long mLastLoginTime;//上次登录时间的长整型变量
+
+ private int mActionId;//表示当前操作的整型变量
+
+ private Account mAccount;//一个 Account 对象,用于存储用户账号信息
+
+ private JSONArray mUpdateArray;//一个 JSONArray 对象,用于存储任务更新信息
+
+
+ //GTaskClient 类的一个私有构造方法,使用 private 关键字修饰,表示只能在类内部调用
+ private GTaskClient() {
+ mHttpClient = null; //初始化为null
+=======
public class GTaskClient {
private static final String TAG = GTaskClient.class.getSimpleName();
@@ -92,6 +128,7 @@ public class GTaskClient {
private GTaskClient() {
mHttpClient = null;
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
mGetUrl = GTASK_GET_URL;
mPostUrl = GTASK_POST_URL;
mClientVersion = -1;
@@ -102,6 +139,126 @@ public class GTaskClient {
mUpdateArray = null;
}
+<<<<<<< HEAD
+ //用来获取的实例化对象
+ public static synchronized GTaskClient getInstance() { //使用 public 关键字修饰,表示可以从任何地方访问
+ if (mInstance == null) { //首先判断 mInstance 是否为 null,即判断是否已经存在单例实例
+ mInstance = new GTaskClient();//如果 mInstance 为 null,则创建一个新的 GTaskClient 实例,并赋值给 mInstance
+ }
+ return mInstance; //返回mInstance这个实例化对象
+ }
+
+ //用来实现登录操作的函数,传入的参数是一个Activity
+ public boolean login(Activity activity) {
+ // we suppose that the cookie would expire after 5 minutes
+ // then we need to re-login
+ // 设置登录操作限制时间,如果超时则需要重新登录
+ final long interval = 1000 * 60 * 5; // 判断距离最后一次登录操作是否超过5分钟
+ if (mLastLoginTime + interval < System.currentTimeMillis()) { // 判断上次登录时间加上限制时间是否小于当前系统时间
+ mLoggedin = false; // 如果超时了,设置登录状态为未登录
+ }
+
+ // need to re-login after account switch
+ //重新登录操作
+ if (mLoggedin && !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity.getSyncAccountName(activity))) { // 如果已经登录且同步账户名称发生变化
+ mLoggedin = false; // 设置登录状态为未登录
+ }
+
+ //如果没超过时间,则不需要重新登录
+ if (mLoggedin) { // 如果已经登录
+ Log.d(TAG, "already logged in"); // 打印日志,表示已经登录
+ return true; // 返回已经登录的状态
+ }
+
+ mLastLoginTime = System.currentTimeMillis(); // 更新最后登录时间为当前系统时间
+ String authToken = loginGoogleAccount(activity, false); // 尝试使用谷歌账户登录,获取授权令牌
+ if (authToken == null) { // 如果获取的授权令牌为空
+ Log.e(TAG, "login google account failed"); // 打印错误日志,表示谷歌账户登录失败
+ return false; // 返回登录失败的状态
+ }
+
+ // login with custom domain if necessary
+ //尝试使用用户自己的域名登录
+ if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase().endsWith("googlemail.com"))) { // 如果用户账户不是以gmail.com或googlemail.com结尾
+ StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); // 构建自定义域名的URL
+ int index = mAccount.name.indexOf('@') + 1; // 获取@符号后的索引位置
+ String suffix = mAccount.name.substring(index); // 获取@符号后的字符串作为域名后缀
+ url.append(suffix + "/"); // 拼接域名后缀到URL
+ mGetUrl = url.toString() + "ig"; // 设置用户对应的getUrl
+ mPostUrl = url.toString() + "r/ig"; // 设置用户对应的postUrl
+
+ if (tryToLoginGtask(activity, authToken)) { // 尝试使用自定义域名登录
+ mLoggedin = true; // 设置登录状态为已登录
+ }
+ }
+
+ // try to login with google official URL
+ //如果用户账户无法登录,则使用谷歌官方的URI进行登录
+ if (!mLoggedin) { // 如果之前的登录尝试未成功
+ mGetUrl = GTASK_GET_URL; // 设置使用谷歌官方URL进行get请求
+ mPostUrl = GTASK_POST_URL; // 设置使用谷歌官方URL进行post请求
+ if (!tryToLoginGtask(activity, authToken)) { // 尝试使用谷歌官方的URL进行登录
+ return false; // 如果登录失败,返回登录失败状态
+ }
+ }
+
+ mLoggedin = true; // 设置登录状态为已登录
+ return true; // 返回登录成功的状态
+ }
+
+
+ //具体实现登录谷歌账户的方法
+ private String loginGoogleAccount(Activity activity, boolean invalidateToken) {
+ String authToken; // 定义一个用于存储认证令牌的变量
+
+ AccountManager accountManager = AccountManager.get(activity); // 获取账户管理器实例,用于管理用户账户信息
+
+ Account[] accounts = accountManager.getAccountsByType("com.google"); // 获取所有类型为"com.google"的账户列表
+
+ if (accounts.length == 0) { // 如果没有找到Google账户
+ Log.e(TAG, "there is no available google account"); // 记录错误日志,表示没有可用的Google账户
+ return null; // 返回空值
+ }
+
+ String accountName = NotesPreferenceActivity.getSyncAccountName(activity); // 获取同步账户的名称
+
+ Account account = null;
+ for (Account a : accounts) { // 遍历查找已记录的账户信息
+ if (a.name.equals(accountName)) { // 如果找到了同名的账户
+ account = a; // 将找到的账户赋给account变量
+ break; // 跳出循环
+ }
+ }
+ if (account != null) { // 如果找到了匹配的账户
+ mAccount = account; // 将匹配的账户信息存储在mAccount中
+ } else {
+ Log.e(TAG, "unable to get an account with the same name in the settings"); // 记录错误日志,表示无法获取相同名称的账户
+ return null; // 返回空值
+ }
+
+ // get the token now
+ // 获取认证令牌
+ AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, "goanna_mobile", null, activity, null, null); // 异步获取指定账户的认证令牌
+ try {
+ Bundle authTokenBundle = accountManagerFuture.getResult(); // 获取异步操作的结果
+ authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN); // 从结果中获取认证令牌
+
+ // 如果需要废除认证令牌
+ if (invalidateToken) {
+ accountManager.invalidateAuthToken("com.google", authToken); // 废除认证令牌
+ loginGoogleAccount(activity, false); // 重新调用登录方法
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "get auth token failed"); // 记录获取认证令牌失败的错误日志
+ authToken = null; // 将认证令牌置为空
+ }
+
+ return authToken; // 返回获取到的认证令牌
+ }
+
+
+ //尝试登陆Gtask,这只是一个预先判断令牌是否是有效以及是否能登上GTask的方法,而不是具体实现登陆的方法
+=======
public static synchronized GTaskClient getInstance() {
if (mInstance == null) {
mInstance = new GTaskClient();
@@ -207,10 +364,15 @@ public class GTaskClient {
return authToken;
}
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
private boolean tryToLoginGtask(Activity activity, String authToken) {
if (!loginGtask(authToken)) {
// maybe the auth token is out of date, now let's invalidate the
// token and try again
+<<<<<<< HEAD
+ //删除过一个无效的authToken,申请一个新的后再次尝试登陆
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
authToken = loginGoogleAccount(activity, true);
if (authToken == null) {
Log.e(TAG, "login google account failed");
@@ -225,6 +387,17 @@ public class GTaskClient {
return true;
}
+<<<<<<< HEAD
+ //实现登录GTask的具体操作
+ private boolean loginGtask(String authToken) {
+ int timeoutConnection = 10000;
+ int timeoutSocket = 15000; //socket是一种通信连接实现数据的交换的端口
+ HttpParams httpParameters = new BasicHttpParams(); //实例化一个新的HTTP参数类
+ HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection); //设置连接超时时间
+ HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket); //设置设置端口超时时间
+ mHttpClient = new DefaultHttpClient(httpParameters);
+ BasicCookieStore localBasicCookieStore = new BasicCookieStore(); //设置本地cookie
+=======
private boolean loginGtask(String authToken) {
int timeoutConnection = 10000;
int timeoutSocket = 15000;
@@ -233,11 +406,24 @@ public class GTaskClient {
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
mHttpClient = new DefaultHttpClient(httpParameters);
BasicCookieStore localBasicCookieStore = new BasicCookieStore();
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
mHttpClient.setCookieStore(localBasicCookieStore);
HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false);
// login gtask
try {
+<<<<<<< HEAD
+ String loginUrl = mGetUrl + "?auth=" + authToken; //设置登录的url
+ HttpGet httpGet = new HttpGet(loginUrl); //通过登录的uri实例化网页上资源的查找
+ HttpResponse response = null;
+ response = mHttpClient.execute(httpGet);
+
+ //获取CookieStore里存放的cookie
+ // get the cookie now
+ List cookies = mHttpClient.getCookieStore().getCookies();
+ boolean hasAuthCookie = false;
+ for (Cookie cookie : cookies) { //看如果存有“GTL”,则说明有验证成功的有效的cookie
+=======
String loginUrl = mGetUrl + "?auth=" + authToken;
HttpGet httpGet = new HttpGet(loginUrl);
HttpResponse response = null;
@@ -247,6 +433,7 @@ public class GTaskClient {
List cookies = mHttpClient.getCookieStore().getCookies();
boolean hasAuthCookie = false;
for (Cookie cookie : cookies) {
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
if (cookie.getName().contains("GTL")) {
hasAuthCookie = true;
}
@@ -256,13 +443,21 @@ public class GTaskClient {
}
// get the client version
+<<<<<<< HEAD
+ //获取client的内容
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
String resString = getResponseContent(response.getEntity());
String jsBegin = "_setup(";
String jsEnd = ")}";
int begin = resString.indexOf(jsBegin);
int end = resString.lastIndexOf(jsEnd);
String jsString = null;
+<<<<<<< HEAD
+ if (begin != -1 && end != -1 && begin < end) { //if循环用来在返回的Content中截取从_setup(开始到)}中间的字符串内容,也就是gtask_url的内容
+=======
if (begin != -1 && end != -1 && begin < end) {
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
jsString = resString.substring(begin + jsBegin.length(), end);
}
JSONObject js = new JSONObject(jsString);
@@ -284,31 +479,55 @@ public class GTaskClient {
return mActionId++;
}
+<<<<<<< HEAD
+ //实例化创建一个用于向网络传输数据的对象
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
private HttpPost createHttpPost() {
HttpPost httpPost = new HttpPost(mPostUrl);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
httpPost.setHeader("AT", "1");
+<<<<<<< HEAD
+ return httpPost; //返回一个空的httpPost实例化对象
+ }
+
+ //通过URL获取响应后返回的数据
+ private String getResponseContent(HttpEntity entity) throws IOException {
+ String contentEncoding = null;
+ if (entity.getContentEncoding() != null) { //使用getContentEncoding()获取网络上的资源和数据
+=======
return httpPost;
}
private String getResponseContent(HttpEntity entity) throws IOException {
String contentEncoding = null;
if (entity.getContentEncoding() != null) {
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
contentEncoding = entity.getContentEncoding().getValue();
Log.d(TAG, "encoding: " + contentEncoding);
}
InputStream input = entity.getContent();
+<<<<<<< HEAD
+ if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) { //GZIP是使用DEFLATE进行压缩数据的另一个压缩库
+ input = new GZIPInputStream(entity.getContent());
+ } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) { //DEFLATE是一个无专利的压缩算法,它可以实现无损数据压缩
+=======
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
input = new GZIPInputStream(entity.getContent());
} else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) {
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
Inflater inflater = new Inflater(true);
input = new InflaterInputStream(entity.getContent(), inflater);
}
try {
InputStreamReader isr = new InputStreamReader(input);
+<<<<<<< HEAD
+ BufferedReader br = new BufferedReader(isr); //是一个包装类,它可以包装字符流,将字符流放入缓存里,先把字符读到缓存里,到缓存满了时候,再读入内存,是为了提供读的效率而设计的
+=======
BufferedReader br = new BufferedReader(isr);
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
StringBuilder sb = new StringBuilder();
while (true) {
@@ -323,12 +542,21 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //通过JSON发送请求
+ //请求的具体内容在json的实例化对象js中然后传入
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
private JSONObject postRequest(JSONObject js) throws NetworkFailureException {
if (!mLoggedin) {
Log.e(TAG, "please login first");
throw new ActionFailureException("not logged in");
}
+<<<<<<< HEAD
+ //实例化一个httpPost的对象用来向服务器传输数据,在这里就是发送请求,而请求的内容在js里
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
HttpPost httpPost = createHttpPost();
try {
LinkedList list = new LinkedList();
@@ -337,6 +565,10 @@ public class GTaskClient {
httpPost.setEntity(entity);
// execute the post
+<<<<<<< HEAD
+ //执行这个请求
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
HttpResponse response = mHttpClient.execute(httpPost);
String jsString = getResponseContent(response.getEntity());
return new JSONObject(jsString);
@@ -360,10 +592,20 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //创建单个任务
+ //传入参数是一个.gtask.data.Task包里Task类的对象
+ public void createTask(Task task) throws NetworkFailureException {
+ commitUpdate();
+ try {
+
+ JSONObject jsPost = new JSONObject();//利用json获取Task里的内容,并且创建相应的jsPost
+=======
public void createTask(Task task) throws NetworkFailureException {
commitUpdate();
try {
JSONObject jsPost = new JSONObject();
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
JSONArray actionList = new JSONArray();
// action_list
@@ -377,7 +619,11 @@ public class GTaskClient {
JSONObject jsResponse = postRequest(jsPost);
JSONObject jsResult = (JSONObject) jsResponse.getJSONArray(
GTaskStringUtils.GTASK_JSON_RESULTS).get(0);
+<<<<<<< HEAD
+ task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID)); //使用task.setGid设置task的new_ID
+=======
task.setGid(jsResult.getString(GTaskStringUtils.GTASK_JSON_NEW_ID));
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
} catch (JSONException e) {
Log.e(TAG, e.toString());
@@ -386,6 +632,10 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //创建一个任务列表
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
public void createTaskList(TaskList tasklist) throws NetworkFailureException {
commitUpdate();
try {
@@ -412,6 +662,16 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //同步更新操作
+ public void commitUpdate() throws NetworkFailureException {
+ if (mUpdateArray != null) {
+ try {
+ JSONObject jsPost = new JSONObject(); //使用JSONObject进行数据存储
+
+ // action_list
+ jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray); //使用jsPost.put,Put的信息包括UpdateArray和ClientVersion
+=======
public void commitUpdate() throws NetworkFailureException {
if (mUpdateArray != null) {
try {
@@ -419,11 +679,16 @@ public class GTaskClient {
// action_list
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray);
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
// client_version
jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion);
+<<<<<<< HEAD
+ postRequest(jsPost); //使用postRequest发送这个jspost,进行处理
+=======
postRequest(jsPost);
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
mUpdateArray = null;
} catch (JSONException e) {
Log.e(TAG, e.toString());
@@ -433,12 +698,20 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //添加更新的事项
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
public void addUpdateNode(Node node) throws NetworkFailureException {
if (node != null) {
// too many update items may result in an error
// set max to 10 items
if (mUpdateArray != null && mUpdateArray.length() > 10) {
+<<<<<<< HEAD
+ commitUpdate(); //调用commitUpdate()来提交更新
+=======
commitUpdate();
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
}
if (mUpdateArray == null)
@@ -447,6 +720,10 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //用来移动任务,它通过构建 JSON 对象和发送 POST 请求来实现任务的移动操作
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
public void moveTask(Task task, TaskList preParent, TaskList curParent)
throws NetworkFailureException {
commitUpdate();
@@ -456,6 +733,11 @@ public class GTaskClient {
JSONObject action = new JSONObject();
// action_list
+<<<<<<< HEAD
+ //type——移动类型,ID——操作的 ID,GTASK_JSON_ID——要移动的任务的 ID
+ //SOURCE_LIST——要移动任务的原始父任务列表的 ID,DEST_PARENT——要移动任务的新父任务列表的 ID
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE);
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());
@@ -463,15 +745,27 @@ public class GTaskClient {
if (preParent == curParent && task.getPriorSibling() != null) {
// put prioring_sibing_id only if moving within the tasklist and
// it is not the first one
+<<<<<<< HEAD
+ //设置优先级ID,只有当移动是发生在文件中
+ action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling());
+ }
+ action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid());//设置移动前所属列表
+ action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid());//设置当前所属列表
+=======
action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling());
}
action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid());
action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid());
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
if (preParent != curParent) {
// put the dest_list only if moving between tasklists
action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid());
}
actionList.put(action);
+<<<<<<< HEAD
+ //最后将ACTION_LIST加入到jsPost中
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
@@ -486,6 +780,85 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //用来删除节点,它通过构建 JSON 对象和发送 POST 请求来实现节点的删除操作
+ public void deleteNode(Node node) throws NetworkFailureException {
+ commitUpdate(); // 提交更新操作
+
+ try {
+ JSONObject jsPost = new JSONObject(); // 创建一个新的JSON对象,用于存储POST请求的参数
+ JSONArray actionList = new JSONArray(); // 创建一个新的JSON数组,用于存储操作列表
+
+ // action_list
+ node.setDeleted(true); // 标志该节点已被删除
+ actionList.put(node.getUpdateAction(getActionId())); // 将删除操作的ID加入到操作列表中
+ jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); // 将操作列表加入到POST请求参数中
+
+ // client_version
+ jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); // 将客户端版本号加入到POST请求参数中
+
+ postRequest(jsPost); // 发送POST请求
+ mUpdateArray = null; // 将更新数组置为空
+ } catch (JSONException e) { // 捕获JSON异常
+ Log.e(TAG, e.toString()); // 记录错误日志
+ e.printStackTrace();
+ throw new ActionFailureException("delete node: handing jsonobject failed"); // 抛出操作失败异常
+ }
+ }
+
+
+ //获取任务列表
+ public JSONArray getTaskLists() throws NetworkFailureException {
+ if (!mLoggedin) { // 如果未登录
+ Log.e(TAG, "please login first"); // 记录错误日志
+ throw new ActionFailureException("not logged in"); // 抛出操作失败异常
+ }
+
+ try {
+ HttpGet httpGet = new HttpGet(mGetUrl); // 创建一个HTTP GET请求对象
+ HttpResponse response = null; // 定义一个HTTP响应对象
+
+ response = mHttpClient.execute(httpGet); // 执行HTTP GET请求,并将响应存储在response对象中
+
+ // get the task list
+ String resString = getResponseContent(response.getEntity()); // 从响应实体中获取响应内容
+ String jsBegin = "_setup("; // 定义JS脚本开始标记
+ String jsEnd = ")}"; // 定义JS脚本结束标记
+ int begin = resString.indexOf(jsBegin); // 查找JS脚本开始标记的位置
+ int end = resString.lastIndexOf(jsEnd); // 查找JS脚本结束标记的位置
+ String jsString = null;
+
+ // 如果找到了JS脚本开始和结束标记
+ if (begin != -1 && end != -1 && begin < end) {
+ jsString = resString.substring(begin + jsBegin.length(), end); // 截取JS脚本字符串
+ }
+
+ JSONObject js = new JSONObject(jsString); // 创建一个新的JSON对象,用于解析JS脚本字符串
+ return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS); // 返回解析结果中的任务列表信息
+ } catch (ClientProtocolException e) { // 捕获客户端协议异常
+ Log.e(TAG, e.toString()); // 记录错误日志
+ e.printStackTrace();
+ throw new NetworkFailureException("gettasklists: httpget failed"); // 抛出网络操作失败异常
+ } catch (IOException e) { // 捕获IO异常
+ Log.e(TAG, e.toString()); // 记录错误日志
+ e.printStackTrace();
+ throw new NetworkFailureException("gettasklists: httpget failed"); // 抛出网络操作失败异常
+ } catch (JSONException e) { // 捕获JSON异常
+ Log.e(TAG, e.toString()); // 记录错误日志
+ e.printStackTrace();
+ throw new ActionFailureException("get task lists: handing jasonobject failed"); // 抛出操作失败异常
+ }
+ }
+
+
+ //通过传入的TASKList的gid,从网络上获取相应属于这个任务列表的任务
+ public JSONArray getTaskList(String listGid) throws NetworkFailureException {
+ commitUpdate();
+ try {
+ JSONObject jsPost = new JSONObject();//创建一个新的 JSONObject jsPost 用于存储 POST 请求的数据。
+ JSONArray actionList = new JSONArray();//创建一个新的 JSONArray actionList 用于存列表。
+ JSONObject action = new JSONObject();//创建一个新的 JSONObject action 用于表示单个操作。
+=======
public void deleteNode(Node node) throws NetworkFailureException {
commitUpdate();
try {
@@ -553,11 +926,16 @@ public class GTaskClient {
JSONObject jsPost = new JSONObject();
JSONArray actionList = new JSONArray();
JSONObject action = new JSONObject();
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
// action_list
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL);
+<<<<<<< HEAD
+ action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());//这里设置为传入的listGid
+=======
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid);
action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false);
actionList.put(action);
@@ -575,10 +953,18 @@ public class GTaskClient {
}
}
+<<<<<<< HEAD
+ //用于获取同步账户信息
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
public Account getSyncAccount() {
return mAccount;
}
+<<<<<<< HEAD
+ //重置更新内容
+=======
+>>>>>>> 3a7a23b9d2717a31b97b2a5c6deed09784b90564
public void resetUpdateArray() {
mUpdateArray = null;
}