diff --git a/doc/实践模板-开源软件泛读、标注和维护报告文档.docx b/doc/实践模板-开源软件泛读、标注和维护报告文档.docx
index 4ef4e20..8939b03 100644
Binary files a/doc/实践模板-开源软件泛读、标注和维护报告文档.docx and b/doc/实践模板-开源软件泛读、标注和维护报告文档.docx differ
diff --git a/src/xiaomi/Notes-master/AndroidManifest.xml b/src/xiaomi/Notes-master/AndroidManifest.xml
index e5c7d47..5982f19 100644
--- a/src/xiaomi/Notes-master/AndroidManifest.xml
+++ b/src/xiaomi/Notes-master/AndroidManifest.xml
@@ -1,26 +1,10 @@
-
-
-
+ android:versionName="0.1">
-
+
@@ -33,8 +17,17 @@
+ android:icon="@drawable/icon_app_new"
+ android:label="@string/app_name">
+
+
+
+
+
+
-
-
-
-
-
+ android:theme="@style/NoteTheme">
+
+
-
+
+
-
+
@@ -81,13 +72,13 @@
+ android:label="@string/app_widget2x2">
@@ -100,8 +91,7 @@
-
+ android:label="@string/app_widget4x4">
@@ -112,39 +102,32 @@
android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" />
-
-
+
-
-
+ android:name=".ui.AlarmReceiver"
+ android:process=":remote">
-
-
+ android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
-
+ android:theme="@android:style/Theme.Holo.Light">
-
+ android:name=".gtask.remote.GTaskSyncService"
+ android:exported="false">
-
+
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/res/color/primary_text_dark.xml b/src/xiaomi/Notes-master/res/color/primary_text_dark.xml
index 7c85459..8ad98e3 100644
--- a/src/xiaomi/Notes-master/res/color/primary_text_dark.xml
+++ b/src/xiaomi/Notes-master/res/color/primary_text_dark.xml
@@ -1,4 +1,4 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/res/layout/note_edit.xml b/src/xiaomi/Notes-master/res/layout/note_edit.xml
index 10b2aa7..1bb3ed8 100644
--- a/src/xiaomi/Notes-master/res/layout/note_edit.xml
+++ b/src/xiaomi/Notes-master/res/layout/note_edit.xml
@@ -31,6 +31,17 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content">
+
+
+
+ android:layout_height="fill_parent">
+
+
+ />
+
+
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/res/menu/note_list.xml b/src/xiaomi/Notes-master/res/menu/note_list.xml
index 42ea736..bd3a465 100644
--- a/src/xiaomi/Notes-master/res/menu/note_list.xml
+++ b/src/xiaomi/Notes-master/res/menu/note_list.xml
@@ -32,8 +32,18 @@
-
+
+
+
+
+
diff --git a/src/xiaomi/Notes-master/res/values-night/themes.xml b/src/xiaomi/Notes-master/res/values-night/themes.xml
new file mode 100644
index 0000000..41acc3a
--- /dev/null
+++ b/src/xiaomi/Notes-master/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/res/values-zh-rCN/strings.xml b/src/xiaomi/Notes-master/res/values-zh-rCN/strings.xml
index 09f75ed..e87098f 100644
--- a/src/xiaomi/Notes-master/res/values-zh-rCN/strings.xml
+++ b/src/xiaomi/Notes-master/res/values-zh-rCN/strings.xml
@@ -122,5 +122,11 @@
- %1$s 条符合“%2$s”的搜索结果
-
+ 撤销
+ //中文
+ 提示
+ 您不能再执行撤销了
+ 您还没有输入任何内容
+ 朗读
+ 设置字体
diff --git a/src/xiaomi/Notes-master/res/values-zh-rTW/strings.xml b/src/xiaomi/Notes-master/res/values-zh-rTW/strings.xml
index 3c41894..e29b79b 100644
--- a/src/xiaomi/Notes-master/res/values-zh-rTW/strings.xml
+++ b/src/xiaomi/Notes-master/res/values-zh-rTW/strings.xml
@@ -1,4 +1,4 @@
-
+
-
+
Notes
Notes 2x2
Notes 4x4
@@ -39,6 +38,12 @@
/MIUI/notes/
notes_%s.txt
+
+
+ Switch_to_picture1
+ Switch_to_picture2
+ Switch_to_picture3
+
(%d)
New Folder
Export text
@@ -127,9 +132,22 @@
set
cancel
- - %1$s result for \"%2$s\"
+ - %1$s result for \"%2$s\"
- - %1$s results for \"%2$s\"
+ - %1$s results for \"%2$s\"
+ FullscreenActivity
+ Dummy Button
+ 写下你的快乐
+ SplashActivity
+
+
+
+ Revoke
+ Set font
+ voice speech
+ Tips
+ You can not revoke any more
+ You haven not input anything
diff --git a/src/xiaomi/Notes-master/res/values/styles.xml b/src/xiaomi/Notes-master/res/values/styles.xml
index d750e65..fd4c3ff 100644
--- a/src/xiaomi/Notes-master/res/values/styles.xml
+++ b/src/xiaomi/Notes-master/res/values/styles.xml
@@ -16,18 +16,22 @@
-->
+
+
+
+
@@ -64,6 +68,15 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/res/values/themes.xml b/src/xiaomi/Notes-master/res/values/themes.xml
new file mode 100644
index 0000000..d28505f
--- /dev/null
+++ b/src/xiaomi/Notes-master/res/values/themes.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/data/Contact.java b/src/xiaomi/Notes-master/src/net/micode/notes/data/Contact.java
index f43b896..2b18ea5 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/data/Contact.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/data/Contact.java
@@ -36,19 +36,18 @@ import java.util.HashMap;
*/
public class Contact {
-
private static HashMap sContactCache;//定义了一个静态的HashMap变量sContactCache
private static final String TAG = "Contact";//定义了一个静态的字符串常量TAG
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 "
+ + ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
+ + " AND " + Data.RAW_CONTACT_ID + " IN "
+ "(SELECT raw_contact_id "
+ " FROM phone_lookup"
+ " WHERE min_match = '+')";
/*
*声明了一个字符串常量CALLER_ID_SELECTION,
*其中使用了函数调用PHONE_NUMBERS_EQUAL用来匹配电话号码,同时还使用了条件语句限制数据类型为电话号码联系人ID.
- */
+ */
/**
* 该方法定义了一个getContact,通过给定的电话号码实现获取联系人信息的功能。
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java b/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java
index 50c84e5..988f767 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java
@@ -53,168 +53,168 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
private static NotesDatabaseHelper mInstance;
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语句,定义了便签表的结构,包含便签各种属性和字段,存储了用户创建的所有便签的信息。
+ "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语句,存储了与便签相关的数据信息,包括了各种附加数据,用来扩展便签功能。
+ "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 + ");";
+ "CREATE INDEX IF NOT EXISTS note_id_index ON " +
+ TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
/**
* 当将便签移动到文件夹时,通过增加文件夹的便签数量来实现
*/
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =
- "CREATE TRIGGER increase_folder_count_on_update "+
- " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
- " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
- " END";
+ "CREATE TRIGGER increase_folder_count_on_update "+
+ " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
+ " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
+ " END";
/**
* 将便签从文件夹中移出时,通过减少文件夹的便签数量来实现
*/
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =
- "CREATE TRIGGER decrease_folder_count_on_update " +
- " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
- " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
- " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
- " END";
+ "CREATE TRIGGER decrease_folder_count_on_update " +
+ " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
+ " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
+ " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
+ " END";
/**
* 当向文件夹中插入新的便签时,通过增加文件夹的便签数量来实现
*/
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER =
- "CREATE TRIGGER increase_folder_count_on_insert " +
- " AFTER INSERT ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
- " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
- " END";
+ "CREATE TRIGGER increase_folder_count_on_insert " +
+ " AFTER INSERT ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
+ " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
+ " END";
/**
* 当从文件夹中删除便签时,通过减少文件夹的便签数量来实现
*/
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER =
- "CREATE TRIGGER decrease_folder_count_on_delete " +
- " AFTER DELETE ON " + TABLE.NOTE +
- " BEGIN " +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
- " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
- " AND " + NoteColumns.NOTES_COUNT + ">0;" +
- " END";
+ "CREATE TRIGGER decrease_folder_count_on_delete " +
+ " AFTER DELETE ON " + TABLE.NOTE +
+ " BEGIN " +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
+ " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
+ " AND " + NoteColumns.NOTES_COUNT + ">0;" +
+ " END";
/**
* 当插入新的数据类型时,需要更新便签的内容{@link DataConstants#NOTE}
*/
private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER =
- "CREATE TRIGGER update_note_content_on_insert " +
- " AFTER INSERT ON " + TABLE.DATA +
- " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
- " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
- " END";
+ "CREATE TRIGGER update_note_content_on_insert " +
+ " AFTER INSERT ON " + TABLE.DATA +
+ " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
+ " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
+ " END";
/**
* Update note's content when data with {@link DataConstants#NOTE} type has changed
*/
private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER =
- "CREATE TRIGGER update_note_content_on_update " +
- " AFTER UPDATE ON " + TABLE.DATA +
- " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
- " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
- " END";
+ "CREATE TRIGGER update_note_content_on_update " +
+ " AFTER UPDATE ON " + TABLE.DATA +
+ " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
+ " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
+ " END";
/**
* Update note's content when data with {@link DataConstants#NOTE} type has deleted
*/
private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER =
- "CREATE TRIGGER update_note_content_on_delete " +
- " AFTER delete ON " + TABLE.DATA +
- " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.SNIPPET + "=''" +
- " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
- " END";
+ "CREATE TRIGGER update_note_content_on_delete " +
+ " AFTER delete ON " + TABLE.DATA +
+ " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.SNIPPET + "=''" +
+ " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
+ " END";
/**
* 删除已经被删除的便签所关联的数据
*/
private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER =
- "CREATE TRIGGER delete_data_on_delete " +
- " AFTER DELETE ON " + TABLE.NOTE +
- " BEGIN" +
- " DELETE FROM " + TABLE.DATA +
- " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
- " END";
+ "CREATE TRIGGER delete_data_on_delete " +
+ " AFTER DELETE ON " + TABLE.NOTE +
+ " BEGIN" +
+ " DELETE FROM " + TABLE.DATA +
+ " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
+ " END";
/**
* 删除已经被删除的文件夹所包含的便签
*/
private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER =
- "CREATE TRIGGER folder_delete_notes_on_delete " +
- " AFTER DELETE ON " + TABLE.NOTE +
- " BEGIN" +
- " DELETE FROM " + TABLE.NOTE +
- " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
- " END";
+ "CREATE TRIGGER folder_delete_notes_on_delete " +
+ " AFTER DELETE ON " + TABLE.NOTE +
+ " BEGIN" +
+ " DELETE FROM " + TABLE.NOTE +
+ " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
+ " END";
/**
* 将已经被移动到回收站文件夹的文件夹中的便签也一并移动到回收站文件夹
*/
private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER =
- "CREATE TRIGGER folder_move_notes_on_trash " +
- " AFTER UPDATE ON " + TABLE.NOTE +
- " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
- " BEGIN" +
- " UPDATE " + TABLE.NOTE +
- " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
- " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
- " END";
+ "CREATE TRIGGER folder_move_notes_on_trash " +
+ " AFTER UPDATE ON " + TABLE.NOTE +
+ " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
+ " BEGIN" +
+ " UPDATE " + TABLE.NOTE +
+ " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
+ " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
+ " END";
public NotesDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java b/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java
index d7b3880..3dd6e4e 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java
@@ -29,22 +29,14 @@ 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;
+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;//定义了一个枚举类型,表示数据库表的名称。
-/**
- * @Package: net.micode.notes.data
- * @ClassName: NotesProvider
- * @Description:
- * 这个类是对ContentProvider类的扩展,功能是提供小米便签应用程序的数据,
- * 在类当中实现了数据库的增添删减修改查找操作,并且可以处理与搜索有关的查询。
- * @Author: Dong Jiaqi
- * @CreateDate: 12/23/2023 23:27 PM
- */
-public class NotesProvider extends ContentProvider {
- private static final UriMatcher mMatcher;
+
+public class NotesProvider extends ContentProvider {//android中的ContentProvider类
+ private static final UriMatcher mMatcher;//riMatcher是Android中的一个类,用于匹配URI。
private NotesDatabaseHelper mHelper;
@@ -58,70 +50,54 @@ public class NotesProvider extends ContentProvider {
private static final int URI_SEARCH = 5;
private static final int URI_SEARCH_SUGGEST = 6;
- /**
- * 定义了一个静态代码块,初始化UriMatcher对象并且添加匹配规则
- * 调用了addURI()方法,向mMatcher这一个UriMatcher对象中添加了一系列匹配规则
- */
static {
- mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ mMatcher = new UriMatcher(UriMatcher.NO_MATCH);//
+ //创建一个UriMatcher对象mMatcher,初始值为UriMatcher.NO_MATCH,表示没有任何匹配规则。
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
+ //第一个参数是authority(授权),第二个参数是路径,第三个参数是匹配的URI类型。
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);
- }
+ }//根据不同的URI路径,确定应该调用哪个处理程序来处理请求
+ //例如,当用户访问"http://example.com/note"时,mMatcher会匹配到第一个规则
/**
* x'0A' represents the '\n' character in sqlite. For title and content in the search result,
* we will trim '\n' and white space in order to show more information.
*/
- private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + ","
- + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
- + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + ","
- + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + ","
- + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + ","
- + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
- + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
-
+ private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + ","
+ + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
+ + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + ","
+ + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + ","
+ + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + ","
+ + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
+ + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
+ //用于搜索笔记的投影字段列表。这个投影字段列表可以用于构建SQL查询语句,以便在数据库中搜索和检索相关笔记。
private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
- + " FROM " + TABLE.NOTE
+ + " FROM " + TABLE.NOTE//从名为TABLE.NOTE的表中检索数据
+ " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER
+ " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
-
- /**
- * onCreate()方法的功能是在应用程序启动时进行初始化数据库帮助类
- * @return 返回true表示创建成功
- */
+ //是一个SQL查询语句,用于从数据库中检索与给定搜索条件匹配的笔记
@Override
public boolean onCreate() {
mHelper = NotesDatabaseHelper.getInstance(getContext());
return true;
}
- /**
- * query()方法用于执行查询操作,根据传入的URI参数,选择执行不同的查询语句返回
- * @param uri 要查询数据的URI,用来确定要操作的表和行
- * @param projection 表示查询返回的列的数组,可以指定查询结果中包含的列
- * @param selection 表示用于筛选的条件
- * @param selectionArgs 表示selection中的占位符的值
- * @param sortOrder 表示查询结果的排序顺序
- * @return 返回查询结果的游标(Cursor)对象(c)
- */
@Override
+ //查询uri在数据库的位置
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor c = null;
+ //获取可读数据库
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
- /**
- * 这是一个switch语句块,用来针对不同的URI进行不同的操作。
- * 对于3种类型的URI,进行了不同的操作,如果URI不匹配这任何一种情况,就视为ILLegalArgumentException异常,表示URI不被支持或不合法
- * 这个语句块的目的是为了处理不同类型的URI,并且根据URI类型执行相应的数据库查询操作,属于典型的Android ContentProvider的逻辑处理代码
- */
switch (mMatcher.match(uri)) {
+ //匹配数据库中相应条目
case URI_NOTE:
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder);
@@ -143,6 +119,7 @@ public class NotesProvider extends ContentProvider {
case URI_SEARCH:
case URI_SEARCH_SUGGEST:
if (sortOrder != null || projection != null) {
+ //异常情况
throw new IllegalArgumentException(
"do not specify sortOrder, selection, selectionArgs, or projection" + "with this query");
}
@@ -160,11 +137,6 @@ public class NotesProvider extends ContentProvider {
return null;
}
- /**
- * 这个语句块是在处理 URI_SEARCH 和 URI_SEARCH_SUGGEST 的情况下执行的,主要功能是执行数据库的原始查询(rawQuery)操作,用于搜索符合指定条件的数据,并将结果存储在 Cursor 对象中。
- * 如果在执行数据库查询时发生 IllegalStateException 异常,那么异常信息会被捕获,并通过 Log.e() 方法记录下来,方便在日志中进行查看和分析。
- * 目的是为了在执行数据库查询时,确保搜索关键词被正确地格式化并传入查询语句中,同时也确保在出现数据库查询异常时能够进行相应的异常处理和记录。
- */
try {
searchString = String.format("%%%s%%", searchString);
c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY,
@@ -182,17 +154,13 @@ public class NotesProvider extends ContentProvider {
return c;
}
- /**
- * 用于执行插入操作,根据传入的URI参数,选择在不同的表中进行插入
- * @param uri 传入数据的URI,用来确定要操作的表和行
- * @param values 表示要插入的数据集合
- * @return 返回插入数据的URI,即ContentUris.withAppendedId(uri, insertedId)
- */
@Override
+ //插入uri
public Uri insert(Uri uri, ContentValues values) {
- SQLiteDatabase db = mHelper.getWritableDatabase();
- long dataId = 0, noteId = 0, insertedId = 0;
+ SQLiteDatabase db = mHelper.getWritableDatabase();//获取可写的数据库
+ long dataId = 0, noteId = 0, insertedId = 0;//初始化
switch (mMatcher.match(uri)) {
+ //新增条目
case URI_NOTE:
insertedId = noteId = db.insert(TABLE.NOTE, null, values);
break;
@@ -208,6 +176,7 @@ public class NotesProvider extends ContentProvider {
throw new IllegalArgumentException("Unknown URI " + uri);
}
// Notify the note uri
+ //通知Android系统中的Notes应用程序,某个笔记或数据已经发生了变化
if (noteId > 0) {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null);
@@ -218,18 +187,15 @@ public class NotesProvider extends ContentProvider {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
}
-
+ //它通过调用getContentResolver().notifyChange()方法来实现这个功能。
+ //在这段代码中,首先检查noteId和dataId是否大于0,以确保它们是有效的ID。然后,使用ContentUris.withAppendedId()方法来构建对应的URI,
+ // 其中Notes.CONTENT_NOTE_URI和Notes.CONTENT_DATA_URI分别表示笔记和数据的URI。
+ // 最后,调用getContext().getContentResolver().notifyChange()方法并传入构建好的URI,以通知系统该URI所对应的资源已经发生了变化。
return ContentUris.withAppendedId(uri, insertedId);
}
- /**
- * 执行删除操作,根据传入URI参数,选择在不同的表中执行删除操作
- * @param uri 传入数据的URI,用来确定要操作的表和行
- * @param selection 表示删除的条件
- * @param selectionArgs 表示selection中的占位符的值
- * @return 返回收到影响的内容行数
- */
@Override
+ //删除一个uri,操作与上面差不多
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
@@ -266,6 +232,7 @@ public class NotesProvider extends ContentProvider {
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
+ //通知系统相关数据已经发生变化,以便进行相应的更新或处理。
if (count > 0) {
if (deleteData) {
getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
@@ -275,25 +242,13 @@ public class NotesProvider extends ContentProvider {
return count;
}
- /**
- * 执行更新操作,根据传入URI参数,在不同的表中进行更新
- * @param uri 传入数据的URI,用来确定要操作的表和行
- * @param values 表示要更新的数据集合
- * @param selection 表示用于筛选的条件
- * @param selectionArgs 表示selection中的占位符的值
- * @return 返回收到影响的行数
- */
@Override
+ //更新uri
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean updateData = false;
- /**
- * 这个语句块根据传入的 URI(Uniform Resource Identifier)进行匹配,并执行相应的操作。
- * 目的是根据传入的 URI 执行相应的数据库更新操作。根据不同的 URI,可以实现对不同表和记录的更新操作。
- * 通过 switch-case 结构,可以清晰地处理不同的情况,并执行相应的操作,同时也提供了一个默认的处理方式来处理未知的 URI。
- */
switch (mMatcher.match(uri)) {
case URI_NOTE:
increaseNoteVersion(-1, selection, selectionArgs);
@@ -328,23 +283,13 @@ public class NotesProvider extends ContentProvider {
return count;
}
- /**
- * 用于解析查询条件,将其转换为SQL语句中的WHERE子句
- * @param selection 表示用来解析的条件
- * @return 返回转换后的字符串
- */
private String parseSelection(String selection) {
return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
}
-
- /**
- * 用于增加便签的版本号
- * @param id 要增加版本号的便签的ID
- * @param selection 查询选择条件,用来筛选要增加版本号的便签
- * @param selectionArgs 表示占位符参数
- */
+ //这段代码是一个私有方法,用于增加笔记的版本号。
+ // 它接受三个参数:id(笔记的ID)、selection(查询条件)和selectionArgs(查询条件的参数)
private void increaseNoteVersion(long id, String selection, String[] selectionArgs) {
- StringBuilder sql = new StringBuilder(120);
+ StringBuilder sql = new StringBuilder(120);//sql对象,构建SQL语句
sql.append("UPDATE ");
sql.append(TABLE.NOTE);
sql.append(" SET ");
@@ -352,12 +297,14 @@ public class NotesProvider extends ContentProvider {
sql.append("=" + NoteColumns.VERSION + "+1 ");
if (id > 0 || !TextUtils.isEmpty(selection)) {
- sql.append(" WHERE ");
+ sql.append(" WHERE ");//那么在WHERE子句中添加相应的条件
}
if (id > 0) {
sql.append(NoteColumns.ID + "=" + String.valueOf(id));
+ ////将笔记ID等于给定id的条件添加到WHERE子句中
}
if (!TextUtils.isEmpty(selection)) {
+ //那么将解析后的查询条件添加到WHERE子句中。
String selectString = id > 0 ? parseSelection(selection) : selection;
for (String args : selectionArgs) {
selectString = selectString.replaceFirst("\\?", args);
@@ -368,10 +315,6 @@ public class NotesProvider extends ContentProvider {
mHelper.getWritableDatabase().execSQL(sql.toString());
}
- /**
- * 该方法根据需要自行补充实现,给开源后其他软件工程师留下了增添空间
- * @param uri 数据的URI
- */
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java
index 1699caa..3a2050b 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java
@@ -24,33 +24,13 @@ import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
-/**
- * @Package: net.micode.notes.gtask.data
- * @ClassName: MetaData
- * @Description:
- * MetaData类继承自 Task 类。它用于处理任务的元数据信息,并封装了一些操作元数据的方法。
- * 这个类用于管理任务的元数据信息,包括相关的 GID,在设置和获取元数据的同时,还提供了判断任务是否值得保存的方法,以及根据远程 JSON 数据设置任务内容的方法。
- * 同时,限制了部分方法的访问,以确保其按照预期的方式被使用。
- * @Author: Dong Jiaqi
- * @CreateDate: 12/24/2023 9:53 AM
- */
+
public class MetaData extends Task {
private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null;
- /**
- * 作用是将给定的 GID 和其他元数据信息添加到任务的注释信息中,并设置任务的名称为固定的值。
- * @param gid 表示任务的全局唯一标识符(Global Task ID),是一个字符串类型的参数。
- * @param metaInfo 表示元数据信息,是一个 JSONObject 对象,包含任务的其他相关信息。
- */
public void setMeta(String gid, JSONObject metaInfo) {
- /**
- * 这个语句块作用是向 metaInfo 这个 JSONObject 对象中添加一个键值对,其中键是 GTaskStringUtils.META_HEAD_GTASK_ID,值是变量 gid。
- * 使用了 try-catch 块来捕获可能抛出的 JSONException 异常。
- * 为什么要这么写呢:
- * 因为在 Java 中,JSONObject 的 put 方法声明了可能抛出 JSONException 异常。这意味着在调用 put 方法时,需要进行异常处理,否则会导致编译错误。因此,为了保证程序的健壮性,开发者通常会在调用可能会引发异常的方法时使用 try-catch 块进行异常处理,以防止程序异常终止。
- */
try {
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
@@ -60,29 +40,19 @@ public class MetaData extends Task {
setName(GTaskStringUtils.META_NOTE_NAME);
}
- //作用是获取任务的相关 GID,并返回其字符串形式。
public String getRelatedGid() {
- return mRelatedGid;//返回值是一个字符串类型的变量 mRelatedGid,表示相关 GID(Global Task ID)。mRelatedGid 是一个成员变量,它保存了在任务的元数据信息中提取出来的相关 GID。
+ return mRelatedGid;
}
- //作用是判断任务是否值得保存。它通过检查任务的注释信息是否为null来确定任务是否值得保存。
@Override
public boolean isWorthSaving() {
- return getNotes() != null;//如果注释信息不为null,则返回true,表示任务值得保存;反之,如果注释信息为null,则返回false,表示任务不值得保存。
+ return getNotes() != null;
}
- /**
- * 功能是从远程 JSON 对象中获取任务的内容,包括基本的任务属性和元数据信息,并将其存储到当前的 Task 对象中。
- * @param js JSONObject 对象,表示从远程服务器获取的任务信息。
- */
@Override
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
if (getNotes() != null) {
- /**
- * 这个语句块作用是从任务的注释信息中提取相关 GID,并将其保存到变量 mRelatedGid 中。
- * 使用try-catch块是为了处理可能抛出的异常,确保程序稳定性
- */
try {
JSONObject metaInfo = new JSONObject(getNotes().trim());
mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
@@ -96,7 +66,7 @@ public class MetaData extends Task {
@Override
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
- throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");//抛出一个IllegalAccessError异常,并且提供异常的详细描述信息
+ throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
@Override
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java
index c2a5253..63950e0 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java
@@ -20,33 +20,24 @@ import android.database.Cursor;
import org.json.JSONObject;
-/**
- * @Package: net.micode.notes.gtask.data
- * @ClassName: Node
- * @Description:
- * Node类是一个抽象类,定义了一些常量字段以及一些方法,还定义了节点对象的基本属性和操作,
- * * 同时提供了抽象方法来处理节点内容的设置和同步操作的创建按,以及普通方法来设置和获取节点的属性。
- * @Author: Dong Jiaqi
- * @CreateDate: 12/24/2023 10:23 AM
- */
public abstract class Node {
- public static final int SYNC_ACTION_NONE = 0;//表示没有同步操作。
+ public static final int SYNC_ACTION_NONE = 0;
- public static final int SYNC_ACTION_ADD_REMOTE = 1;//表示远程添加操作。
+ public static final int SYNC_ACTION_ADD_REMOTE = 1;
- public static final int SYNC_ACTION_ADD_LOCAL = 2;//表示本地添加操作。
+ 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_REMOTE = 3;
- public static final int SYNC_ACTION_DEL_LOCAL = 4;//表示本地删除操作。
+ 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_REMOTE = 5;
- public static final int SYNC_ACTION_UPDATE_LOCAL = 6;//表示本地更新操作。
+ public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
- public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;//表示更新冲突操作。
+ public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
- public static final int SYNC_ACTION_ERROR = 8;//表示同步错误操作。
+ public static final int SYNC_ACTION_ERROR = 8;
private String mGid;
@@ -75,66 +66,34 @@ public abstract class Node {
public abstract int getSyncAction(Cursor c);
- /**
- * 设置节点对象的全局唯一标识符(gid)。
- * @param gid 表示要设置的全局唯一标识符,它是一个字符串类型的参数。可以是任意有效的字符串,用于对节点进行唯一标识和区分。
- */
public void setGid(String gid) {
this.mGid = gid;
}
- /**
- * 设置节点对象的名称。它通过将传入的字符串参数 name 赋值给节点对象的成员变量 mName 来实现。
- * @param name 表示要设置的节点名称,它是一个字符串类型的参数。可以是任意有效的字符串,用于标识节点的名称或描述。
- */
public void setName(String name) {
this.mName = name;
}
- /**
- * 设置节点对象的最后修改时间。它通过将传入的长整型参数 lastModified 赋值给节点对象的成员变量 mLastModified 来实现。
- * @param lastModified 表示要设置的节点的最后修改时间,它是一个长整型参数,用来记录节点对象的最后修改时间
- */
public void setLastModified(long lastModified) {
this.mLastModified = lastModified;
}
- /**
- * 设置节点对象的删除状态。它通过将传入的布尔类型参数 deleted 赋值给节点对象的成员变量 mDeleted 来实现。
- * @param deleted 表示要设置的节点的删除状态,它是一个布尔类型的参数。当该参数为 true 时,表示节点被标记为已删除;当该参数为 false 时,表示节点未被删除。
- */
public void setDeleted(boolean deleted) {
this.mDeleted = deleted;
}
- /**
- * 获取节点对象的全局唯一标识符(gid)。它通过返回节点对象的成员变量 mGid 的值来实现。
- * @return this.mGid表示节点的全局唯一标识符。这是一个字符串类型的返回值,用于表示节点对象的唯一标识符。
- */
public String getGid() {
return this.mGid;
}
- /**
- * 获取节点对象的名称。它通过返回节点对象的成员变量 mName 的值来实现。
- * @return this.mName表示节点的名称。这是一个字符串类型的返回值,用于表示节点对象的名称或描述。
- */
public String getName() {
return this.mName;
}
- /**
- * 获取节点对象的最后修改时间。它通过返回节点对象的成员变量 mLastModified 的值来实现。
- * @return this.mLastModified表示节点的最后修改时间。这是一个长整型的返回值
- */
public long getLastModified() {
return this.mLastModified;
}
- /**
- * 获取节点对象的删除状态。它通过返回节点对象的成员变量 mDeleted 的布尔值来实现。
- * @return 表示节点的删除状态。当返回值为 true 时,表示节点已被标记为已删除;当返回值为 false 时,表示节点未被删除。
- */
public boolean getDeleted() {
return this.mDeleted;
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java
index 60f3022..d3ec3be 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java
@@ -34,33 +34,26 @@ import net.micode.notes.gtask.exception.ActionFailureException;
import org.json.JSONException;
import org.json.JSONObject;
-/**
- * @Package: net.micode.notes.gtask.data
- * @ClassName: SqlData
- * @Description:
- * 封装了对数据库中数据的读取、更新和提交操作,可以用于管理和操作数据库中的数据。
- * @Author: Dong Jiaqi
- * @CreateDate: 12/24/2023 10:58 AM
- */
+
public class SqlData {
private static final String TAG = SqlData.class.getSimpleName();
- private static final int INVALID_ID = -99999;//定义了一个名为 INVALID_ID 的私有静态整型常量,并赋值为 -99999,被用来表示无效的 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
- };//定义了一个名为 PROJECTION_DATA 的字符串数组,其中包含了一组列名
+ };
- public static final int DATA_ID_COLUMN = 0;//表示数据的 ID 在数据列中的索引位置,即第一列。
+ public static final int DATA_ID_COLUMN = 0;
- public static final int DATA_MIME_TYPE_COLUMN = 1;//表示数据的 MIME 类型在数据列中的索引位置,即第二列。
+ public static final int DATA_MIME_TYPE_COLUMN = 1;
- public static final int DATA_CONTENT_COLUMN = 2;//表示数据的内容在数据列中的索引位置,即第三列。
+ public static final int DATA_CONTENT_COLUMN = 2;
- public static final int DATA_CONTENT_DATA_1_COLUMN = 3;//表示数据的内容数据1在数据列中的索引位置,即第四列。
+ public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
- public static final int DATA_CONTENT_DATA_3_COLUMN = 4;//表示数据的内容数据3在数据列中的索引位置,即第五列。
+ public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
private ContentResolver mContentResolver;
@@ -78,54 +71,36 @@ public class SqlData {
private ContentValues mDiffDataValues;
- /**
- * 构造函数,接收一个Context对象作为参数,并初始化成员变量。
- * @param context 用于获取应用程序的上下文信息,以便后续操作数据库。
- */
public SqlData(Context context) {
- mContentResolver = context.getContentResolver();//这是构造方法的定义,表明这是一个公共的构造方法,并且接受一个 Context 类型的参数。
+ mContentResolver = context.getContentResolver();
mIsCreate = true;
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
- mDataContent = "";//成员变量初始化
+ mDataContent = "";
mDataContentData1 = 0;
mDataContentData3 = "";
- mDiffDataValues = new ContentValues();//创建新的ContentValues对象
+ mDiffDataValues = new ContentValues();
}
- /**
- * 构造函数,接收一个Context对象和一个Cursor对象作为参数,并根据Cursor对象加载成员变量的值。
- * @param context 用于获取应用程序的上下文信息,以便后续操作数据库;
- * @param c Cursor 对象用于获取数据库中的数据。
- */
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
- loadFromCursor(c);//调用 loadFromCursor() 方法,将传入的 Cursor 对象作为参数,以从 Cursor 对象中加载数据库中的数据到 SqlData 对象的成员变量中。
+ loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
- /**
- * 从传入的 Cursor 对象中加载数据,并将数据赋值给 SqlData 对象的各个成员变量。
- * @param c Cursor 对象用于获取数据库中的数据
- */
private void loadFromCursor(Cursor c) {
- mDataId = c.getLong(DATA_ID_COLUMN);//从 Cursor 对象中获取指定列索引为 DATA_ID_COLUMN 的长整型数据,并赋值给 mDataId 成员变量。
- mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);//从 Cursor 对象中获取指定列索引为 DATA_MIME_TYPE_COLUMN 的字符串数据,并赋值给 mDataMimeType 成员变量。
+ 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);
}
- /**
- * 根据传入的JSON对象设置成员变量的值。根据JSON对象中的字段值判断是否需要更新成员变量,并将需要更新的值存储在mDiffDataValues对象中。
- * @param js JSONObject对象用于获取数据
- * @throws JSONException 抛出的异常
- */
public void setContent(JSONObject js) throws JSONException {
- long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;//检查 JSON 对象 js 中是否包含名为 DataColumns.ID 的字段,如果包含则将其转换为 long 类型并赋给 dataId,否则将 INVALID_ID 赋给 dataId。
- if (mIsCreate || mDataId != dataId) {//检查是否正在创建新数据(mIsCreate 为 true),或者已有数据的 dataId 是否与新获取的 dataId 不同。
- mDiffDataValues.put(DataColumns.ID, dataId);//如果满足条件,则将 DataColumns.ID 和对应的 dataId 放入 mDiffDataValues 中。
+ long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
+ if (mIsCreate || mDataId != dataId) {
+ mDiffDataValues.put(DataColumns.ID, dataId);
}
mDataId = dataId;
@@ -155,53 +130,42 @@ public class SqlData {
mDataContentData3 = dataContentData3;
}
- /**
- * 将成员变量的值转换为JSON对象并返回。
- * @return JSONObject 对象包含了 SqlData 对象中各个成员变量的值,使用相应的键值表示。如果当前对象是新创建的,则打印错误日志并返回 null。
- * @throws JSONException 抛出的异常
- */
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
JSONObject js = new JSONObject();
- js.put(DataColumns.ID, mDataId);//将类的成员变量 mDataId 的值存储到 js 对象中,使用键名 DataColumns.ID。
- js.put(DataColumns.MIME_TYPE, mDataMimeType);//将类的成员变量 mDataMimeType 的值存储到 js 对象中,使用键名 DataColumns.MIME_TYPE
+ js.put(DataColumns.ID, mDataId);
+ js.put(DataColumns.MIME_TYPE, mDataMimeType);
js.put(DataColumns.CONTENT, mDataContent);
js.put(DataColumns.DATA1, mDataContentData1);
js.put(DataColumns.DATA3, mDataContentData3);
return js;
}
- /**
- * 提交数据的更改到数据库中。如果是新创建的数据,则将数据插入数据库并获取其ID;如果是已存在的数据,则根据mDiffDataValues对象中的差异字段值更新数据库中对应的记录。
- * @param noteId 便签的ID,表示要提交数据的便签的ID
- * @param validateVersion 布尔值,表示是否需要验证版本号
- * @param version 长整型数,表示版本号
- */
public void commit(long noteId, boolean validateVersion, long version) {
- if (mIsCreate) {//如果数据是新创建的
+ if (mIsCreate) {
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
mDiffDataValues.remove(DataColumns.ID);
}
- mDiffDataValues.put(DataColumns.NOTE_ID, noteId); //设置便签的ID
- Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);//向数据库中插入数据
+ mDiffDataValues.put(DataColumns.NOTE_ID, noteId);
+ Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);
try {
mDataId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString());
throw new ActionFailureException("create note failed");
}
- } else {//如果不是新创建的数据
+ } else {
if (mDiffDataValues.size() > 0) {
int result = 0;
- if (!validateVersion) {//如果不用验证版本,直接更新数据
+ if (!validateVersion) {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
- } else {//如果要验证版本,根据版本号更新数据
+ } else {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
" ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE
@@ -215,14 +179,10 @@ public class SqlData {
}
}
- mDiffDataValues.clear();//提交后清空数据
+ mDiffDataValues.clear();
mIsCreate = false;
}
- /**
- * 返回成员变量mDataId的值。
- * @return 成员信息的ID
- */
public long getId() {
return mDataId;
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java
index d2ebbd3..1d0f45b 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java
@@ -37,14 +37,7 @@ import org.json.JSONObject;
import java.util.ArrayList;
-/**
- * @Package: net.micode.notes.gtask.data
- * @ClassName: SqlNote
- * @Description:
- * SqlNote类包含用于处理小米便签的数据库操作,是一个用于管理便签数据的工具类
- * @Author: Dong Jiaqi
- * @CreateDate: 12/24/2023 17:18 PM
- */
+
public class SqlNote {
private static final String TAG = SqlNote.class.getSimpleName();
@@ -59,9 +52,9 @@ public class SqlNote {
NoteColumns.VERSION
};
- public static final int ID_COLUMN = 0;//便签的ID列的索引为0
+ public static final int ID_COLUMN = 0;
- public static final int ALERTED_DATE_COLUMN = 1;//提醒日期列的索引为1
+ public static final int ALERTED_DATE_COLUMN = 1;
public static final int BG_COLOR_ID_COLUMN = 2;
@@ -127,12 +120,8 @@ public class SqlNote {
private ContentValues mDiffNoteValues;
- private ArrayList mDataList;//用Java中的ArrayList类定义了一个SqlData对象 mDataList,用于存储从数据库查询中返回的便签数据
+ private ArrayList mDataList;
- /**
- * 构造方法,用来创建一个新的SqlNote对象,初始化新的 SqlNote 对象,并将其成员变量设置为默认值。
- * @param context 要使用到的上下文对象
- */
public SqlNote(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
@@ -154,50 +143,33 @@ public class SqlNote {
mDataList = new ArrayList();
}
- /**
- * 另外一个构造方法,用于创建一个新的 SqlNote 对象,并从给定的 Cursor 中加载数据。
- * @param context 要使用的上下文对象
- * @param c 要加载数据的游标对象
- */
public SqlNote(Context context, Cursor c) {
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(c);
mDataList = new ArrayList();
- if (mType == Notes.TYPE_NOTE)
+ if (mType == Notes.TYPE_NOTE) {
loadDataContent();
+ }
mDiffNoteValues = new ContentValues();
}
- /**
- * 另一个构造方法,用于创建一个新的 SqlNote 对象,并从给定的 ID 加载数据。
- * @param context 要使用的上下文对象
- * @param id 要加载数据的便签的ID
- */
public SqlNote(Context context, long id) {
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(id);
mDataList = new ArrayList();
- if (mType == Notes.TYPE_NOTE)
+ if (mType == Notes.TYPE_NOTE) {
loadDataContent();
+ }
mDiffNoteValues = new ContentValues();
}
- /**
- * 通过笔记 ID 从数据库中加载便签数据,并将其存储在 SqlNote 对象的成员变量中
- * @param id 要加载数据的便签 ID
- */
private void loadFromCursor(long id) {
Cursor c = null;
- /**
- * try-finally语句块 用于在加载笔记数据后正确地关闭游标,以确保资源的释放。
- * 这么写是为了避免在发生异常或错误时,游标未被关闭而导致资源泄漏。
- * 通过在 finally 块中关闭游标,可以确保无论查询是否成功,都会正确地释放资源。
- */
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",
new String[] {
@@ -210,15 +182,12 @@ public class SqlNote {
Log.w(TAG, "loadFromCursor: cursor = null");
}
} finally {
- if (c != null)
+ if (c != null) {
c.close();
+ }
}
}
- /**
- * 从游标中加载便签数据,并将其存储在 SqlNote 对象的成员变量中。
- * @param c 要从中加载数据的游标
- */
private void loadFromCursor(Cursor c) {
mId = c.getLong(ID_COLUMN);
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
@@ -234,17 +203,9 @@ public class SqlNote {
mVersion = c.getLong(VERSION_COLUMN);
}
- /**
- * 根据特定笔记 ID 加载与之关联的数据内容,并将其存储在数据列表中供进一步操作和展示。
- * 通过查询数据库,遍历游标并创建相应的数据对象,可以方便地加载数据内容并进行后续处理。
- */
private void loadDataContent() {
Cursor c = null;
mDataList.clear();
- /**
- * 从数据库中查询与指定笔记 ID 相关联的数据内容,并将查询结果存储在 mDataList 列表中。
- * 这种写法可以保证在出现异常时,也能正确地关闭游标,避免资源泄露和其他问题。
- */
try {
c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA,
"(note_id=?)", new String[] {
@@ -263,24 +224,13 @@ public class SqlNote {
Log.w(TAG, "loadDataContent: cursor = null");
}
} finally {
- if (c != null)
+ if (c != null) {
c.close();
+ }
}
}
-
- /**
- * 根据传入的JSONObject对象设置内容。
- * 根据JSONObject中的不同字段值更新类中的属性,并将差异值存储在mDiffNoteValues中。
- * @param js 包含要设置的内容的JSONObject对象。
- * @return 如果成功设置内容,则返回true;否则返回false
- */
public boolean setContent(JSONObject js) {
- /**
- * try块中的代码用于解析JSON对象并获取其中的数据。如果解析过程中发生了JSONException异常,那么程序会跳转到catch块中,并执行其中的代码。
- * catch块中的代码主要用于打印异常信息并返回一个布尔值false,以表示解析失败。
- * 这样能够通过捕获异常并进行适当的处理,可以避免程序崩溃或产生不可预料的结果。
- */
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
@@ -291,14 +241,14 @@ public class SqlNote {
.getString(NoteColumns.SNIPPET) : "";
if (mIsCreate || !mSnippet.equals(snippet)) {
mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);
- }//判断是否需要更新笔记的摘要(snippet)。它通过比较当前对象的mSnippet属性和传入的参数snippet,如果两者不相等,则将新的摘要值存储在mDiffNoteValues中。
+ }
mSnippet = snippet;
int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE)
: Notes.TYPE_NOTE;
if (mIsCreate || mType != type) {
mDiffNoteValues.put(NoteColumns.TYPE, type);
- }//检查是否正在创建新的笔记(mIsCreate为true),或者当前笔记的类型与传入的类型值不相等(mType != type)。如果满足其中一个条件,就会将新的类型值存储在mDiffNoteValues中。
+ }
mType = type;
} else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) {
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
@@ -413,10 +363,6 @@ public class SqlNote {
return true;
}
- /**
- * 将当前对象的属性值转换为一个JSON对象并返回。
- * @return 返回转换后的JSONObject对象作为结果
- */
public JSONObject getContent() {
try {
JSONObject js = new JSONObject();
@@ -465,74 +411,39 @@ public class SqlNote {
return null;
}
- /**
- * 设置当前对象的父级ID属性,并将该属性的值存储到mDiffNoteValues中。
- * @param id long类型,表示要设置的父级ID
- */
public void setParentId(long id) {
mParentId = id;
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
- /**
- * 将指定的Google Tasks任务的ID(gid)放入mDiffNoteValues中,以便后续判断属性变化时进行处理。
- * @param gid 字符串类型,表示要设置的Google Tasks任务的ID
- */
public void setGtaskId(String gid) {
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
- /**
- * 将指定的同步ID(syncId)放入mDiffNoteValues中,以便后续判断属性变化时进行处理。
- * @param syncId long类型,表示要设置的同步ID
- */
public void setSyncId(long syncId) {
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
}
- /**
- * 将当前对象的本地修改状态重置为未修改。
- */
public void resetLocalModified() {
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
}
- /**
- * 获取当前对象ID属性值,将其作为结果返回
- * @return 当前对象的ID属性值
- */
public long getId() {
return mId;
}
- /**
- * 获取当前对象的父级ID属性值,并返回该值。
- * @return 当前对象的父级ID属性值
- */
public long getParentId() {
return mParentId;
}
- /**
- * 获取当前对象的摘要属性值,并返回该值。
- * @return 当前对象的摘要属性值
- */
public String getSnippet() {
return mSnippet;
}
- /**
- * 判断当前对象是否为“便签”类型。
- * @return 布尔类型的数据,表示当前对象是否为“便签”类型。如果是便签类型,则返回true;否则返回false。
- */
public boolean isNoteType() {
return mType == Notes.TYPE_NOTE;
}
- /**
- * 将当前对象所代表的笔记或文件夹信息提交到数据库中进行保存,并更新当前对象的属性值。
- * @param validateVersion 布尔类型的数据,表示是否需要验证版本信息。如果为true,则在更新时需要比较版本号;否则不需要比较版本号。
- */
public void commit(boolean validateVersion) {
if (mIsCreate) {
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
@@ -589,8 +500,9 @@ public class SqlNote {
// refresh local info
loadFromCursor(mId);
- if (mType == Notes.TYPE_NOTE)
+ if (mType == Notes.TYPE_NOTE) {
loadDataContent();
+ }
mDiffNoteValues.clear();
mIsCreate = false;
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Task.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Task.java
index 4fd9506..6a19454 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Task.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Task.java
@@ -31,16 +31,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
-/**
- * @Package: net.micode.notes.gtask.data
- * @ClassName: Task
- * @Description:
- * Task类继承自Node类。该类用于表示一个任务,在Google任务管理系统中使用。
- * 它包含了一些任务的属性和方法,例如任务是否已完成、笔记内容、元数据等。
- * 另外,该类还提供了一些用于生成和解析JSON格式数据的方法,以便与Google任务管理系统进行交互。
- * @Author: Dong Jiaqi
- * @CreateDate: 12/24/2023 19:48 PM
- */
+
public class Task extends Node {
private static final String TAG = Task.class.getSimpleName();
@@ -54,27 +45,17 @@ public class Task extends Node {
private TaskList mParent;
- /**
- * 构造方法在对象创建时被调用,用于初始化对象的属性。
- * 所有属性都被初始化为初始值或者null。
- */
public Task() {
- super();//调用父类Node的构造方法确保父类的属性得到正确初始化
- mCompleted = false;//任务完成状态设置为未完成
- mNotes = null;//暂时没有便签笔记
- mPriorSibling = null;//当前任务没有前节点
- mParent = null;//当前任务没有父节点
- mMetaInfo = null;//当前任务没有元数据信息
+ super();
+ mCompleted = false;
+ mNotes = null;
+ mPriorSibling = null;
+ mParent = null;
+ mMetaInfo = null;
}
- /**
- * 用于生成一个表示创建任务操作的JSON对象。
- * 如果在生成JSON对象的过程中发生异常,将会抛出一个ActionFailureException异常,并打印错误信息。
- * @param actionId 表示操作的唯一标识符。
- * @return 生成的JSONObject对象,包含了表示创建任务操作的各个字段和对应的值。
- */
public JSONObject getCreateAction(int actionId) {
- JSONObject js = new JSONObject();//创建一个空的JSONObject对象。
+ JSONObject js = new JSONObject();
try {
// action_type
@@ -116,17 +97,12 @@ public class Task extends Node {
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
- throw new ActionFailureException("fail to generate task-create jsonobject");//抛出异常
+ throw new ActionFailureException("fail to generate task-create jsonobject");
}
return js;
}
- /**
- * 用于生成一个表示更新任务操作的JSON对象。
- * @param actionId 表示操作的唯一标识符。
- * @return 生成的JSONObject对象,包含了表示更新任务操作的各个字段和对应的值。
- */
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
@@ -159,11 +135,6 @@ public class Task extends Node {
return js;
}
- /**
- * 用于根据传入的JSONObject对象设置任务的各个字段值。
- * 保持任务对象的状态与传入的JSON数据一致。
- * @param js 表示一个JSONObject对象,包含了任务的各个字段和对应的值。
- */
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
@@ -204,25 +175,17 @@ public class Task extends Node {
}
}
- /**
- * 用于根据传入的本地JSONObject对象设置任务的名称,从而与本地数据保持一致。
- * @param js 包含了本地数据的各个字段和对应的值。
- */
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
- /**
- * 根据传入的JSONObject对象解析任务的名称字段,并将其设置为任务对象的名称。
- * 同时,还会检查便签的类型,只有当类型为普通便签时才会继续设置任务名称。
- */
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
- if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) {//检查便签类型是不是普通便签
+ if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) {
Log.e(TAG, "invalid type");
return;
}
@@ -241,11 +204,6 @@ public class Task extends Node {
}
}
- /**
- * 根据任务对象的内容生成一个本地的JSONObject对象。
- * @return 对于新创建的任务:返回构造好的JSONObject对象js。
- * 对于已同步的任务:返回mMetaInfo对象本身。
- */
public JSONObject getLocalJSONFromContent() {
String name = getName();
try {
@@ -289,10 +247,6 @@ public class Task extends Node {
}
}
- /**
- * 设置任务的元数据。
- * @param metaData MetaData对象,表示任务的元数据。
- */
public void setMetaInfo(MetaData metaData) {
if (metaData != null && metaData.getNotes() != null) {
try {
@@ -304,16 +258,6 @@ public class Task extends Node {
}
}
- /**
- * 根据传入的Cursor对象和任务的元数据判断同步操作的类型。
- * @param c Cursor对象c,用于查询本地数据库中的任务数据。
- * @return 整数,表示同步操作的类型
- * SYNC_ACTION_NONE:无需同步
- * SYNC_ACTION_UPDATE_LOCAL:需要更新本地任务
- * SYNC_ACTION_UPDATE_REMOTE:需要更新远程任务
- * SYNC_ACTION_UPDATE_CONFLICT:存在冲突,需要解决
- * SYNC_ACTION_ERROR:同步出错
- */
public int getSyncAction(Cursor c) {
try {
JSONObject noteInfo = null;
@@ -367,80 +311,39 @@ public class Task extends Node {
return SYNC_ACTION_ERROR;
}
- /**
- * 判断当前任务是否值得保存。
- * @return 类型为boolean,true表示任务值得保存,false表示任务不值得保存。
- */
public boolean isWorthSaving() {
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|| (getNotes() != null && getNotes().trim().length() > 0);
}
- /**
- * 设置当前任务的完成状态。
- * 调用这个方法,可以更新当前任务的完成状态,以便在应用程序中进行相应的展示或处理。
- * @param completed boolean类型的参数,用来表示当前任务的完成状态。
- */
public void setCompleted(boolean completed) {
this.mCompleted = completed;
}
- /**
- * 设置当前任务的备注信息。
- * 调用这个方法,可以更新当前任务的备注信息,以便在应用程序中进行相应的展示或处理。
- * @param notes String类型的参数,用来表示当前任务的备注信息。
- */
public void setNotes(String notes) {
this.mNotes = notes;
}
- /**
- * 设置当前任务的前一个兄弟任务。
- * 调用这个方法,可以建立任务之间的关联关系,例如设置任务的顺序、父子关系等。
- * @param priorSibling Task类型的参数,表示当前任务的前一个兄弟任务。
- */
public void setPriorSibling(Task priorSibling) {
this.mPriorSibling = priorSibling;
}
- /**
- * 设置当前任务的父任务列表。
- * 调用这个方法,可以建立任务之间的关联关系,例如设置任务的层级结构、父子关系等。
- * @param parent TaskList类型的参数,表示当前任务所属的父任务列表。
- */
public void setParent(TaskList parent) {
this.mParent = parent;
}
- /**
- * 获取当前任务的完成状态。
- * 调用这个方法,可以获取当前任务是否已经完成,以便在应用程序中进行相应的展示或处理。
- * @return 类型为boolean,true表示任务已完成,false表示任务未完成。
- */
public boolean getCompleted() {
return this.mCompleted;
}
- /**
- * 获取当前任务的备注信息。
- * @return 类型为String,表示当前任务的备注信息。如果任务没有备注信息,则返回一个空字符串。
- */
public String getNotes() {
return this.mNotes;
}
- /**
- * 获取当前任务的前一个兄弟任务。
- * @return 类型为Task,表示当前任务的前一个兄弟任务。如果当前任务没有前一个兄弟任务,则返回null。
- */
public Task getPriorSibling() {
return this.mPriorSibling;
}
- /**
- * 获取当前任务所属的父任务列表。
- * @return 类型为TaskList,表示当前任务所属的父任务列表。如果当前任务没有父任务列表,则返回null。
- */
public TaskList getParent() {
return this.mParent;
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/TaskList.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/TaskList.java
index b3d810b..cd71d29 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/TaskList.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/TaskList.java
@@ -30,36 +30,19 @@ import org.json.JSONObject;
import java.util.ArrayList;
-/**
- * @Package: net.micode.notes.gtask.data
- * @ClassName: TaskList
- * @Description:
- * TaskList继承自Node类。该类表示一个任务列表,具有管理任务列表及其子任务的功能。
- * 提供了创建、更新、删除任务列表以及管理子任务的方法,可以通过JSON对象进行远程和本地数据的转换,并提供了一系列对子任务进行操作的方法。
- * @Author: Dong Jiaqi
- * @CreateDate: 12/24/2023 20:48 PM
- */
public class TaskList extends Node {
- private static final String TAG = TaskList.class.getSimpleName();//私有静态常量,用于在日志和调试中标识类名。
+ private static final String TAG = TaskList.class.getSimpleName();
- private int mIndex;//私有整型变量,表示任务列表的索引。
+ private int mIndex;
- private ArrayList mChildren;//私有ArrayList,存储Task对象,表示该任务列表下的子任务列表。
+ private ArrayList mChildren;
- /**
- * 构造方法,初始化一个空的任务列表,初始化mChildren为一个空的Task列表,将mIndex设置为1。
- */
public TaskList() {
super();
mChildren = new ArrayList();
mIndex = 1;
}
- /**
- * 根据给定的actionId创建一个用于创建任务列表的JSONObject对象。
- * @param actionId 整型参数,表示操作的ID。
- * @return 表示创建操作的JSONObject对象。
- */
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject();
@@ -91,11 +74,6 @@ public class TaskList extends Node {
return js;
}
- /**
- * 根据给定的actionId创建一个用于更新任务列表的JSONObject对象。
- * @param actionId 整型参数,表示操作的ID。
- * @return 表示更新操作的JSONObject对象。
- */
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
@@ -125,10 +103,6 @@ public class TaskList extends Node {
return js;
}
- /**
- * 根据远程传入的JSON对象设置任务列表的内容。
- * @param js 表示从远程服务器返回的JSONObject对象,包含了任务列表的属性。
- */
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
@@ -155,10 +129,6 @@ public class TaskList extends Node {
}
}
- /**
- * 根据本地JSON对象设置任务列表的内容。
- * @param js 表示从远程服务器返回的JSONObject对象,包含了任务列表的属性。
- */
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
@@ -171,13 +141,14 @@ public class TaskList extends Node {
String name = folder.getString(NoteColumns.SNIPPET);
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + name);
} else if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
- if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER)
+ if (folder.getLong(NoteColumns.ID) == Notes.ID_ROOT_FOLDER) {
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT);
- else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER)
+ } else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER) {
setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX
+ GTaskStringUtils.FOLDER_CALL_NOTE);
- else
+ } else {
Log.e(TAG, "invalid system folder");
+ }
} else {
Log.e(TAG, "error type");
}
@@ -187,10 +158,6 @@ public class TaskList extends Node {
}
}
- /**
- * 根据任务列表的内容生成本地JSON对象。
- * @return 表示本地的JSONObject对象,包含了任务列表的属性信息。
- */
public JSONObject getLocalJSONFromContent() {
try {
JSONObject js = new JSONObject();
@@ -217,17 +184,6 @@ public class TaskList extends Node {
}
}
- /**
- * 根据数据库游标中的信息确定同步操作的类型。
- * @param c 表示一个Cursor对象,包含了当前任务列表的属性信息。
- * @return 表示同步操作的代码
- * SYNC_ACTION_NONE(不执行任何操作)
- * SYNC_ACTION_UPDATE_LOCAL(更新本地)
- * SYNC_ACTION_ERROR(同步操作出错)
- * SYNC_ACTION_UPDATE_REMOTE(当前任务列表的同步ID是否与最后修改时间相同,更新远程)
- * SYNC_ACTION_UPDATE_REMOTE(当前任务列表的同步ID是否与最后修改时间不相同,更新远程)
- * SYNC_ACTION_ERROR(同步操作出错)
- */
public int getSyncAction(Cursor c) {
try {
if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
@@ -261,19 +217,10 @@ public class TaskList extends Node {
return SYNC_ACTION_ERROR;
}
- /**
- * 获取子任务的数量。
- * @return 子任务的数量
- */
public int getChildTaskCount() {
return mChildren.size();
}
- /**
- * 向任务列表中添加一个子任务。
- * @param task 表示要添加的子任务
- * @return boolean:表示是否成功将子任务添加到当前任务中,如果添加成功则返回true,否则返回false
- */
public boolean addChildTask(Task task) {
boolean ret = false;
if (task != null && !mChildren.contains(task)) {
@@ -288,12 +235,6 @@ public class TaskList extends Node {
return ret;
}
- /**
- * 在指定位置添加一个子任务。
- * @param task 表示要插入的子任务。
- * @param index 表示要插入的位置索引,从0开始计数。
- * @return boolean:表示是否成功将子任务插入到当前任务中的指定位置,如果插入成功则返回true,否则返回false。
- */
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
@@ -320,11 +261,6 @@ public class TaskList extends Node {
return true;
}
- /**
- * 从任务列表中移除一个子任务。
- * @param task 表示要移除的子任务
- * @return boolean:表示是否成功从当前任务中移除了指定的子任务,如果移除成功则返回true,否则返回false。
- */
public boolean removeChildTask(Task task) {
boolean ret = false;
int index = mChildren.indexOf(task);
@@ -346,12 +282,6 @@ public class TaskList extends Node {
return ret;
}
- /**
- * 移动指定子任务到新的位置。
- * @param task 表示要移动的子任务
- * @param index 表示要移动到的位置索引,从0开始计数。
- * @return boolean:表示是否成功将子任务移动到指定位置,如果移动成功则返回true,否则返回false
- */
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) {
@@ -370,11 +300,6 @@ public class TaskList extends Node {
return (removeChildTask(task) && addChildTask(task, index));
}
- /**
- * 根据全局唯一标识符查找子任务。
- * @param gid 表示要查找的子任务的gid(全局唯一标识符)
- * @return Task:如果找到具有匹配gid的子任务,则返回该子任务对象;如果未找到匹配的子任务,则返回null
- */
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
@@ -385,20 +310,10 @@ public class TaskList extends Node {
return null;
}
- /**
- * 获取指定子任务在任务列表中的索引。
- * @param task 表示要获取索引位置的子任务对象。
- * @return int:表示指定子任务在当前任务的子任务列表中的索引位置,如果子任务存在于列表中则返回其索引位置(从0开始计数),如果子任务不存在于列表中则返回-1。
- */
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
- /**
- * 根据索引获取子任务。
- * @param index 表示要获取子任务的索引位置,从0开始计数。
- * @return Task:表示位于指定索引位置的子任务对象,如果索引位置有效则返回该子任务对象,否则返回null。
- */
public Task getChildTaskByIndex(int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
@@ -407,11 +322,6 @@ public class TaskList extends Node {
return mChildren.get(index);
}
- /**
- * 根据全局唯一标识符获取子任务。
- * @param gid 表示要查找的子任务的gid
- * @return Task:如果找到具有匹配gid的子任务,则返回匹配的子任务对象;如果未找到匹配的子任务,则返回null
- */
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
if (task.getGid().equals(gid))
@@ -420,26 +330,14 @@ public class TaskList extends Node {
return null;
}
- /**
- * 获取任务列表的子任务列表。
- * @return ArrayList:表示当前任务的子任务列表,即包含所有子任务的ArrayList对象。
- */
public ArrayList getChildTaskList() {
return this.mChildren;
}
- /**
- * 设置任务列表的索引。
- * @param index 表示要设置的索引值
- */
public void setIndex(int index) {
this.mIndex = index;
}
- /**
- * 获取任务列表的索引。
- * @return 表示当前对象的索引值
- */
public int getIndex() {
return this.mIndex;
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java
index 4044e44..2a1ca23 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java
@@ -352,9 +352,9 @@ public class GTaskClient {
}
InputStream input = entity.getContent();
- if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
+ if (contentEncoding != null && "gzip".equalsIgnoreCase(contentEncoding)) {
input = new GZIPInputStream(entity.getContent());
- } else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) {
+ } else if (contentEncoding != null && "deflate".equalsIgnoreCase(contentEncoding)) {
Inflater inflater = new Inflater(true);
input = new InflaterInputStream(entity.getContent(), inflater);
}
@@ -520,8 +520,9 @@ public class GTaskClient {
commitUpdate();
}
- if (mUpdateArray == null)
+ if (mUpdateArray == null) {
mUpdateArray = new JSONArray();
+ }
mUpdateArray.put(node.getUpdateAction(getActionId()));
}
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java
index ffb8566..4b1c4f6 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java
@@ -206,8 +206,9 @@ public class GTaskManager {
*@return void
*/
private void initGTaskList() throws NetworkFailureException {
- if (mCancelled)
+ if (mCancelled) {
return;
+ }
//getInstance即为创建一个实例,client应指远端客户机,用于与远程服务器进行通信
GTaskClient client = GTaskClient.getInstance();
try {
@@ -461,8 +462,9 @@ public class GTaskManager {
mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid);
// for system folder, only update remote name if necessary
if (!node.getName().equals(
- GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT))
+ GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) {
doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c);
+ }
} else {
doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c);
}
@@ -494,8 +496,9 @@ public class GTaskManager {
// necessary
if (!node.getName().equals(
GTaskStringUtils.MIUI_FOLDER_PREFFIX
- + GTaskStringUtils.FOLDER_CALL_NOTE))
+ + GTaskStringUtils.FOLDER_CALL_NOTE)) {
doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c);
+ }
} else {
doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c);
}
@@ -558,8 +561,9 @@ public class GTaskManager {
}
}
- if (!mCancelled)
+ if (!mCancelled) {
GTaskClient.getInstance().commitUpdate();
+ }
}
/**
@@ -769,12 +773,13 @@ public class GTaskManager {
// we need to skip folder if it has already existed
String folderName = GTaskStringUtils.MIUI_FOLDER_PREFFIX;
- if (sqlNote.getId() == Notes.ID_ROOT_FOLDER)
+ if (sqlNote.getId() == Notes.ID_ROOT_FOLDER) {
folderName += GTaskStringUtils.FOLDER_DEFAULT;
- else if (sqlNote.getId() == Notes.ID_CALL_RECORD_FOLDER)
+ } else if (sqlNote.getId() == Notes.ID_CALL_RECORD_FOLDER) {
folderName += GTaskStringUtils.FOLDER_CALL_NOTE;
- else
+ } else {
folderName += sqlNote.getSnippet();
+ }
//iterator迭代器,通过统一的接口迭代所有的map元素
Iterator> iter = mGTaskListHashMap.entrySet().iterator();
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/model/WorkingNote.java b/src/xiaomi/Notes-master/src/net/micode/notes/model/WorkingNote.java
index be081e4..855585b 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/model/WorkingNote.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/model/WorkingNote.java
@@ -280,7 +280,9 @@ public class WorkingNote {
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
}
}
-
+ public void setmContent(String text){
+ mContent = text;
+ }
public void setWorkingText(String text) {
if (!TextUtils.equals(mContent, text)) {
mContent = text;
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/translate/BaiduTranslateService.java b/src/xiaomi/Notes-master/src/net/micode/notes/translate/BaiduTranslateService.java
new file mode 100644
index 0000000..8e26c2c
--- /dev/null
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/translate/BaiduTranslateService.java
@@ -0,0 +1,24 @@
+package net.micode.notes.translate;
+
+import retrofit2.Call;
+import retrofit2.http.Field;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.POST;
+//源URL https://fanyi-api.baidu.com/api/trans/vip/translate
+//参数如下
+// String q 英文单词/中文
+// String from 原始语种 zh中文/eh英文
+// String to 目标语种 zh中文/eh英文
+// String from zh中文/eh英文
+// String appid 你的appid
+// String salt 随机数(整形转字符串)
+// String sign 签名 32位字母小写MD5编码的 appid+q+salt+密钥
+public interface BaiduTranslateService {
+ //翻译接口
+ //表示提交表单数据,@Field注解键名
+ //适用于数据量少的情况
+ @POST("translate")
+ @FormUrlEncoded
+ Call translate(@Field("q") String q, @Field("from") String from, @Field("to") String to, @Field("appid") String appid, @Field("salt") String salt,
+ @Field("sign") String sign);
+}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/translate/MD5Utils.java b/src/xiaomi/Notes-master/src/net/micode/notes/translate/MD5Utils.java
new file mode 100644
index 0000000..ecd9e6e
--- /dev/null
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/translate/MD5Utils.java
@@ -0,0 +1,35 @@
+package net.micode.notes.translate;
+
+import java.security.MessageDigest;
+
+/**
+ * 加密解密工具类(对字符串加密) MD5加密
+ */
+public class MD5Utils {
+
+ /**
+ * MD5加密算法使用 对字符串加密
+ *
+ * @param info 参数为需要加密的String
+ * @return 返回加密后的String
+ */
+ public static String getMD5Code(String info) {
+ try {
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ md5.update(info.getBytes("utf-8"));//设置编码格式
+ byte[] encryption = md5.digest();
+ StringBuffer stringBuffer = new StringBuffer();
+ for (int i = 0; i < encryption.length; i++) {
+ if (Integer.toHexString(0xff & encryption[i]).length() == 1) {
+ stringBuffer.append("0").append(Integer.toHexString(0xff & encryption[i]));
+ } else {
+ stringBuffer.append(Integer.toHexString(0xff & encryption[i]));
+ }
+ }
+ return stringBuffer.toString();
+ } catch (Exception e) {
+ return "MD5加密异常";
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/translate/RespondBean.java b/src/xiaomi/Notes-master/src/net/micode/notes/translate/RespondBean.java
new file mode 100644
index 0000000..eddfe3d
--- /dev/null
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/translate/RespondBean.java
@@ -0,0 +1,65 @@
+package net.micode.notes.translate;
+
+import java.util.List;
+
+public class RespondBean {
+
+ /**
+ * from : zh
+ * to : en
+ * trans_result : [{"src":"你好","dst":"Hello"}]
+ */
+
+ private String from;
+ private String to;
+ private List trans_result;
+
+ public String getFrom() {
+ return from;
+ }
+
+ public void setFrom(String from) {
+ this.from = from;
+ }
+
+ public String getTo() {
+ return to;
+ }
+
+ public void setTo(String to) {
+ this.to = to;
+ }
+
+ public List getTrans_result() {
+ return trans_result;
+ }
+
+ public void setTrans_result(List trans_result) {
+ this.trans_result = trans_result;
+ }
+
+ public static class TransResultBean {
+ /**
+ * src : 你好
+ * dst : Hello
+ */
+ private String src;
+ private String dst;
+
+ public String getSrc() {
+ return src;
+ }
+
+ public void setSrc(String src) {
+ this.src = src;
+ }
+
+ public String getDst() {
+ return dst;
+ }
+
+ public void setDst(String dst) {
+ this.dst = dst;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java
index ca89c22..85723be 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java
@@ -39,77 +39,36 @@ import net.micode.notes.tool.DataUtils;
import java.io.IOException;
-/**
- *
- * @ProjectName:
- * @Package: net.micode.notes.ui
- * @ClassName: AlarmAlertActivity
- * @Description: AlarmAlertActivity类的作用是作为一个提醒警报的活动界面。
- * 当便签的提醒功能触发时,系统会启动AlarmAlertActivity,显示提醒的详细内容和相关操作选项,
- * 让用户可以对提醒进行处理,比如查看提醒内容、延迟提醒或者标记为已完成等操作。
- * 这个类主要负责提醒相关的界面展示和用户交互逻辑。
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 10:33
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 10:33
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
+
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
- private long mNoteId; //文本在数据库存储中的ID号
- private String mSnippet; //闹钟提示时出现的文本片段
+ private long mNoteId;
+ private String mSnippet;
private static final int SNIPPET_PREW_MAX_LEN = 60;
MediaPlayer mPlayer;
-
- /**
- * @method onCreate
- * @description :
- * 初始化提醒界面的布局和逻辑。
- * 设置窗口特性,请求不显示标题栏,并在锁屏状态下显示提醒界面。
- * 获取传入该活动的Intent对象,并尝试从中获取便签的ID。
- * 使用获取到的便签ID获取便签的摘要信息,并进行相应的处理。
- * 创建一个MediaPlayer对象,用于播放提醒的声音。
- * 检查该便签是否在便签数据库中可见。
- * 如果便签可见,则显示操作对话框,并播放提醒音效。
- * 如果便签不可见,则关闭该界面。
- * @date: 2023-12-24 10:41
- * @author: xumingyang
- * @param
- * @return
- */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- //Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的
- //onsaveInstanceState方法是用来保存Activity的状态的
- //能从onCreate的参数savedInsanceState中获得状态数
requestWindowFeature(Window.FEATURE_NO_TITLE);
- //界面显示——无标题
+
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
if (!isScreenOn()) {
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
- //保持窗体点亮
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
- //将窗体点亮
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
- //允许窗体点亮时锁屏
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
- }//在手机锁屏后如果到了闹钟提示时间,点亮屏幕
+ }
Intent intent = getIntent();
try {
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
- //根据ID从数据库中获取标签的内容;
- //getContentResolver()是实现数据共享,实例存储。
mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0,
SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info)
: mSnippet;
- //判断标签片段是否达到符合长度
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
@@ -118,41 +77,20 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
mPlayer = new MediaPlayer();
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
showActionDialog();
- //弹出对话框
playAlarmSound();
- //闹钟提示音激发
} else {
finish();
- //完成闹钟动作
}
}
- /**
- * @method isScreenOn
- * @description 判断屏幕是否锁屏,调用系统函数判断
- * @date: 2023-12-24 10:45
- * @author: xumingyang
- * @param
- * @return bool 类型
- */
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn();
}
- /**
- * @method playAlarmSound
- * @description:
- * 该段代码的作用是根据用户的设置,播放系统默认的闹钟铃声。
- * 并且可以支持在静音模式下播放闹钟铃声
- * @date: 2023-12-24 10:47
- * @author: xumingyang
- * @param
- * @return
- */
private void playAlarmSound() {
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
- //调用系统的铃声管理URI,得到闹钟提示音
+
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
@@ -163,19 +101,12 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
try {
mPlayer.setDataSource(this, url);
- //方法:setDataSource(Context context, Uri uri)
- //解释:无返回值,设置多媒体数据来源【根据 Uri】
mPlayer.prepare();
- //准备同步
mPlayer.setLooping(true);
- //设置是否循环播放
mPlayer.start();
- //开始播放
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
- //e.printStackTrace()函数功能是抛出异常, 还将显示出更深的调用信息
- //System.out.println(e),这个方法打印出异常,并且输出在哪里出现的异常
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -188,99 +119,39 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
}
-
- /**
- * @method showActionDialog
- * @description
- * 创建一个AlertDialog.Builder对象,并设置对话框的标题为应用的名称(R.string.app_name)。
- * 将对话框的消息内容设置为mSnippet变量所存储的文本信息。
- * 设置对话框的积极按钮(Positive Button)的文本为“确定”(R.string.notealert_ok),并将当前类作为按钮的点击监听器。
- * 如果屏幕处于开启状态(通过isScreenOn()方法判断),则设置对话框的消极按钮(Negative Button)的文本为“进入”(R.string.notealert_enter),并将当前类作为按钮的点击监听器。
- * 调用dialog.show().setOnDismissListener(this)方法显示对话框,并设置当前类作为对话框消失时的监听器。
- * @date: 2023-12-24 10:51
- * @author: xumingyang
- * @param
- * @return
- */
private void showActionDialog() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
- /*
- * AlertDialog的构造方法全部是Protected的
- * 所以不能直接通过new一个AlertDialog来创建出一个AlertDialog。
- * 要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法
- * 如这里的dialog就是新建了一个AlertDialog
- */
dialog.setTitle(R.string.app_name);
- //为对话框设置标题
dialog.setMessage(mSnippet);
- //为对话框设置内容
dialog.setPositiveButton(R.string.notealert_ok, this);
- //给对话框添加"Yes"按钮
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);
- }//对话框添加"No"按钮
+ }
dialog.show().setOnDismissListener(this);
}
- /**
- * @method onClick
- * @description :
- * 根据点击的按钮类型执行相应的操作,
- * 如果点击的是对话框中的消极按钮,则打开一个新的便签编辑界面,并将当前笔记的id传递给该Activity。
- * @date: 2023-12-24 10:55
- * @author: xumingyang
- * @param
- * @return
- */
public void onClick(DialogInterface dialog, int which) {
switch (which) {
- //用which来选择click后下一步的操作
case DialogInterface.BUTTON_NEGATIVE:
- //这是取消操作
Intent intent = new Intent(this, NoteEditActivity.class);
- //实现两个类间的数据传输
intent.setAction(Intent.ACTION_VIEW);
- //设置动作属性
intent.putExtra(Intent.EXTRA_UID, mNoteId);
- //实现key-value对
- //EXTRA_UID为key;mNoteId为键
startActivity(intent);
- //开始动作
break;
default:
- //这是确定操作'
break;
}
}
- /**
- * @method onDismiss
- * @description 在闹钟提醒对话框消失时,停止闹钟铃声并结束当前Activity的生命周期。
- * @date: 2023-12-24 10:57
- * @author: xumingyang
- * @param
- * @return
- */
public void onDismiss(DialogInterface dialog) {
stopAlarmSound();
- //停止闹钟声音
finish();
- //完成该动作
}
- /**
- * @method stopAlarmSound
- * @description 停止正在播放的闹钟声音,并释放相关的资源。
- * @date: 2023-12-24 10:58
- * @author: xumingyang
- * @param
- * @return
- */
+
private void stopAlarmSound() {
if (mPlayer != null) {
mPlayer.stop();
- //停止播放
mPlayer.release();
- //释放MediaPlayer对象
mPlayer = null;
}
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java
index 16d229a..f221202 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java
@@ -27,21 +27,6 @@ import android.database.Cursor;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
-/**
- *
- * @ProjectName:
- * @Package: net.micode.notes.ui
- * @ClassName: AlarmInitReceiver
- * @Description: AlarmInitReceiver类是小米便签应用中的一个广播接收器(BroadcastReceiver)
- * 其作用是在设备启动时接收系统发送的广播,并执行一些初始化操作
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 11:11
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 11:11
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
-
public class AlarmInitReceiver extends BroadcastReceiver {
@@ -49,35 +34,19 @@ public class AlarmInitReceiver extends BroadcastReceiver {
NoteColumns.ID,
NoteColumns.ALERTED_DATE
};
- //对数据库的操作,调用标签ID和闹钟时间
+
private static final int COLUMN_ID = 0;
private static final int COLUMN_ALERTED_DATE = 1;
-
- /**
- * @method onReceive
- * @description 是在设备启动后,通过查询数据库找到需要提醒的标签,并设置对应的闹钟。
- * 这样,在设备启动完成后,小米便签应用可以重新加载标签的提醒功能,确保按时提醒用户。
- * @date: 2023-12-24 11:26
- * @author: xumingyang
- * @param *Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签
- * 从游标中获取提醒日期(alertDate)
- * 创建一个新的Intent对象(sender),并指定目标广播接收器(AlarmReceiver)
- * 创建PendingIntent:使用getBroadcast()方法创建一个用于启动广播的PendingIntent对象(pendingIntent)
- * @return 查询结果将以Cursor对象(c)返回
- */
@Override
public void onReceive(Context context, Intent intent) {
long currentDate = System.currentTimeMillis();
- //System.currentTimeMillis()产生一个当前的毫秒
- //这个毫秒其实就是自1970年1月1日0时起的毫秒数
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
PROJECTION,
NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
new String[] { String.valueOf(currentDate) },
- //将long变量currentDate转化为字符串
null);
- //Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签
+
if (c != null) {
if (c.moveToFirst()) {
do {
@@ -93,9 +62,4 @@ public class AlarmInitReceiver extends BroadcastReceiver {
c.close();
}
}
- /*
- * 然而通过网上查找资料发现,对于闹钟机制的启动,通常需要上面的几个步骤
- * 如新建Intent、PendingIntent以及AlarmManager等
- * 这里就是根据数据库里的闹钟时间创建一个闹钟机制
- */
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java
index d425245..54e503b 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java
@@ -20,37 +20,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-/**
- *
- * @ProjectName:
- * @Package: net.micode.notes.ui
- * @ClassName: AlarmReceiver
- * @Description: 通过AlarmReceiver类,可以实现小米便签的提醒功能,
- * 让用户按时收到提醒并进行相应的操作。
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 12:46
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 12:46
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
-
-
- /**
- * @method
- * @description 段代码是用于在接收到广播时启动AlarmAlertActivity活动,并在新的任务栈中展示该活动
- * @param *Context context和Intent intent,其中context表示上下文环境,intent表示接收到的广播意图。
- * @return
- */
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- //重写了onReceive()方法,该方法在接收到广播时会被调用
intent.setClass(context, AlarmAlertActivity.class);
- ////启动AlarmAlertActivity
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- ////activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈
- //所以要新起一个栈装入启动的activity
context.startActivity(intent);
}
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePicker.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePicker.java
index cc52e91..496b0cd 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePicker.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePicker.java
@@ -28,23 +28,8 @@ import android.view.View;
import android.widget.FrameLayout;
import android.widget.NumberPicker;
-/**
- *
- * @ProjectName:
- * @Package: net.micode.notes.ui
- * @ClassName: DateTimePicker
- * @Description: 用于选择日期和时间的自定义视图,包括年、月、日、时、分等选择器。
- * 它使用了NumberPicker控件来实现日期和时间的选择功能,并提供了一些回调接口以便在日期和时间改变时进行通知。
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 12:58
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 12:58
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
public class DateTimePicker extends FrameLayout {
- //FrameLayout是布局模板之一
- //所有的子元素全部在屏幕的右上方
+
private static final boolean DEFAULT_ENABLE_STATE = true;
private static final int HOURS_IN_HALF_DAY = 12;
@@ -60,15 +45,13 @@ public class DateTimePicker extends FrameLayout {
private static final int MINUT_SPINNER_MAX_VAL = 59;
private static final int AMPM_SPINNER_MIN_VAL = 0;
private static final int AMPM_SPINNER_MAX_VAL = 1;
- //初始化控件
+
private final NumberPicker mDateSpinner;
private final NumberPicker mHourSpinner;
private final NumberPicker mMinuteSpinner;
private final NumberPicker mAmPmSpinner;
- //NumberPicker是数字选择器
- //这里定义的四个变量全部是在设置闹钟时需要选择的变量(如日期、时、分、上午或者下午)
private Calendar mDate;
- //定义了Calendar类型的变量mDate,用于操作时间
+
private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK];
private boolean mIsAm;
@@ -89,22 +72,8 @@ public class DateTimePicker extends FrameLayout {
onDateTimeChanged();
}
};
- //OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听
- //将现在日期的值传递给mDate;updateDateControl是同步操作
private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
- //这里是对 小时(Hour) 的监听
-
- /**
- * @method onValueChange
- * @description 这段代码是一个回调函数,用于监听NumberPicker的数值改变事件。
- * 当用户改变了时间选择器中的小时数时,就会触发这个回调函数。
- * 在函数中,首先判断当前选择器是否为24小时制,如果不是则需要处理上下午的切换和跨天的情况。
- * @date: 2023-12-24 13:03
- * @author: xumingyang
- * @param *声明一个Calendar的变量cal,便于后续的操作
- * @return isdateChanged bool类型 判断是否需要对时间进行调整
- */
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
boolean isDateChanged = false;
@@ -114,33 +83,29 @@ public class DateTimePicker extends FrameLayout {
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, 1);
isDateChanged = true;
- //这里是对于12小时制时,晚上11点和12点交替时对日期的更改
} else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) {
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, -1);
isDateChanged = true;
- }//这里是对于12小时制时,晚上11点和12点交替时对日期的更改
+ }
if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY ||
oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) {
mIsAm = !mIsAm;
updateAmPmControl();
- }//这里是对于12小时制时,中午11点和12点交替时对AM和PM的更改
+ }
} else {
if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) {
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, 1);
isDateChanged = true;
- //这里是对于24小时制时,晚上11点和12点交替时对日期的更改
} else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) {
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, -1);
isDateChanged = true;
}
- }//这里是对于12小时制时,凌晨11点和12点交替时对日期的更改
+ }
int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY);
- //通过数字选择器对newHour的赋值
mDate.set(Calendar.HOUR_OF_DAY, newHour);
- //通过set函数将新的Hour值传给mDate
onDateTimeChanged();
if (isDateChanged) {
setCurrentYear(cal.get(Calendar.YEAR));
@@ -151,25 +116,16 @@ public class DateTimePicker extends FrameLayout {
};
private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() {
- /**
- * @method onValueChange
- * @description 用于监控 NumberPicker(数字选择器)的数值变化事件。
- * 具体来说,这个监听器是用于监听分钟选择器的数值变化。
- * @param *三个参数:picker(当前的 NumberPicker 对象)、oldVal(旧值)和 newVal(新值)
- */
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
int minValue = mMinuteSpinner.getMinValue();
int maxValue = mMinuteSpinner.getMaxValue();
int offset = 0;
- //设置offset,作为小时改变的一个记录数据
if (oldVal == maxValue && newVal == minValue) {
offset += 1;
} else if (oldVal == minValue && newVal == maxValue) {
offset -= 1;
}
- //如果原值为59,新值为0,则offset加1
- //如果原值为0,新值为59,则offset减1
if (offset != 0) {
mDate.add(Calendar.HOUR_OF_DAY, offset);
mHourSpinner.setValue(getCurrentHour());
@@ -189,15 +145,9 @@ public class DateTimePicker extends FrameLayout {
};
private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
- /**
- * @method onValueChange
- * @description 实现了一个监听器,用于监测用户对NumberPicker控件数值的改变,
- * 并根据改变的数值来更新界面上的上午/下午控件
- */
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mIsAm = !mIsAm;
- //对AM和PM的监听
if (mIsAm) {
mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY);
} else {
@@ -216,25 +166,18 @@ public class DateTimePicker extends FrameLayout {
public DateTimePicker(Context context) {
this(context, System.currentTimeMillis());
}
- //通过对数据库的访问,获取当前的系统时间
public DateTimePicker(Context context, long date) {
this(context, date, DateFormat.is24HourFormat(context));
}
- //上面函数的得到的是一个天文数字(1970至今的秒数),需要DateFormat将其变得有意义
public DateTimePicker(Context context, long date, boolean is24HourView) {
super(context);
- //获取系统时间
mDate = Calendar.getInstance();
mInitialising = true;
mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY;
inflate(context, R.layout.datetime_picker, this);
- /*
- * 如果当前Activity里用到别的layout,比如对话框layout
- * 还要设置这个layout上的其他组件的内容,就必须用inflate()方法先将对话框的layout找出来
- * 然后再用findViewById()找到它上面的其它组件
- */
+
mDateSpinner = (NumberPicker) findViewById(R.id.date);
mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL);
mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL);
@@ -271,28 +214,17 @@ public class DateTimePicker extends FrameLayout {
mInitialising = false;
}
- /**
- * @method setEnabled
- * @description 这个函数用于统一设置控件及其相关子控件的可用状态,并且会根据传入的参数值进行相应的操作
- * @param *布尔值 enabled,用于指定控件是否可用。
- * @return 将 mIsEnabled 的值更新为传入的 enabled,以保持状态同步
- */
@Override
public void setEnabled(boolean enabled) {
if (mIsEnabled == enabled) {
return;
}
- /*
- * 如果传入的参数 enabled 与当前的控件可用状态 mIsEnabled 相同,则无需进行任何操作,直接返回。
- * 这样可以避免重复设置控件的可用状态。
- */
super.setEnabled(enabled);
mDateSpinner.setEnabled(enabled);
mMinuteSpinner.setEnabled(enabled);
mHourSpinner.setEnabled(enabled);
mAmPmSpinner.setEnabled(enabled);
mIsEnabled = enabled;
- //将 mIsEnabled 的值更新为传入的 enabled,以保持状态同步
}
@Override
@@ -307,7 +239,7 @@ public class DateTimePicker extends FrameLayout {
*/
public long getCurrentDateInTimeMillis() {
return mDate.getTimeInMillis();
- }//实现函数——得到当前的秒数
+ }
/**
* Set the current date
@@ -319,7 +251,7 @@ public class DateTimePicker extends FrameLayout {
cal.setTimeInMillis(date);
setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH),
cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
- }//实现函数功能——设置当前的时间,参数是date
+ }
/**
* Set the current date
@@ -337,14 +269,13 @@ public class DateTimePicker extends FrameLayout {
setCurrentDay(dayOfMonth);
setCurrentHour(hourOfDay);
setCurrentMinute(minute);
- }//实现函数功能——设置当前的时间,参数是各详细的变量
+ }
/**
* Get current year
*
* @return The current year
*/
- //下面是得到year、month、day等值
public int getCurrentYear() {
return mDate.get(Calendar.YEAR);
}
@@ -515,7 +446,7 @@ public class DateTimePicker extends FrameLayout {
mDateSpinner.setDisplayedValues(mDateDisplayValues);
mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2);
mDateSpinner.invalidate();
- }// 对于星期几的算法
+ }
private void updateAmPmControl() {
if (mIs24HourView) {
@@ -525,7 +456,7 @@ public class DateTimePicker extends FrameLayout {
mAmPmSpinner.setValue(index);
mAmPmSpinner.setVisibility(View.VISIBLE);
}
- }// 对于上下午操作的算法
+ }
private void updateHourControl() {
if (mIs24HourView) {
@@ -535,7 +466,7 @@ public class DateTimePicker extends FrameLayout {
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW);
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW);
}
- }// 对与小时的算法
+ }
/**
* Set the callback that indicates the 'Set' button has been pressed.
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java
index f673733..2c47ba4 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java
@@ -29,43 +29,21 @@ import android.content.DialogInterface.OnClickListener;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
-/**
- *
- * @ProjectName: DateTimePickerDialog
- * @Package: net.micode.notes.ui
- * @ClassName: DateTimePickerDialog
- * @Description: DateTimePickerDialog 的作用是提供一个日期和时间选择器的对话框,用于让用户选择日期和时间。
- * 该对话框通常用于设置便签的提醒时间或截止时间等功能,用户可以通过滚动选择器来选择特定的日期和时间。
- * DateTimePickerDialog 提供了直观且方便的界面,使用户能够方便地选择所需的日期和时间。
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 13:52
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 13:52
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
public class DateTimePickerDialog extends AlertDialog implements OnClickListener {
private Calendar mDate = Calendar.getInstance();
- //创建一个Calendar类型的变量 mDate,方便时间的操作
private boolean mIs24HourView;
private OnDateTimeSetListener mOnDateTimeSetListener;
- //声明一个时间日期滚动选择控件 mOnDateTimeSetListener
private DateTimePicker mDateTimePicker;
- //DateTimePicker控件,控件一般用于让用户可以从日期列表中选择单个值。
- //运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的
public interface OnDateTimeSetListener {
void OnDateTimeSet(AlertDialog dialog, long date);
}
public DateTimePickerDialog(Context context, long date) {
- //对该界面对话框的实例化
super(context);
- //对数据库的操作
mDateTimePicker = new DateTimePicker(context);
setView(mDateTimePicker);
- //添加一个子视图
mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
public void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute) {
@@ -74,21 +52,15 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
mDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
mDate.set(Calendar.MINUTE, minute);
- //将视图中的各选项设置为系统当前时间
updateTitle(mDate.getTimeInMillis());
}
});
mDate.setTimeInMillis(date);
- //得到系统时间
mDate.set(Calendar.SECOND, 0);
- //将秒数设置为0 对日期时间进行标准化处理
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
- //将日期时间选择器设置为当前设置的日期时间。
setButton(context.getString(R.string.datetime_dialog_ok), this);
setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null);
- //设置按钮
set24HourView(DateFormat.is24HourFormat(this.getContext()));
- //时间标准化打印
updateTitle(mDate.getTimeInMillis());
}
@@ -98,7 +70,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
mOnDateTimeSetListener = callBack;
- }//将时间日期滚动选择控件实例化
+ }
private void updateTitle(long date) {
int flag =
@@ -107,13 +79,12 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
DateUtils.FORMAT_SHOW_TIME;
flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR;
setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
- }//android开发中常见日期管理工具类(API)——DateUtils:按照上下午显示时间
+ }
public void onClick(DialogInterface arg0, int arg1) {
if (mOnDateTimeSetListener != null) {
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
}
- }//第一个参数arg0是接收到点击事件的对话框
- //第二个参数arg1是该对话框上的按钮
+ }
}
\ No newline at end of file
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/DropdownMenu.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/DropdownMenu.java
index 7e6e7d0..613dc74 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/DropdownMenu.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/DropdownMenu.java
@@ -27,38 +27,17 @@ import android.widget.PopupMenu.OnMenuItemClickListener;
import net.micode.notes.R;
-/**
- *
- * @ProjectName:
- * @Package: net.micode.notes.ui
- * @ClassName: DropdownMenu
- * @Description: DropdownMenu是一个下拉菜单,它的作用是提供一种选择多个选项的方式。
- * 当用户点击DropdownMenu时,会弹出一个下拉列表,列出了多个选项供用户选择。
- * 1.笔记分类:用户可以使用DropdownMenu来选择笔记的分类,比如工作、生活、学习等,从而方便地将笔记进行分类管理。
- * 2.笔记排序:用户可以使用DropdownMenu来选择笔记的排序方式,比如按时间、按标题等进行排序,以满足不同排序需求。
- * 3.标签管理:用户可以使用DropdownMenu来选择或添加标签,以对笔记进行更细粒度的分类和标记。
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 13:57
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 13:57
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
public class DropdownMenu {
private Button mButton;
private PopupMenu mPopupMenu;
- //声明一个下拉菜单
private Menu mMenu;
public DropdownMenu(Context context, Button button, int menuId) {
mButton = button;
mButton.setBackgroundResource(R.drawable.dropdown_icon);
- //设置这个view的背景
mPopupMenu = new PopupMenu(context, mButton);
mMenu = mPopupMenu.getMenu();
mPopupMenu.getMenuInflater().inflate(menuId, mMenu);
- //MenuInflater是用来实例化Menu目录下的Menu布局文件
- //根据ID来确认menu的内容选项
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mPopupMenu.show();
@@ -70,13 +49,13 @@ public class DropdownMenu {
if (mPopupMenu != null) {
mPopupMenu.setOnMenuItemClickListener(listener);
}
- }//设置菜单的监听
+ }
public MenuItem findItem(int id) {
return mMenu.findItem(id);
}
- //对于菜单选项的初始化,根据索引搜索菜单需要的选项
+
public void setTitle(CharSequence title) {
mButton.setText(title);
}
-}//布局文件,设置标题
+}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java
index ac79adf..96b77da 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java
@@ -28,54 +28,25 @@ import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
-/**
- *
- * @ProjectName:
- * @Package: net.micode.notes.ui
- * @ClassName: FoldersListAdapter
- * @Description: FoldersListAdapter 的作用是作为文件夹列表的适配器,用于管理和显示文件夹列表的数据和视图。
- * @Author: xumingyang
- * @CreateDate: 2023-12-24 14:05
- * @UpdateUser: 更新者:
- * @UpdateDate: 2023-12-24 14:05
- * @UpdateRemark: 更新说明:
- * @Version: 1.0
- */
+
public class FoldersListAdapter extends CursorAdapter {
- /*
- * CursorAdapter是Cursor和ListView的接口
- * FoldersListAdapter继承了CursorAdapter的类
- * 主要作用是便签数据库和用户的交互
- * 这里就是用folder(文件夹)的形式展现给用户
- */
public static final String [] PROJECTION = {
NoteColumns.ID,
NoteColumns.SNIPPET
- };//调用数据库中便签的ID和片段
+ };
public static final int ID_COLUMN = 0;
public static final int NAME_COLUMN = 1;
- /**
- * @method FoldersListAdapter
- * @description 用于初始化FoldersListAdapter类的实例。这个类可能是用于管理文件夹列表显示的适配器,其中包含了数据库操作相关的功能
- * @param context 参数通常是指当前的上下文
- * c 参数可能是一个用于查询数据库的Cursor对象。
- */
public FoldersListAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
- }//数据库操作
+ }
- /**
- * @method newView
- * @description 用于创建新的视图用于显示文件夹列表项。
- * @return 将该视图返回给适配器使用
- */
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new FolderListItem(context);
- }//创建一个文件夹,对于各文件夹中子标签的初始化
+ }
@Override
public void bindView(View view, Context context, Cursor cursor) {
@@ -84,23 +55,20 @@ public class FoldersListAdapter extends CursorAdapter {
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
((FolderListItem) view).bind(folderName);
}
- }//将各个布局文件绑定起来
+ }
public String getFolderName(Context context, int position) {
Cursor cursor = (Cursor) getItem(position);
return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
- }//根据数据库中标签的ID得到标签的各项内容
-
+ }
private class FolderListItem extends LinearLayout {
private TextView mName;
public FolderListItem(Context context) {
super(context);
- //操作数据库
inflate(context, R.layout.folder_list_item, this);
- //根据布局文件的名字等信息将其找出来
mName = (TextView) findViewById(R.id.tv_folder_name);
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
index 78dfae4..4ba448e 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
@@ -19,22 +19,38 @@ package net.micode.notes.ui;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
+import android.app.Dialog;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
+import android.content.ContentResolver;
import android.content.ContentUris;
+import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Paint;
+import android.graphics.Typeface;
+import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.provider.DocumentsContract;
+import android.provider.MediaStore;
+import android.speech.tts.TextToSpeech;
+import android.support.annotation.RequiresApi;
+import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
+import android.text.TextWatcher;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
+import android.text.style.ImageSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -43,10 +59,12 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
+import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -65,15 +83,32 @@ import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
+import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Map;
+import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import net.micode.notes.translate.BaiduTranslateService;
+import net.micode.notes.translate.RespondBean;
+import net.micode.notes.translate.MD5Utils;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.gson.GsonConverterFactory;
+
+import android.speech.tts.TextToSpeech.OnInitListener;
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
+ public static void setmChanged(Stack mChanged) {
+ NoteEditActivity.mChanged = mChanged;
+ }
+
private class HeadViewHolder {
public TextView tvModified;
@@ -149,22 +184,338 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
+ private CharSequence restore_translate = null;
+
+ private boolean mIsRvoke = false;
+
+ private TextToSpeech mTTS;
+ private static Stack mChanged;
+ private final int PHOTO_REQUEST = 1;
+ private Dialog alertDialog2;
+ Context context;
+ private static final int MAX_TIME_OF_RVOKE_TIME=100;
+ private final int MAX_OF_RVOKE_TIME=100;
+ public void translateChtoEn() {
+ //准备请求百度翻译接口需要的参数
+ final EditText editable = findViewById(R.id.note_edit_view);
+ String word = editable.getText().toString();
+ word = word.replaceAll("\\n","//");
+ String from = "auto";//源语种 en 英语 zh 中文
+ //String中英文占用一个字节,中文占用两个字节,
+ //利用String的这个存储特性可以用来判断String中有没有中文。
+ // to = "zh"; //没有汉字 英译中
+ String to = "en";//含有汉字 中译英
+ String appid = "20240103001929054";//appid 管理控制台有
+ String salt = (int) (Math.random() * 100 + 1) + "";//随机数这里范围是[0,100]整数无强制要求
+ String key = "Xa_yB5ihrTIaG8Nlv4S6";//密钥 管理控制台有
+ String secretKey = appid + word + salt + key;// secretKey = appid+q+salt+密钥
+ String sign = MD5Utils.getMD5Code(secretKey);// 签名 = secretKey 的MD5加密32位字母小写
+ Log.d(TAG, "secretKey:" + secretKey);
+ Log.d(TAG, "sign: " + sign);
+
+ Retrofit retrofitBaidu = new Retrofit.Builder()
+ .baseUrl("https://fanyi-api.baidu.com/api/trans/vip/")
+ .addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
+ .build();
+ BaiduTranslateService baiduTranslateService =retrofitBaidu.create(BaiduTranslateService.class);
+ retrofit2.Call call = baiduTranslateService.translate(word, from, to, appid, salt, sign);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ //请求成功
+ Log.d(TAG, "onResponse: 请求成功");
+ RespondBean respondBean = response.body();//返回的JSON字符串对应的对象
+ String result = respondBean.getTrans_result().get(0).getDst();//获取翻译的字符串String
+ editable.setText(result);
+ Log.d(TAG, "中译英结果" + result);
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ //请求失败 打印异常
+ Log.d(TAG, "onResponse: 请求失败 " + t);
+ }
+ });
+ }
+ public void translateEntoCh() {
+ //准备请求百度翻译接口需要的参数
+ final EditText editable = findViewById(R.id.note_edit_view);
+ String word = editable.getText().toString();
+ word = word.replaceAll("\\n","//");
+ Log.d(TAG, word);
+ String from = "auto";//源语种 en 英语 zh 中文
+ //String中英文占用一个字节,中文占用两个字节,
+ //利用String的这个存储特性可以用来判断String中有没有中文。
+ // to = "zh"; //没有汉字 英译中
+ String to = "zh";//含有汉字 英译中
+ String appid = "20240103001929054";//appid 管理控制台有
+ String salt = (int) (Math.random() * 100 + 1) + "";//随机数这里范围是[0,100]整数无强制要求
+ String key = "Xa_yB5ihrTIaG8Nlv4S6";//密钥 管理控制台有
+ String secretKey = appid + word + salt + key;// secretKey = appid+q+salt+密钥
+ String sign = MD5Utils.getMD5Code(secretKey);// 签名 = secretKey 的MD5加密32位字母小写
+ Log.d(TAG, "secretKey:" + secretKey);
+ Log.d(TAG, "sign: " + sign);
+
+ Retrofit retrofitBaidu = new Retrofit.Builder()
+ .baseUrl("https://fanyi-api.baidu.com/api/trans/vip/")
+ .addConverterFactory(GsonConverterFactory.create()) // 设置数据解析器
+ .build();
+ BaiduTranslateService baiduTranslateService =retrofitBaidu.create(BaiduTranslateService.class);
+ retrofit2.Call call = baiduTranslateService.translate(word, from, to, appid, salt, sign);
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ //请求成功
+ Log.d(TAG, "onResponse: 请求成功");
+ RespondBean respondBean = response.body();//返回的JSON字符串对应的对象
+ String result = respondBean.getTrans_result().get(0).getDst();//获取翻译的字符串String
+ editable.setText(result);
+ Log.d(TAG, "英译中结果" + result);
+ }
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ //请求失败 打印异常
+ Log.d(TAG, "onResponse: 请求失败 " + t);
+ }
+ });
+ }
+ public void doTranslate(){
+ final EditText editable = findViewById(R.id.note_edit_view);
+ final Button get_local = findViewById(R.id.translate); //R.id.translate是定义在界面左上角的按钮
+ get_local.setOnClickListener(new OnClickListener() { //如果点击按钮,则触发
+ @Override
+ public void onClick(final View v) {
+ Button trans1 = new Button(NoteEditActivity.this); //三个功能的按钮
+ Button trans2 = new Button(NoteEditActivity.this);
+ Button trans3 = new Button(NoteEditActivity.this);
+ trans1.setText("中文翻译为英文");
+ trans2.setText("英文翻译为中文");
+ trans3.setText("还原");
+ LinearLayout linear = new LinearLayout(NoteEditActivity.this); //定义线性表结构
+ linear.setOrientation(LinearLayout.VERTICAL); //设置为垂直结构
+ linear.addView(trans1); //将三个按钮添加到线性表中
+ linear.addView(trans2);
+ linear.addView(trans3);
+ AlertDialog.Builder builder = new AlertDialog.Builder(NoteEditActivity.this); //定义一个AlertDialog生成器
+ builder.setView(linear); //附上线性表结构
+ builder.setTitle("请选择翻译模式"); //提示语句
+ AlertDialog choose_trans = builder.create(); //生成一个AlertDialog的对话框
+ choose_trans.show(); //展示
+ trans1.setOnClickListener(new OnClickListener() { //如果点击第一个按钮,则触发
+ @Override
+ public void onClick(View v) {
+ restore_translate = editable.getText();
+ Log.d(TAG, "666" + restore_translate);
+ choose_trans.dismiss();
+ if(restore_translate == null){
+ Toast.makeText(NoteEditActivity.this, "当前无可翻译内容", Toast.LENGTH_SHORT).show();
+ }
+ else{
+ translateChtoEn();
+ Toast.makeText(NoteEditActivity.this, "中文翻译为英文", Toast.LENGTH_SHORT).show();
+ }
+
+ }
+ });
+ trans2.setOnClickListener(new OnClickListener(){ //如果点击第二个按钮,则触发
+ @Override
+ public void onClick(View v) {
+ restore_translate = editable.getText();
+ Log.d(TAG, "666" + restore_translate);
+ choose_trans.dismiss();
+ if(restore_translate == null){
+ Toast.makeText(NoteEditActivity.this, "当前无可翻译内容", Toast.LENGTH_SHORT).show();
+ }
+ else{
+ translateEntoCh();
+ Toast.makeText(NoteEditActivity.this, "英文翻译为中文", Toast.LENGTH_SHORT).show();
+ }
+
+ }
+ });
+ trans3.setOnClickListener(new OnClickListener() { //如果点击第三个按钮,则触发
+ @Override
+ public void onClick(View v) {
+ choose_trans.dismiss();
+ Log.d(TAG, "666" + restore_translate);
+ if (restore_translate == null ||
+ restore_translate.toString().equals(editable.getText().toString())) {
+ Toast.makeText(NoteEditActivity.this, "无可还原内容", Toast.LENGTH_SHORT).show();
+ } else {
+ editable.setText(restore_translate);
+ Toast.makeText(NoteEditActivity.this, "已还原", Toast.LENGTH_SHORT).show();//功能语句
+ }
+ }
+ });
+ }
+
+ });
+ }
+
+ //图片地址转换为图片
+ private void convertToImage() {
+ NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view);
+ Editable editable = noteEditText.getText();
+ String noteText = editable.toString();
+ int length = editable.length();
+ for (int i = 0; i < length; i++) {
+ for (int j = i; j < length; j++) {
+ String img_fragment = noteText.substring(i, j + 1);
+ if (img_fragment.length() > 15 && img_fragment.endsWith("[/local]") && img_fragment.startsWith("[local]")) {
+ int limit = 7;
+ int len = img_fragment.length() - 15;
+ String path = img_fragment.substring(limit, limit + len);
+ Bitmap bitmap = null;
+ Log.d(TAG, "图片的路径是:" + path);
+ try {
+ bitmap = BitmapFactory.decodeFile(path);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (bitmap != null) {
+ Log.d(TAG, "图片不为null");
+ ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
+ String ss = "[local]" + path + "[/local]";
+ SpannableString spannableString = new SpannableString(ss);
+ spannableString.setSpan(imageSpan, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ Log.d(TAG, "Create spannable string success!");
+ Editable edit_text = noteEditText.getEditableText();
+ edit_text.delete(i, i + len + 15);
+ edit_text.insert(i, spannableString);
+ }
+ }
+ }
+ }
+ }
+ //处理返回的数据,并将图片的路径也写入到数据库
+ @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+ protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ super.onActivityResult(requestCode, resultCode, intent);
+ ContentResolver resolver = getContentResolver();
+ switch (requestCode) {
+ case PHOTO_REQUEST:
+ Uri originalUri = intent.getData();
+ Bitmap bitmap = null;
+ try {
+ bitmap = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));//2.解码图片
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "onActivityResult: get file_exception");
+ e.printStackTrace();
+ }
+
+ if (bitmap != null) {
+ Log.d(TAG, "onActivityResult: bitmap is not null");
+ ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
+ String path = getPath(this, originalUri);
+ String img_fragment = "[local]" + path + "[/local]";
+ SpannableString spannableString = new SpannableString(img_fragment);
+ spannableString.setSpan(imageSpan, 0, img_fragment.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ NoteEditText e = (NoteEditText) findViewById(R.id.note_edit_view);
+ int index = e.getSelectionStart();
+ Log.d(TAG, "Index是: " + index);
+ Editable edit_text = e.getEditableText();
+ edit_text.insert(index, spannableString);
+ mWorkingNote.setmContent(e.getText().toString());
+ ContentResolver contentResolver = getContentResolver();
+ ContentValues contentValues = new ContentValues();
+ final long id = mWorkingNote.getNoteId();
+ contentValues.put("snippet", mWorkingNote.getContent());
+ contentResolver.update(Uri.parse("content://micode_notes/note"), contentValues, "_id=?", new String[]{"" + id});
+ ContentValues contentValues1 = new ContentValues();
+ contentValues1.put("content", mWorkingNote.getContent());
+ contentResolver.update(Uri.parse("content://micode_notes/data"), contentValues1, "mime_type=? and note_id=?", new String[]{"vnd.android.cursor.item/text_note", "" + id});
+
+ } else {
+ Toast.makeText(NoteEditActivity.this, "获取图片失败", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+ public String getPath(final Context context, final Uri uri) {
+
+ final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
+ if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
+ if (isMediaDocument(uri)) {
+ final String docId = DocumentsContract.getDocumentId(uri);
+ final String[] split = docId.split(":");
+ final String type = split[0];
+
+ Uri contentUri = null;
+ if ("image".equals(type)) {
+ contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+ }
+
+ final String selection = "_id=?";
+ final String[] selectionArgs = new String[]{split[1]};
+
+ return getDataColumn(context, contentUri, selection, selectionArgs);
+ }
+ }
+ // Media
+ else if ("content".equalsIgnoreCase(uri.getScheme())) {
+ return getDataColumn(context, uri, null, null);
+ }
+ // File
+ else if ("file".equalsIgnoreCase(uri.getScheme())) {
+ return uri.getPath();
+ }
+ return null;
+ }
+ public String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
+ Cursor cursor = null;
+ final String column = "_data";
+ final String[] projection = {column};
+
+ try {
+ cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ final int column_index = cursor.getColumnIndexOrThrow(column);
+ return cursor.getString(column_index);
+ }
+ } finally {
+ if(cursor != null){
+ cursor.close();
+ }
+
+ }
+ return null;
+ }
+ public boolean isMediaDocument(Uri uri) {
+ return "com.android.providers.media.documents".equals(uri.getAuthority());
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
-
+ setmChanged(new Stack<>() );
if (savedInstanceState == null && !initActivityState(getIntent())) {
finish();
return;
}
initResources();
+
+ final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);
+ add_img_btn.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Log.d(TAG, "onClick: click add image button");
+ Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT);
+ loadImage.addCategory(Intent.CATEGORY_OPENABLE);
+ loadImage.setType("image/*");
+ startActivityForResult(loadImage, PHOTO_REQUEST);
+ }
+ });
}
+
/**
* Current activity may be killed when the memory is low. Once it is killed, for another time
* user load this activity, we should restore the former state
*/
+ //用于在Activity被系统销毁后恢复其状态
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
@@ -179,12 +530,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
+ //该方法主要用于初始化Activity的状态,根据传入的Intent的不同动作(action)执行不同的操作。
private boolean initActivityState(Intent intent) {
/**
* If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
* then jump to the NotesListActivity
*/
mWorkingNote = null;
+ //打开某个笔记的操作
if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
mUserQuery = "";
@@ -196,7 +549,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
}
-
+ //DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE) 是一个方法调用
+ // 用于检查给定的 noteId 是否存在于笔记数据库中
if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
Intent jump = new Intent(this, NotesListActivity.class);
startActivity(jump);
@@ -204,6 +558,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
finish();
return false;
} else {
+ //如果指定的笔记 ID 存在于笔记数据库中,则调用 WorkingNote.load() 方法,根据指定的笔记 ID 加载笔记对象,并将结果赋值给 mWorkingNote
mWorkingNote = WorkingNote.load(this, noteId);
if (mWorkingNote == null) {
Log.e(TAG, "load note failed with note id" + noteId);
@@ -215,7 +570,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
} else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
+ //需要创建或编辑一个笔记
// New note
+ //从 Intent 中获取一些额外的信息,如文件夹 ID、小部件 ID、小部件类型和背景资源 ID。这些信息用于确定新笔记的位置和外观。
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
@@ -268,6 +625,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
initNoteScreen();
}
+ //用于初始化笔记屏幕
private void initNoteScreen() {
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
@@ -293,6 +651,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* is not ready
*/
showAlertHeader();
+ convertToImage();
}
private void showAlertHeader() {
@@ -362,7 +721,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return true;
}
-
+ //初始化一些资源
private void initResources() {
mHeadViewPanel = findViewById(R.id.note_title);
mNoteHeaderHolder = new HeadViewHolder();
@@ -374,11 +733,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
+
+ //这段代码的作用是为sBgSelectorBtnsMap中的所有ImageView对象设置点击事件监听器。
+ // 当某个ImageView被点击时,会触发与当前类关联的onClick()方法。
+ //sBgSelectorBtnsMap是一个Map对象,它存储了一些键值对,其中每个sBgSelectorBtnsMap是一个Map对象,它存储了一些键值对,其中每个键对应一个ImageView对象的id,每个值则未在这段代码中给出。
+ // 这种数据结构通常用于在Android应用中存储和操作UI元素,例如这里的ImageView。
+ // 通过键(即ImageView的id),可以快速找到并操作对应的UI元素。
+ // 具体来说,这段代码遍历了sBgSelectorBtnsMap中的所有键,并为每个键对应的ImageView设置了一个点击事件监听器。
for (int id : sBgSelectorBtnsMap.keySet()) {
ImageView iv = (ImageView) findViewById(id);
iv.setOnClickListener(this);
}
-
mFontSizeSelector = findViewById(R.id.font_size_selector);
for (int id : sFontSizeBtnsMap.keySet()) {
View view = findViewById(id);
@@ -391,10 +756,150 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* The id may larger than the length of resources, in this case,
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
*/
+ //这段代码是用于获取应用程序的字体大小设置
if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
+ /*
+ 撤回部分
+ */
+ mNoteEditor.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after)
+ {
+
+ }
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
+ @Override
+ public void afterTextChanged(Editable s) {//文本更改后
+ if(!mIsRvoke) {
+ saveMyChanged();
+ }else {
+ mIsRvoke = false;
+ }
+ }
+ });
+
+ //翻译
+ doTranslate();
+ //朗读
+ mTTS = new TextToSpeech(this, new OnInitListener() {
+ @Override
+ public void onInit(int status) {
+ if (status == TextToSpeech.SUCCESS) {
+ mTTS.setLanguage(Locale.CHINESE);
+ mTTS.setPitch(1.5f);// 设置音调,值越大声音越尖(女生),值越小则变成男声,1.0是常规
+ mTTS.setSpeechRate(0.5f);
+ }
+
+ }
+ });
+ mHeadViewPanel = findViewById(R.id.note_title);
+ }
+
+
+ private void texttoSpeech(){
+ mTTS.speak(mNoteEditor.getText().toString(),TextToSpeech.QUEUE_FLUSH,null,null);
+ }
+ private void doRevoke(){
+ int size = mChanged.size();//获取当前栈大小
+ AlertDialog.Builder dialog = new AlertDialog.Builder(this);//创建一个alertdialog 窗口
+ dialog.setTitle(R.string.tips_of_revoke);//设置 title 信息
+ dialog.setCancelable(true);//设置为可取消
+ dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {//只需要设置一个 OK 键即可
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ });
+ mIsRvoke= true;
+ if(size<=1){//如果栈中元素过少,打印提示信息
+ dialog.setMessage(R.string.have_not_input_anything);//提示用户您还没有输入任何信息
+ dialog.show();//显示当前 alertdialog
+ return;
+ }
+ else {
+ mNoteEditor.setText((CharSequence) mChanged.elementAt(size-2));//在textview 中设置撤销的内容
+ mNoteEditor.setSelection(mNoteEditor.length());
+ mChanged.removeElementAt(size-1);//删除元素
+ if(size==2){
+ dialog.setMessage(R.string.can_not_revoke);//如果只有一次操作,那么提示用户不能再撤销了
+ dialog.show();//显示当前 alertdialog
+ }
+ }
+ }
+ private void saveMyChanged(){
+ SpannableString text = new SpannableString(mNoteEditor.getText());//用 getText方法获取每次编辑的内容
+ if(mChanged.size()>=MAX_TIME_OF_RVOKE_TIME){//如果栈中的数据大于最大撤销次数,就把第一次修改的内容删除
+ mChanged.removeElementAt(0);
+ }
+ mChanged.add(text);//然后把本次修改的内容加入栈中
+ }
+
+ public void showSingleAlertDialog(){
+ final String[] items = {"默认-普通","默认-非衬线","默认-衬线","默认-等宽","仿宋","黑体","楷体","隶书","微软雅黑"};
+ AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
+ alertBuilder.setTitle("请选择字体");
+ alertBuilder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ switch (i) {
+ case 0:
+ mNoteEditor.setTypeface(Typeface.DEFAULT);
+ break;
+ case 1:
+ mNoteEditor.setTypeface(Typeface.SANS_SERIF);
+ break;
+ case 2:
+ mNoteEditor.setTypeface(Typeface.SERIF);
+ break;
+ case 3:
+ mNoteEditor.setTypeface(Typeface.MONOSPACE);
+ break;
+ case 4:
+ Typeface typeface0 = Typeface.createFromAsset(getAssets(), "front/simfang.ttf");
+ mNoteEditor.setTypeface(typeface0);
+ break;
+ case 5:
+ Typeface typeface1 = Typeface.createFromAsset(getAssets(), "front/simhei.ttf");
+ mNoteEditor.setTypeface(typeface1);
+
+ break;
+ case 6:
+ Typeface typeface2 = Typeface.createFromAsset(getAssets(), "front/simkai.ttf");
+ mNoteEditor.setTypeface(typeface2);
+
+ break;
+ case 7:
+ Typeface typeface3 = Typeface.createFromAsset(getAssets(), "front/SIMLI.TTF");
+ mNoteEditor.setTypeface(typeface3);
+ break;
+ case 8:
+ Typeface typeface4 = Typeface.createFromAsset(getAssets(), "front/msyh.ttc");
+ mNoteEditor.setTypeface(typeface4);
+ break;
+ }
+ Toast.makeText(NoteEditActivity.this, items[i],Toast.LENGTH_SHORT).show();
+ }
+ });
+ alertBuilder.setPositiveButton("确定",new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ alertDialog2.dismiss();
+ }
+ });
+ alertBuilder.setNegativeButton("取消", new DialogInterface.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ alertDialog2.dismiss();
+ }
+ });
+ alertDialog2 = alertBuilder.create();
+ alertDialog2.show();
}
@Override
@@ -424,13 +929,19 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sendBroadcast(intent);
setResult(RESULT_OK, intent);
}
-
+ /*
+ 这段代码是一个事件处理函数,用于处理按钮点击事件。根据不同的按钮ID执行不同的操作。
+ */
public void onClick(View v) {
int id = v.getId();
+ //如果按钮ID等于R.id.btn_set_bg_color,则表示用户点击了设置背景颜色的按钮。
+ // 此时,将背景颜色选择器的可见性设置为可见,并显示当前选中的背景颜色对应的控件
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
+ //如果按钮ID在sBgSelectorBtnsMap中存在,表示用户点击了某个背景颜色按钮。
+ // 此时,隐藏当前选中的背景颜色对应的控件,将工作笔记的背景颜色设置为该按钮对应的ID,并将背景颜色选择器的可见性设置为不可见。
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id));
@@ -444,8 +955,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
getWorkingText();
switchToListMode(mWorkingNote.getContent());
} else {
- mNoteEditor.setTextAppearance(this,
- TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
+ mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
}
mFontSizeSelector.setVisibility(View.GONE);
}
@@ -479,6 +989,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
}
+ //该方法的主要作用是根据当前的工作笔记(mWorkingNote)的属性来准备和更新菜单项。
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (isFinishing()) {
@@ -486,6 +997,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
clearSettingState();
menu.clear();
+ //工作笔记的文件夹ID
if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) {
getMenuInflater().inflate(R.menu.call_note_edit, menu);
} else {
@@ -505,7 +1017,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
@Override
- //这段代码是一个用于处理菜单项点击事件的方法onOptionsItemSelected(MenuItem item),当用户点击菜单项时,会根据菜单项的ID执行相应的操作。以下是对代码的解释:
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.menu_new_note) {
@@ -524,8 +1035,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
- } else if (itemId == R.id.menu_font_size) {//修改字体的大小
- mFontSizeSelector.setVisibility(View.VISIBLE);
+ } else if (itemId == R.id.menu_font_size) {
+ mFontSizeSelector.setVisibility (View.VISIBLE);
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
} else if (itemId == R.id.menu_list_mode) {
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
@@ -539,24 +1050,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
setReminder();
} else if (itemId == R.id.menu_delete_remind) {
mWorkingNote.setAlertDate(0, false);
+ }else if(itemId == R.id.menu_revoke) {
+ doRevoke();
+ }else if(itemId == R.id.menu_voice_speech){
+ Log.d(TAG,"in");
+ texttoSpeech();
+ }else if(itemId == R.id.menu_font_setting){
+ showSingleAlertDialog();
}
+
+
return true;
}
-//onOptionsItemSelected方法是一个覆盖方法,用于在用户选择某个选项菜单项时被调用。
-//
-//在这段代码中,首先获取选项菜单项的ID,即itemId = item.getItemId()。
-//
-//然后使用if-else语句对不同的菜单项进行处理。
-//
-//若itemId等于R.id.menu_new_note,则调用createNewNote()方法。
-//若itemId等于R.id.menu_delete,则创建一个AlertDialog对话框,设置标题、图标和消息,并添加确定按钮和取消按钮的点击事件监听器,点击确定按钮时调用deleteCurrentNote()方法并结束当前活动。
-//若itemId等于R.id.menu_font_size,则设置字体大小选择器显示,并根据当前选中的字体大小ID找到对应的视图并设置其可见性为可见。
-//若itemId等于R.id.menu_list_mode,则切换工作笔记的清单模式(若当前为0,则切换为检查清单模式,否则切换为普通文本模式)。
-//若itemId等于R.id.menu_share,则获取当前工作笔记的文本内容,并将其发送到指定目标。
-//若itemId等于R.id.menu_send_to_desktop,则发送笔记到桌面。
-//若itemId等于R.id.menu_alert,则设置提醒事项。
-//若itemId等于R.id.menu_delete_remind,则将工作笔记的提醒日期设置为0,表示删除提醒。
-//最后,返回值为true,表示已经处理了选择的菜单项。
+
+
private void setReminder() {
DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis());
d.setOnDateTimeSetListener(new OnDateTimeSetListener() {
@@ -566,15 +1073,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
});
d.show();
}
-//这段代码定义了一个名为setReminder的私有方法,用于设置笔记的提醒时间。
-//
-//在方法内部,首先创建一个DateTimePickerDialog对象d,并将当前时间作为默认时间传递给该对象。
-//
-//接着,为d设置一个OnDateTimeSetListener监听器,当用户设置时间时,会调用该监听器的OnDateTimeSet方法。在该方法中,调用正在编辑的笔记对象mWorkingNote的setAlertDate方法,将用户设置的时间转换成毫秒值,并将其设置为笔记的提醒时间。
-//
-//最后,显示d对话框,让用户选择提醒时间。
-//
-//因此,这段代码用于弹出一个日期时间选择对话框,让用户设置笔记的提醒时间,并将设置的时间保存到正在编辑的笔记对象中。
+
/**
* Share note to apps that support {@link Intent#ACTION_SEND} action
* and {@text/plain} type
@@ -585,49 +1084,50 @@ public class NoteEditActivity extends Activity implements OnClickListener,
intent.setType("text/plain");
context.startActivity(intent);
}
-//这段代码是一个私有方法sendTo,用于使用系统默认的分享功能将指定的文本信息发送给其他应用程序。
-//
-//在方法内部,首先创建一个新的Intent对象,并将其动作设置为Intent.ACTION_SEND,表示发送内容。
-//
-//接着,通过putExtra方法将要分享的文本信息info放入Intent中,使用Intent.EXTRA_TEXT作为键。
-//
-//然后,使用setType方法将要分享的内容的MIME类型设置为"text/plain",表示纯文本类型。
-//
-//最后,通过context.startActivity(intent)启动该Intent,将文本信息发送给其他应用程序进行处理。
-//
-//因此,这段代码用于在给定的Context上下文环境中,利用系统默认的分享功能将特定的文本信息发送给其他应用程序。
-
- private void createNewNote() {//新建便签
+
+ private void createNewNote() {
// Firstly, save current editing notes
+ //保存当前便签
saveNote();
// For safety, start a new NoteEditActivity
finish();
+ //设置链接器
Intent intent = new Intent(this, NoteEditActivity.class);
+ //将该活动定义为创建或编辑
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
+ //将运行便签的id添加到INTENT_EXTRA_FOLDER_ID标记中
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId());
+ //开始活动并链接
startActivity(intent);
}
- private void deleteCurrentNote() {//删除便签
+ private void deleteCurrentNote() {
+ //假如当前运行的便签内存有数据
if (mWorkingNote.existInDatabase()) {
HashSet ids = new HashSet();
long id = mWorkingNote.getNoteId();
+ //如果不是头文件夹建立一个hash表把便签id存起来
if (id != Notes.ID_ROOT_FOLDER) {
ids.add(id);
} else {
Log.d(TAG, "Wrong note id, should not happen");
}
if (!isSyncMode()) {
+ //在非同步模式情况下
+ //删除操作
if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
Log.e(TAG, "Delete Note error");
}
} else {
+ //同步模式
+ //移动至垃圾文件夹的操作
if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) {
Log.e(TAG, "Move notes to trash folder error, should not happens");
}
}
}
+ //将这些标签的删除标记置为true
mWorkingNote.markDeleted(true);
}
@@ -827,15 +1327,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return hasChecked;
}
-//段代码是一个私有方法getWorkingText,用于获取工作笔记的文本内容,并根据是否为待办事项模式进行相应处理。同时,该方法返回一个布尔值,表示在待办事项模式下是否有选中的项目。
-//
-//在方法内部,首先检查当前工作笔记mWorkingNote是否为待办事项模式。如果是,就遍历所有子视图view,其中包含每个待办事项的复选框和文本编辑框。对于每个非空的文本编辑框,如果其相应的复选框被选中,则将文本内容作为已选中的待办事项添加到字符串缓冲区sb中,并将标记hasChecked设置为true;否则,将文本内容作为未选中的待办事项添加到字符串缓冲区sb中。
-//
-//最后,将字符串缓冲区sb中的内容作为工作笔记的文本内容设置到mWorkingNote对象中。如果不是待办事项模式,则将文本编辑器mNoteEditor中的文本内容设置为工作笔记的文本内容。
-//
-//最终,该方法返回一个布尔值hasChecked,表示在待办事项模式下是否有选中的项目。
-//
-//因此,这段代码用于获取工作笔记的文本内容,并根据是否为待办事项模式进行相应处理并返回结果。
+
private boolean saveNote() {
getWorkingText();
boolean saved = mWorkingNote.saveNote();
@@ -851,17 +1343,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
return saved;
}
-//这段代码是一个私有方法saveNote,用于保存当前正在编辑的笔记。
-//
-//在方法内部,首先调用getWorkingText方法获取当前正在编辑的笔记的文本内容,并将其保存到mWorkingNote对象中。
-//
-//接着,调用mWorkingNote.saveNote()方法将笔记保存到数据库中,并将保存结果保存到saved变量中。
-//
-//如果保存成功,则调用setResult(RESULT_OK)方法,设置当前Activity的返回状态为RESULT_OK。这个状态用于标识从编辑状态返回到列表视图时,是创建新笔记还是编辑已有笔记。
-//
-//最后,返回保存是否成功的布尔值。
-//
-//因此,这段代码用于将当前正在编辑的笔记保存到数据库中,并设置返回状态。
+
private void sendToDesktop() {
/**
* Before send message to home, we should make sure that current
@@ -896,33 +1378,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
showToast(R.string.error_note_empty_for_send_to_desktop);
}
}
-//这段代码定义了一个名为sendToDesktop的私有方法,用于将笔记发送到桌面。
-//
-//在方法内部,首先检查当前正在编辑的笔记是否存在于数据库中。如果笔记不存在于数据库中,则调用saveNote()方法保存笔记。
-//
-//接着,如果当前正在编辑的笔记具有有效的笔记ID(即大于0),则执行以下操作:
-//
-//创建一个Intent对象sender用于发送广播。
-//
-//创建一个Intent对象shortcutIntent,指定其目标为NoteEditActivity类,并设置动作为Intent.ACTION_VIEW。
-//
-//将正在编辑的笔记ID作为附加数据放入shortcutIntent中。
-//
-//将笔记内容生成适合作为快捷方式图标标题的字符串,并放入sender中作为附加数据。
-//
-//将应用程序的图标资源作为快捷方式图标放入sender中。
-//
-//设置sender的动作为com.android.launcher.action.INSTALL_SHORTCUT,表示要安装快捷方式。
-//
-//弹出一个简短的提示消息,提示用户笔记已经进入桌面。
-//
-//发送广播,安装快捷方式。
-//
-//如果当前正在编辑的笔记没有有效的笔记ID,则执行以下操作:
-//
-//输出一个错误日志,表示发送到桌面出错。
-//
-//弹出一个提示消息,提醒用户必须输入一些内容才能发送到桌面。
+
private String makeShortcutIconTitle(String content) {
content = content.replace(TAG_CHECKED, "");
content = content.replace(TAG_UNCHECKED, "");
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
index 766561d..8061ad2 100644
--- a/src/xiaomi/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
@@ -79,6 +79,10 @@ import java.io.InputStreamReader;
import java.util.HashSet;
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
+ /*
+ 用于首页背景切换的控制变量
+ */
+ private int background = -1;
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
private static final int FOLDER_LIST_QUERY_TOKEN = 1;
@@ -140,7 +144,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
initResources();
-
+ getWindow().setBackgroundDrawableResource(R.drawable.picture1);
/**
* Insert an introduction when user firstly use this application
*/
@@ -509,11 +513,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
Log.e(TAG, "Wrong folder id, should not happen " + folderId);
return;
}
-//该方法接收一个参数folderId,表示要删除的文件夹的ID。
-//
-//在方法内部,首先通过条件判断检查folderId是否等于Notes.ID_ROOT_FOLDER(根文件夹的ID)。如果是根文件夹的ID,则记录错误日志并返回,不执行删除操作。
-//
-//这段代码的作用是避免意外情况下删除根文件夹,因为根文件夹通常是系统的关键文件夹,不应该被删除。如果传入的folderId等于根文件夹的ID,会输出错误日志并直接返回,避免继续执行删除根文件夹的操作。
+
HashSet ids = new HashSet();
ids.add(folderId);
HashSet widgets = DataUtils.getFolderNoteWidget(mContentResolver,
@@ -558,21 +558,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
mTitleBar.setVisibility(View.VISIBLE);
}
-//该方法接收一个参数data,表示要打开的文件夹。
-//
-//首先,将当前文件夹的ID设置为参数data的ID,并调用startAsyncNotesListQuery()方法开始异步查询当前文件夹下的笔记列表。
-//
-//接下来,根据文件夹的ID判断当前状态:
-//
-//如果文件夹的ID为Notes.ID_CALL_RECORD_FOLDER,则将状态设置为ListEditState.CALL_RECORD_FOLDER,并隐藏添加新笔记按钮;
-//否则,将状态设置为ListEditState.SUB_FOLDER。
-//然后,根据文件夹的ID设置标题栏的文本:
-//
-//如果文件夹的ID为Notes.ID_CALL_RECORD_FOLDER,则设置标题栏的文本为字符串资源R.string.call_record_folder_name;
-//否则,设置标题栏的文本为文件夹的名称(通过调用data.getSnippet()方法获取)。
-//最后,将标题栏设置为可见状态。
-//
-//总之,这段代码实现了打开文件夹的功能,根据文件夹的ID设置不同的状态和标题,并更新UI显示。
public void onClick(View v) {
if (v.getId() == R.id.btn_new_note) {
@@ -591,7 +576,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
-
private void showCreateOrModifyFolderDialog(final boolean create) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null);
@@ -637,7 +621,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
values.put(NoteColumns.LOCAL_MODIFIED, 1);
mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID
+ "=?", new String[] {
- String.valueOf(mFocusNoteDataItem.getId())//获取文件夹名称,并设置对话框的标题为对应的修改文件夹名称;
+ String.valueOf(mFocusNoteDataItem.getId())
});
}
} else if (!TextUtils.isEmpty(name)) {
@@ -650,6 +634,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
});
+
if (TextUtils.isEmpty(etName.getText())) {
positive.setEnabled(false);
}
@@ -676,14 +661,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
});
}
-//该方法接收一个参数create,用于指示是创建文件夹还是修改文件夹。
-//
-//在方法内部,首先创建一个AlertDialog.Builder对象,并通过LayoutInflater从XML布局文件中实例化一个视图。
-// 获取EditText对象用于输入文件夹名称,并调用showSoftInput()方法显示软键盘。
-//
-//根据create参数的值,判断是创建文件夹还是修改文件夹。如果是修改文件夹,
-// 则从mFocusNoteDataItem中获取文件夹名称,并设置对话框的标题为对应的修改文件夹名称;
-// 如果是创建文件夹,则将EditText的文本设置为空,并设置对话框的标题为创建文件夹。
+
@Override
public void onBackPressed() {
switch (mState) {
@@ -795,6 +773,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
} else {
Log.e(TAG, "Wrong state:" + mState);
}
+
+ if (background == -1)
+ {
+ menu.findItem(R.id.menu_switch_to_picture3).setVisible(false);
+ }else if (background == 0){
+ menu.findItem(R.id.menu_switch_to_picture2).setVisible(false);
+ }else if (background == 1){
+ menu.findItem(R.id.menu_switch_to_picture3).setVisible(false);
+ }
return true;
}
@@ -821,34 +808,26 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
createNewNote();
} else if (itemId == R.id.menu_search) {
onSearchRequested();
+ }else if (itemId == R.id.menu_switch_to_picture3) {
+ background = 1;
+ getWindow().setBackgroundDrawableResource(R.drawable.picture1);
+ }else if (itemId == R.id.menu_switch_to_picture2) {
+ background = 0;
+ getWindow().setBackgroundDrawableResource(R.drawable.picture2);
+ }else if (itemId == R.id.menu_switch_to_picture1) {
+ background = -1;
+ getWindow().setBackgroundDrawableResource(R.drawable.picture3);
}
+
return true;
}
-//每当用户选择菜单项时,Android 系统会调用该方法,并传入被选中的菜单项(MenuItem)。该方法首先获取被选中菜单项的ID,然后根据不同的ID执行相应的操作。
-//
-//具体来说:
-//
-//如果选中的菜单项是R.id.menu_new_folder,则调用showCreateOrModifyFolderDialog(true)方法,显示创建或修改文件夹的对话框。
-//如果选中的菜单项是R.id.menu_export_text,则调用exportNoteToText()方法,将笔记导出为文本。
-//如果选中的菜单项是R.id.menu_sync,则根据当前是否处于同步模式(isSyncMode())分别启动或取消同步服务(GTaskSyncService)或打开设置活动(startPreferenceActivity)。
-//如果选中的菜单项是R.id.menu_setting,则打开设置活动(startPreferenceActivity)。
-//如果选中的菜单项是R.id.menu_new_note,则创建新的笔记(createNewNote)。
-//如果选中的菜单项是R.id.menu_search,则执行搜索请求(onSearchRequested)。
-//最后,该方法返回true,表示菜单项的选择事件已经得到处理。
-//
-//总之,该方法根据用户选择的菜单项执行不同的操作,包括创建新文件夹、导出笔记、同步服务控制、打开设置活动、创建新笔记和执行搜索请求等。
+
@Override
public boolean onSearchRequested() {
startSearch(null, false, null /* appData */, false);
return true;
}
-//nSearchRequested方法是一个覆盖方法,用于在用户点击搜索按钮或者执行搜索手势时被调用。
-//
-//在这段代码中,首先调用了startSearch方法来启动搜索功能。startSearch方法接受四个参数:搜索关键字(null表示没有指定关键字),是否全局搜索(false表示只搜索当前应用程序),应用程序数据(null表示没有额外的应用程序数据),以及是否由用户触发的搜索(false表示不是由用户触发)。
-//
-//然后,返回值为true,表示该方法已经处理了搜索请求,并不需要其他的默认处理。
-//
-//总之,该代码片段实现了在搜索请求时调用startSearch方法,并返回true表示已经处理了该搜索请求。
+
private void exportNoteToText() {
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
new AsyncTask() {
@@ -890,18 +869,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}.execute();
}
-//首先,定义了一个名为exportNoteToText的私有方法,没有任何参数。
-//
-//在该方法中,首先通过BackupUtils.getInstance(NotesListActivity.this)获取一个备份工具类的实例。然后创建一个异步任务(AsyncTask)来执行导出操作。
-//
-//在异步任务的doInBackground方法中,调用backup.exportToText()方法来执行导出操作,并返回一个结果值。
-//
-//在异步任务的onPostExecute方法中,根据导出的结果值进行不同的处理:
-//
-//如果结果值等于BackupUtils.STATE_SD_CARD_UNMOUONTED,表示SD卡未挂载,弹出一个对话框提示导出失败和SD卡未挂载的错误信息。
-//如果结果值等于BackupUtils.STATE_SUCCESS,表示导出成功,弹出一个对话框提示导出成功和导出文件的位置信息。
-//如果结果值等于BackupUtils.STATE_SYSTEM_ERROR,表示导出失败,弹出一个对话框提示导出失败的错误信息。
-//在最后,通过调用execute方法来执行异步任务。
+
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
}
diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/ui/SplashActivity.java b/src/xiaomi/Notes-master/src/net/micode/notes/ui/SplashActivity.java
new file mode 100644
index 0000000..39d995d
--- /dev/null
+++ b/src/xiaomi/Notes-master/src/net/micode/notes/ui/SplashActivity.java
@@ -0,0 +1,36 @@
+package net.micode.notes.ui;
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowInsets;
+
+import net.micode.notes.databinding.ActivitySplashBinding;
+import net.micode.notes.R;
+
+public class SplashActivity extends AppCompatActivity {
+ Handler mHandler=new Handler();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState); //加载启动界面
+ setContentView(R.layout.activity_splash); //加载启动图片
+
+ // 当计时结束时,跳转至NotesListActivity
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ Intent intent=new Intent();
+ intent.setClass(SplashActivity.this, NotesListActivity.class);
+ startActivity(intent);
+ finish(); //销毁欢迎页面
+ }
+ }, 2000); // 2 秒后跳转
+ }
+}
\ No newline at end of file