diff --git a/张凇禹.zip b/张凇禹.zip
deleted file mode 100644
index 2ffbb7b..0000000
Binary files a/张凇禹.zip and /dev/null differ
diff --git a/源程序代码-小米便签-Notes-master.zip b/源程序代码-小米便签-Notes-master.zip
deleted file mode 100644
index e40026f..0000000
Binary files a/源程序代码-小米便签-Notes-master.zip and /dev/null differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/.gitignore b/源程序代码-小米便签-Notes-master/Notes-master/.gitignore
new file mode 100644
index 0000000..7df8dff
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/.gitignore
@@ -0,0 +1,9 @@
+# generated files
+bin/
+gen/
+
+# Local configuration file (sdk path, etc)
+project.properties
+.settings/
+.classpath
+.project
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/AndroidManifest.xml b/源程序代码-小米便签-Notes-master/Notes-master/AndroidManifest.xml
new file mode 100644
index 0000000..e5c7d47
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/AndroidManifest.xml
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/NOTICE b/源程序代码-小米便签-Notes-master/Notes-master/NOTICE
new file mode 100644
index 0000000..9a54521
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/README b/源程序代码-小米便签-Notes-master/Notes-master/README
new file mode 100644
index 0000000..fc0d824
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/README
@@ -0,0 +1,23 @@
+[中文]
+
+1. MiCode便签是小米便签的社区开源版,由MIUI团队(www.miui.com) 发起并贡献第一批代码,遵循NOTICE文件所描述的开源协议,
+ 今后为MiCode社区(www.micode.net) 拥有,并由社区发布和维护。
+
+2. Bug反馈和跟踪,请访问Github,
+ https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
+
+3. 功能建议和综合讨论,请访问MiCode,
+ http://micode.net/forum.php?mod=forumdisplay&fid=38
+
+
+[English]
+
+1. MiCode Notes is open source edition of XM notepad, it's first initiated and sponsored by MIUI team (www.miui.com).
+ It's opened under license described by NOTICE file. It's owned by the MiCode community (www.micode.net). In future,
+ the MiCode community will release and maintain this project.
+
+2. Regarding issue tracking, please visit Github,
+ https://github.com/MiCode/Notes/issues?sort=created&direction=desc&state=open
+
+3. Regarding feature request and general discussion, please visit Micode forum,
+ http://micode.net/forum.php?mod=forumdisplay&fid=38
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/color/primary_text_dark.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/color/primary_text_dark.xml
new file mode 100644
index 0000000..7c85459
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/color/primary_text_dark.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/color/secondary_text_dark.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/color/secondary_text_dark.xml
new file mode 100644
index 0000000..c1c2384
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/color/secondary_text_dark.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/bg_btn_set_color.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/bg_btn_set_color.png
new file mode 100644
index 0000000..5eb5d44
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/bg_btn_set_color.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/bg_color_btn_mask.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/bg_color_btn_mask.png
new file mode 100644
index 0000000..100db77
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/bg_color_btn_mask.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/call_record.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/call_record.png
new file mode 100644
index 0000000..fb88ca4
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/call_record.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/clock.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/clock.png
new file mode 100644
index 0000000..5f2ae9a
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/clock.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/delete.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/delete.png
new file mode 100644
index 0000000..643de3e
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/delete.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/dropdown_icon.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/dropdown_icon.9.png
new file mode 100644
index 0000000..5525025
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/dropdown_icon.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_blue.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_blue.9.png
new file mode 100644
index 0000000..55a1856
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_blue.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_green.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_green.9.png
new file mode 100644
index 0000000..2cb2d60
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_green.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_red.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_red.9.png
new file mode 100644
index 0000000..bae944a
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_red.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_blue.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_blue.9.png
new file mode 100644
index 0000000..96e6092
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_blue.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_green.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_green.9.png
new file mode 100644
index 0000000..08d8644
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_green.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_red.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_red.9.png
new file mode 100644
index 0000000..9c430e5
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_red.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_white.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_white.9.png
new file mode 100644
index 0000000..19e8d95
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_white.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_yellow.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_yellow.9.png
new file mode 100644
index 0000000..bf8f580
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_title_yellow.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_white.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_white.9.png
new file mode 100644
index 0000000..918f7a6
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_white.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_yellow.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_yellow.9.png
new file mode 100644
index 0000000..10cb642
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/edit_yellow.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_large.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_large.png
new file mode 100644
index 0000000..78cf2e6
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_large.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_normal.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_normal.png
new file mode 100644
index 0000000..9de7ced
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_normal.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_size_selector_bg.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_size_selector_bg.9.png
new file mode 100644
index 0000000..be8e64c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_size_selector_bg.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_small.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_small.png
new file mode 100644
index 0000000..d3ff104
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_small.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_super.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_super.png
new file mode 100644
index 0000000..85b13a1
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/font_super.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/icon_app.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/icon_app.png
new file mode 100644
index 0000000..418aadc
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/icon_app.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_background.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_background.png
new file mode 100644
index 0000000..087e1f9
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_background.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_down.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_down.9.png
new file mode 100644
index 0000000..b88eebf
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_down.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_middle.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_middle.9.png
new file mode 100644
index 0000000..96b1c8b
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_middle.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_single.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_single.9.png
new file mode 100644
index 0000000..d7e7206
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_single.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_up.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_up.9.png
new file mode 100644
index 0000000..632e88c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_blue_up.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_folder.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_folder.9.png
new file mode 100644
index 0000000..829f61b
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_folder.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_footer_bg.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_footer_bg.9.png
new file mode 100644
index 0000000..5325c25
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_footer_bg.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_down.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_down.9.png
new file mode 100644
index 0000000..64a39d9
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_down.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_middle.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_middle.9.png
new file mode 100644
index 0000000..897325a
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_middle.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_single.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_single.9.png
new file mode 100644
index 0000000..c83405f
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_single.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_up.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_up.9.png
new file mode 100644
index 0000000..141f9e1
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_green_up.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_down.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_down.9.png
new file mode 100644
index 0000000..4224309
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_down.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_middle.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_middle.9.png
new file mode 100644
index 0000000..9988f17
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_middle.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_single.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_single.9.png
new file mode 100644
index 0000000..587c348
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_single.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_up.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_up.9.png
new file mode 100644
index 0000000..46b4757
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_red_up.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_down.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_down.9.png
new file mode 100644
index 0000000..29f9d8c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_down.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_middle.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_middle.9.png
new file mode 100644
index 0000000..77a4ab4
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_middle.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_single.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_single.9.png
new file mode 100644
index 0000000..3e79189
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_single.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_up.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_up.9.png
new file mode 100644
index 0000000..e23cd5c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_white_up.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_down.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_down.9.png
new file mode 100644
index 0000000..31cfc1e
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_down.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_middle.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_middle.9.png
new file mode 100644
index 0000000..b6549b2
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_middle.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_single.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_single.9.png
new file mode 100644
index 0000000..3faf507
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_single.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_up.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_up.9.png
new file mode 100644
index 0000000..4ae791c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/list_yellow_up.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/menu_delete.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/menu_delete.png
new file mode 100644
index 0000000..ccdfc4b
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/menu_delete.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/menu_move.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/menu_move.png
new file mode 100644
index 0000000..1140b71
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/menu_move.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/new_note_normal.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/new_note_normal.png
new file mode 100644
index 0000000..e24e0d1
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/new_note_normal.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/new_note_pressed.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/new_note_pressed.png
new file mode 100644
index 0000000..c748936
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/new_note_pressed.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/note_edit_color_selector_panel.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/note_edit_color_selector_panel.png
new file mode 100644
index 0000000..fc49552
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/note_edit_color_selector_panel.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/notification.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/notification.png
new file mode 100644
index 0000000..b13ab4a
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/notification.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/search_result.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/search_result.png
new file mode 100644
index 0000000..ff2befd
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/search_result.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/selected.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/selected.png
new file mode 100644
index 0000000..b889bef
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/selected.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/title_alert.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/title_alert.png
new file mode 100644
index 0000000..544ee9c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/title_alert.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/title_bar_bg.9.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/title_bar_bg.9.png
new file mode 100644
index 0000000..eb6bff0
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/title_bar_bg.9.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_blue.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_blue.png
new file mode 100644
index 0000000..a1707f4
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_blue.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_green.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_green.png
new file mode 100644
index 0000000..f86886c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_green.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_red.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_red.png
new file mode 100644
index 0000000..0e66c29
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_red.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_white.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_white.png
new file mode 100644
index 0000000..5f0619a
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_white.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_yellow.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_yellow.png
new file mode 100644
index 0000000..12d1c2b
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_2x_yellow.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_blue.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_blue.png
new file mode 100644
index 0000000..9183738
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_blue.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_green.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_green.png
new file mode 100644
index 0000000..fa8b452
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_green.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_red.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_red.png
new file mode 100644
index 0000000..62de074
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_red.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_white.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_white.png
new file mode 100644
index 0000000..a37d67c
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_white.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_yellow.png b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_yellow.png
new file mode 100644
index 0000000..d7c5fa4
Binary files /dev/null and b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable-hdpi/widget_4x_yellow.png differ
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/drawable/new_note.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable/new_note.xml
new file mode 100644
index 0000000..2154ebc
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/drawable/new_note.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/account_dialog_title.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/account_dialog_title.xml
new file mode 100644
index 0000000..7717112
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/account_dialog_title.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/add_account_text.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/add_account_text.xml
new file mode 100644
index 0000000..c799178
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/add_account_text.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/datetime_picker.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/datetime_picker.xml
new file mode 100644
index 0000000..f10d592
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/datetime_picker.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/dialog_edit_text.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/dialog_edit_text.xml
new file mode 100644
index 0000000..361b39a
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/dialog_edit_text.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/folder_list_item.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/folder_list_item.xml
new file mode 100644
index 0000000..77e8148
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/folder_list_item.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_edit.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_edit.xml
new file mode 100644
index 0000000..10b2aa7
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_edit.xml
@@ -0,0 +1,400 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_edit_list_item.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_edit_list_item.xml
new file mode 100644
index 0000000..a885f9c
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_edit_list_item.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_item.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_item.xml
new file mode 100644
index 0000000..d541f6a
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_item.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list.xml
new file mode 100644
index 0000000..6b25d38
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list_dropdown_menu.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list_dropdown_menu.xml
new file mode 100644
index 0000000..3fa271d
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list_dropdown_menu.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list_footer.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list_footer.xml
new file mode 100644
index 0000000..5ca7b22
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/note_list_footer.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/settings_header.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/settings_header.xml
new file mode 100644
index 0000000..5eb8c50
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/settings_header.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/widget_2x.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/widget_2x.xml
new file mode 100644
index 0000000..55970ce
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/widget_2x.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/layout/widget_4x.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/widget_4x.xml
new file mode 100644
index 0000000..dc9bb51
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/layout/widget_4x.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/call_note_edit.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/call_note_edit.xml
new file mode 100644
index 0000000..02c0528
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/call_note_edit.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/call_record_folder.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/call_record_folder.xml
new file mode 100644
index 0000000..c664346
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/call_record_folder.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_edit.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_edit.xml
new file mode 100644
index 0000000..35cacd1
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_edit.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list.xml
new file mode 100644
index 0000000..42ea736
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list_dropdown.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list_dropdown.xml
new file mode 100644
index 0000000..7cbaadc
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list_dropdown.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list_options.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list_options.xml
new file mode 100644
index 0000000..daac008
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/note_list_options.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/menu/sub_folder.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/sub_folder.xml
new file mode 100644
index 0000000..b00de26
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/menu/sub_folder.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/raw-zh-rCN/introduction b/源程序代码-小米便签-Notes-master/Notes-master/res/raw-zh-rCN/introduction
new file mode 100644
index 0000000..7188359
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/raw-zh-rCN/introduction
@@ -0,0 +1,7 @@
+欢迎使用MIUI便签!
+
+ 无论从软件中直接添加,还是从桌面拖出widget,MIUI便签能让你快速建立和保存便签;
+
+ 除了调整文字大小、便签背景、文件夹等基础功能外,你会发现MIUI便签也提供了清单模式、便签提醒、软件加密、导出到SD卡、同步google task的高级功能,让你的生活记录更加美好和安全;
+
+ 来分享你的使用体验吧:http://www.miui.com/index.php
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/raw/introduction b/源程序代码-小米便签-Notes-master/Notes-master/res/raw/introduction
new file mode 100644
index 0000000..269cf7b
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/raw/introduction
@@ -0,0 +1 @@
+Welcome to use MIUI notes!
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rCN/arrays.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rCN/arrays.xml
new file mode 100644
index 0000000..a092386
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rCN/arrays.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ 短信
+ 邮件
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rCN/strings.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..09f75ed
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rCN/strings.xml
@@ -0,0 +1,126 @@
+
+
+
+
+
+ 便签
+ 便签2x2
+ 便签4x4
+ 没有关联内容,点击新建便签。
+ 访客模式下,便签内容不可见
+ ...
+ 新建便签
+ 成功删除提醒
+ 创建提醒
+ 已过期
+ yyyyMMdd
+ MM月dd日 kk:mm
+ 知道了
+ 查看
+ 呼叫电话
+ 发送邮件
+ 浏览网页
+ 打开地图
+
+ 新建文件夹
+ 导出文本
+ 同步
+ 取消同步
+ 设置
+ 搜索
+ 删除
+ 移动到文件夹
+ 选中了 %d 项
+ 没有选中项,操作无效
+ 全选
+ 取消全选
+ 文字大小
+ 小
+ 正常
+ 大
+ 超大
+ 进入清单模式
+ 退出清单模式
+ 查看文件夹
+ 刪除文件夹
+ 修改文件夹名称
+ 文件夹 %1$s 已存在,请重新命名
+ 分享
+ 发送到桌面
+ 提醒我
+ 删除提醒
+ 选择文件夹
+ 上一级文件夹
+ 已添加到桌面
+ 删除
+ 确认要删除所选的 %d 条便签吗?
+ 确认要删除该条便签吗?
+ 确认删除文件夹及所包含的便签吗?
+ 已将所选 %1$d 条便签移到 %2$s 文件夹
+
+ SD卡被占用,不能操作
+ 导出文本时发生错误,请检查SD卡
+ 要查看的便签不存在
+ 不能为空便签设置闹钟提醒
+ 不能将空便签发送到桌面
+ 导出成功
+ 导出失败
+ 已将文本文件(%1$s)输出至SD卡(%2$s)目录
+
+ 同步便签...
+ 同步成功
+ 同步失败
+ 同步已取消
+ 与%1$s同步成功
+ 同步失败,请检查网络和帐号设置
+ 同步失败,发生内部错误
+ 同步已取消
+ 登录%1$s...
+ 正在获取服务器便签列表...
+ 正在同步本地便签...
+
+ 设置
+ 同步账号
+ 与google task同步便签记录
+ 上次同步于 %1$s
+ 添加账号
+ 更换账号
+ 删除账号
+ 取消
+ 立即同步
+ 取消同步
+ 当前帐号 %1$s
+ 如更换同步帐号,过去的帐号同步信息将被清空,再次切换的同时可能会造成数据重复
+ 同步便签
+ 请选择google帐号,便签将与该帐号的google task内容同步。
+ 正在同步中,不能修改同步帐号
+ 同步帐号已设置为%1$s
+ 新建便签背景颜色随机
+ 删除
+ 通话便签
+ 请输入名称
+ 正在搜索便签
+ 搜索便签
+ 便签中的文字
+ 便签
+ 设置
+ 取消
+
+ %1$s 条符合“%2$s”的搜索结果
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rTW/arrays.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rTW/arrays.xml
new file mode 100644
index 0000000..5297209
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rTW/arrays.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ 短信
+ 郵件
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rTW/strings.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..3c41894
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values-zh-rTW/strings.xml
@@ -0,0 +1,127 @@
+
+
+
+
+
+ 便簽
+ 便簽2x2
+ 便簽4x4
+ 沒有關聯內容,點擊新建便簽。
+ 訪客模式下,便籤內容不可見
+ ...
+ 新建便簽
+ 成功刪除提醒
+ 創建提醒
+ 已過期
+ yyyyMMdd
+ MM月dd日 kk:mm
+ 知道了
+ 查看
+ 呼叫電話
+ 發送郵件
+ 浏覽網頁
+ 打開地圖
+ 已將所選 %1$d 便籤移到 %2$s 文件夾
+
+ 新建文件夾
+ 導出文本
+ 同步
+ 取消同步
+ 設置
+ 搜尋
+ 刪除
+ 移動到文件夾
+ 選中了 %d 項
+ 沒有選中項,操作無效
+ 全選
+ 取消全選
+ 文字大小
+ 小
+ 正常
+ 大
+ 超大
+ 進入清單模式
+ 退出清單模式
+ 查看文件夾
+ 刪除文件夾
+ 修改文件夾名稱
+ 文件夾 %1$s 已存在,請重新命名
+ 分享
+ 發送到桌面
+ 提醒我
+ 刪除提醒
+ 選擇文件夾
+ 上一級文件夾
+ 已添加到桌面
+ 刪除
+ 确认要刪除所選的 %d 條便籤嗎?
+ 确认要删除該條便籤嗎?
+ 確認刪除檔夾及所包含的便簽嗎?
+ SD卡被佔用,不能操作
+ 導出TXT時發生錯誤,請檢查SD卡
+ 要查看的便籤不存在
+ 不能爲空便籤設置鬧鐘提醒
+ 不能將空便籤發送到桌面
+ 導出成功
+ 導出失敗
+ 已將文本文件(%1$s)導出至SD(%2$s)目錄
+
+ 同步便簽...
+ 同步成功
+ 同步失敗
+ 同步已取消
+ 與%1$s同步成功
+ 同步失敗,請檢查網絡和帳號設置
+ 同步失敗,發生內部錯誤
+ 同步已取消
+ 登陸%1$s...
+ 正在獲取服務器便籤列表...
+ 正在同步本地便籤...
+
+ 設置
+ 同步賬號
+ 与google task同步便簽記錄
+ 上次同步于 %1$s
+ 添加賬號
+ 更換賬號
+ 刪除賬號
+ 取消
+ 立即同步
+ 取消同步
+ 當前帳號 %1$s
+ 如更換同步帳號,過去的帳號同步信息將被清空,再次切換的同時可能會造成數據重復
+ 同步便簽
+ 請選擇google帳號,便簽將與該帳號的google task內容同步。
+ 正在同步中,不能修改同步帳號
+ 同步帳號已設置為%1$s
+ 新建便籤背景顏色隨機
+
+ 刪除
+ 通話便籤
+ 請輸入名稱
+
+ 正在搜索便籤
+ 搜索便籤
+ 便籤中的文字
+ 便籤
+ 設置
+ 取消
+
+ %1$s 條符合”%2$s“的搜尋結果
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values/arrays.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values/arrays.xml
new file mode 100644
index 0000000..e00210b
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values/arrays.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ -%s
+ --%s
+ --%s
+ --%s
+
+
+
+ Messaging
+ Email
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values/colors.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values/colors.xml
new file mode 100644
index 0000000..123ffbf
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values/colors.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+ #335b5b5b
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values/dimens.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values/dimens.xml
new file mode 100644
index 0000000..194e84f
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values/dimens.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ 33sp
+ 26sp
+ 20sp
+ 17sp
+ 14sp
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values/strings.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values/strings.xml
new file mode 100644
index 0000000..55df868
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values/strings.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+ Notes
+ Notes 2x2
+ Notes 4x4
+ No associated note found, click to create associated note.
+ Privacy mode,can not see note content
+ ...
+ Add note
+ Delete reminder successfully
+ Set reminder
+ Expired
+ yyyyMMdd
+ MMMd kk:mm
+ Got it
+ Take a look
+ Call
+ Send email
+ Browse web
+ Open map
+
+ /MIUI/notes/
+ notes_%s.txt
+
+ (%d)
+ New Folder
+ Export text
+ Sync
+ Cancel syncing
+ Settings
+ Search
+ Delete
+ Move to folder
+ %d selected
+ Nothing selected, the operation is invalid
+ Select all
+ Deselect all
+ Font size
+ Small
+ Medium
+ Large
+ Super
+ Enter check list
+ Leave check list
+ View folder
+ Delete folder
+ Change folder name
+ The folder %1$s exist, please rename
+ Share
+ Send to home
+ Remind me
+ Delete reminder
+ Select folder
+ Parent folder
+ Note added to home
+ Confirm to delete folder and its notes?
+ Delete selected notes
+ Confirm to delete the selected %d notes?
+ Confirm to delete this note?
+ Have moved selected %1$d notes to %2$s folder
+
+ SD card busy, not available now
+ Export failed, please check SD card
+ The note is not exist
+ Sorry, can not set clock on empty note
+ Sorry, can not send and empty note to home
+ Export successful
+ Export fail
+ Export text file (%1$s) to SD (%2$s) directory
+
+ Syncing notes...
+ Sync is successful
+ Sync is failed
+ Sync is canceled
+ Sync is successful with account %1$s
+ Sync failed, please check network and account settings
+ Sync failed, internal error occurs
+ Sync is canceled
+ Logging into %1$s...
+ Getting remote note list...
+ Synchronize local notes with Google Task...
+
+ Settings
+ Sync account
+ Sync notes with google task
+ Last sync time %1$s
+ yyyy-MM-dd hh:mm:ss
+ Add account
+ Change sync account
+ Remove sync account
+ Cancel
+ Sync immediately
+ Cancel syncing
+ Current account %1$s
+ All sync related information will be deleted, which may result in duplicated items sometime
+ Sync notes
+ Please select a google account. Local notes will be synced with google task.
+ Cannot change the account because sync is in progress
+ %1$s has been set as the sync account
+ New note background color random
+
+ Delete
+ Call notes
+ Input name
+
+ Searching Notes
+ Search notes
+ Text in your notes
+ Notes
+ set
+ cancel
+
+ %1$s result for \"%2$s\"
+
+ %1$s results for \"%2$s\"
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/values/styles.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/values/styles.xml
new file mode 100644
index 0000000..d750e65
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/values/styles.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/xml/preferences.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/preferences.xml
new file mode 100644
index 0000000..fe58f8f
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/preferences.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/xml/searchable.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/searchable.xml
new file mode 100644
index 0000000..bf74f14
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/searchable.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/xml/widget_2x_info.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/widget_2x_info.xml
new file mode 100644
index 0000000..ac8b225
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/widget_2x_info.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/res/xml/widget_4x_info.xml b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/widget_4x_info.xml
new file mode 100644
index 0000000..cf79f9c
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/res/xml/widget_4x_info.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/Contact.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/Contact.java
new file mode 100644
index 0000000..d97ac5d
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/Contact.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.data;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Data;
+import android.telephony.PhoneNumberUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+
+public class Contact {
+ private static HashMap sContactCache;
+ private static final String TAG = "Contact";
+
+ private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER
+ + ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
+ + " AND " + Data.RAW_CONTACT_ID + " IN "
+ + "(SELECT raw_contact_id "
+ + " FROM phone_lookup"
+ + " WHERE min_match = '+')";
+
+ public static String getContact(Context context, String phoneNumber) {
+ if(sContactCache == null) {
+ sContactCache = new HashMap();
+ }
+
+ if(sContactCache.containsKey(phoneNumber)) {
+ return sContactCache.get(phoneNumber);
+ }
+
+ String selection = CALLER_ID_SELECTION.replace("+",
+ PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
+ Cursor cursor = context.getContentResolver().query(
+ Data.CONTENT_URI,
+ new String [] { Phone.DISPLAY_NAME },
+ selection,
+ new String[] { phoneNumber },
+ null);
+
+ if (cursor != null && cursor.moveToFirst()) {
+ try {
+ String name = cursor.getString(0);
+ sContactCache.put(phoneNumber, name);
+ return name;
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, " Cursor get string error " + e.toString());
+ return null;
+ } finally {
+ cursor.close();
+ }
+ } else {
+ Log.d(TAG, "No contact matched with number:" + phoneNumber);
+ return null;
+ }
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/Notes.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/Notes.java
new file mode 100644
index 0000000..f240604
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/Notes.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.data;
+
+import android.net.Uri;
+public class Notes {
+ public static final String AUTHORITY = "micode_notes";
+ public static final String TAG = "Notes";
+ public static final int TYPE_NOTE = 0;
+ public static final int TYPE_FOLDER = 1;
+ public static final int TYPE_SYSTEM = 2;
+
+ /**
+ * Following IDs are system folders' identifiers
+ * {@link Notes#ID_ROOT_FOLDER } is default folder
+ * {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder
+ * {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records
+ */
+ public static final int ID_ROOT_FOLDER = 0;
+ public static final int ID_TEMPARAY_FOLDER = -1;
+ public static final int ID_CALL_RECORD_FOLDER = -2;
+ public static final int ID_TRASH_FOLER = -3;
+
+ public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";
+ public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";
+ public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id";
+ public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type";
+ public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id";
+ public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date";
+
+ public static final int TYPE_WIDGET_INVALIDE = -1;
+ public static final int TYPE_WIDGET_2X = 0;
+ public static final int TYPE_WIDGET_4X = 1;
+
+ public static class DataConstants {
+ public static final String NOTE = TextNote.CONTENT_ITEM_TYPE;
+ public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE;
+ }
+
+ /**
+ * Uri to query all notes and folders
+ */
+ public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");
+
+ /**
+ * Uri to query data
+ */
+ public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");
+
+ public interface NoteColumns {
+ /**
+ * The unique ID for a row
+ *
Type: INTEGER (long)
+ */
+ public static final String ID = "_id";
+
+ /**
+ * The parent's id for note or folder
+ *
Type: INTEGER (long)
+ */
+ public static final String PARENT_ID = "parent_id";
+
+ /**
+ * Created data for note or folder
+ *
Type: INTEGER (long)
+ */
+ public static final String CREATED_DATE = "created_date";
+
+ /**
+ * Latest modified date
+ *
Type: INTEGER (long)
+ */
+ public static final String MODIFIED_DATE = "modified_date";
+
+
+ /**
+ * Alert date
+ *
Type: INTEGER (long)
+ */
+ public static final String ALERTED_DATE = "alert_date";
+
+ /**
+ * Folder's name or text content of note
+ *
Type: TEXT
+ */
+ public static final String SNIPPET = "snippet";
+
+ /**
+ * Note's widget id
+ *
Type: INTEGER (long)
+ */
+ public static final String WIDGET_ID = "widget_id";
+
+ /**
+ * Note's widget type
+ *
Type: INTEGER (long)
+ */
+ public static final String WIDGET_TYPE = "widget_type";
+
+ /**
+ * Note's background color's id
+ *
Type: INTEGER (long)
+ */
+ public static final String BG_COLOR_ID = "bg_color_id";
+
+ /**
+ * For text note, it doesn't has attachment, for multi-media
+ * note, it has at least one attachment
+ *
Type: INTEGER
+ */
+ public static final String HAS_ATTACHMENT = "has_attachment";
+
+ /**
+ * Folder's count of notes
+ *
Type: INTEGER (long)
+ */
+ public static final String NOTES_COUNT = "notes_count";
+
+ /**
+ * The file type: folder or note
+ *
Type: INTEGER
+ */
+ public static final String TYPE = "type";
+
+ /**
+ * The last sync id
+ *
Type: INTEGER (long)
+ */
+ public static final String SYNC_ID = "sync_id";
+
+ /**
+ * Sign to indicate local modified or not
+ *
Type: INTEGER
+ */
+ public static final String LOCAL_MODIFIED = "local_modified";
+
+ /**
+ * Original parent id before moving into temporary folder
+ *
Type : INTEGER
+ */
+ public static final String ORIGIN_PARENT_ID = "origin_parent_id";
+
+ /**
+ * The gtask id
+ *
Type : TEXT
+ */
+ public static final String GTASK_ID = "gtask_id";
+
+ /**
+ * The version code
+ *
Type : INTEGER (long)
+ */
+ public static final String VERSION = "version";
+ }
+
+ public interface DataColumns {
+ /**
+ * The unique ID for a row
+ *
Type: INTEGER (long)
+ */
+ public static final String ID = "_id";
+
+ /**
+ * The MIME type of the item represented by this row.
+ *
Type: Text
+ */
+ public static final String MIME_TYPE = "mime_type";
+
+ /**
+ * The reference id to note that this data belongs to
+ *
Type: INTEGER (long)
+ */
+ public static final String NOTE_ID = "note_id";
+
+ /**
+ * Created data for note or folder
+ *
Type: INTEGER (long)
+ */
+ public static final String CREATED_DATE = "created_date";
+
+ /**
+ * Latest modified date
+ *
Type: INTEGER (long)
+ */
+ public static final String MODIFIED_DATE = "modified_date";
+
+ /**
+ * Data's content
+ *
Type: TEXT
+ */
+ public static final String CONTENT = "content";
+
+
+ /**
+ * Generic data column, the meaning is {@link #MIMETYPE} specific, used for
+ * integer data type
+ *
Type: INTEGER
+ */
+ public static final String DATA1 = "data1";
+
+ /**
+ * Generic data column, the meaning is {@link #MIMETYPE} specific, used for
+ * integer data type
+ *
Type: INTEGER
+ */
+ public static final String DATA2 = "data2";
+
+ /**
+ * Generic data column, the meaning is {@link #MIMETYPE} specific, used for
+ * TEXT data type
+ *
Type: TEXT
+ */
+ public static final String DATA3 = "data3";
+
+ /**
+ * Generic data column, the meaning is {@link #MIMETYPE} specific, used for
+ * TEXT data type
+ *
Type: TEXT
+ */
+ public static final String DATA4 = "data4";
+
+ /**
+ * Generic data column, the meaning is {@link #MIMETYPE} specific, used for
+ * TEXT data type
+ *
Type: TEXT
+ */
+ public static final String DATA5 = "data5";
+ }
+
+ public static final class TextNote implements DataColumns {
+ /**
+ * Mode to indicate the text in check list mode or not
+ *
Type: Integer 1:check list mode 0: normal mode
+ */
+ public static final String MODE = DATA1;
+
+ public static final int MODE_CHECK_LIST = 1;
+
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note";
+
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note";
+
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");
+ }
+
+ public static final class CallNote implements DataColumns {
+ /**
+ * Call date for this record
+ *
Type: INTEGER (long)
+ */
+ public static final String CALL_DATE = DATA1;
+
+ /**
+ * Phone number for this record
+ *
Type: TEXT
+ */
+ public static final String PHONE_NUMBER = DATA3;
+
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note";
+
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note";
+
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note");
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java
new file mode 100644
index 0000000..ffe5d57
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/NotesDatabaseHelper.java
@@ -0,0 +1,362 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.data;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.util.Log;
+
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.DataConstants;
+import net.micode.notes.data.Notes.NoteColumns;
+
+
+public class NotesDatabaseHelper extends SQLiteOpenHelper {
+ private static final String DB_NAME = "note.db";
+
+ private static final int DB_VERSION = 4;
+
+ public interface TABLE {
+ public static final String NOTE = "note";
+
+ public static final String DATA = "data";
+ }
+
+ private static final String TAG = "NotesDatabaseHelper";
+
+ 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" +
+ ")";
+
+ 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 ''" +
+ ")";
+
+ private static final String CREATE_DATA_NOTE_ID_INDEX_SQL =
+ "CREATE INDEX IF NOT EXISTS note_id_index ON " +
+ TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
+
+ /**
+ * Increase folder's note count when move note to the folder
+ */
+ 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";
+
+ /**
+ * Decrease folder's note count when move note from folder
+ */
+ 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";
+
+ /**
+ * Increase folder's note count when insert new note to the folder
+ */
+ 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";
+
+ /**
+ * Decrease folder's note count when delete note from the folder
+ */
+ 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";
+
+ /**
+ * Update note's content when insert data with type {@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";
+
+ /**
+ * 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";
+
+ /**
+ * 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";
+
+ /**
+ * Delete datas belong to note which has been deleted
+ */
+ 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";
+
+ /**
+ * Delete notes belong to folder which has been deleted
+ */
+ 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";
+
+ /**
+ * Move notes belong to folder which has been moved to trash folder
+ */
+ 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";
+
+ public NotesDatabaseHelper(Context context) {
+ super(context, DB_NAME, null, DB_VERSION);
+ }
+
+ public void createNoteTable(SQLiteDatabase db) {
+ db.execSQL(CREATE_NOTE_TABLE_SQL);
+ reCreateNoteTableTriggers(db);
+ createSystemFolder(db);
+ Log.d(TAG, "note table has been created");
+ }
+
+ private void reCreateNoteTableTriggers(SQLiteDatabase db) {
+ db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update");
+ db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update");
+ db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_delete");
+ db.execSQL("DROP TRIGGER IF EXISTS delete_data_on_delete");
+ db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_insert");
+ db.execSQL("DROP TRIGGER IF EXISTS folder_delete_notes_on_delete");
+ db.execSQL("DROP TRIGGER IF EXISTS folder_move_notes_on_trash");
+
+ db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER);
+ db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER);
+ db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER);
+ db.execSQL(NOTE_DELETE_DATA_ON_DELETE_TRIGGER);
+ db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER);
+ db.execSQL(FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER);
+ db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER);
+ }
+
+ private void createSystemFolder(SQLiteDatabase db) {
+ ContentValues values = new ContentValues();
+
+ /**
+ * call record foler for call notes
+ */
+ values.put(NoteColumns.ID, Notes.ID_CALL_RECORD_FOLDER);
+ values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ db.insert(TABLE.NOTE, null, values);
+
+ /**
+ * root folder which is default folder
+ */
+ values.clear();
+ values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER);
+ values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ db.insert(TABLE.NOTE, null, values);
+
+ /**
+ * temporary folder which is used for moving note
+ */
+ values.clear();
+ values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER);
+ values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ db.insert(TABLE.NOTE, null, values);
+
+ /**
+ * create trash folder
+ */
+ values.clear();
+ values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER);
+ values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ db.insert(TABLE.NOTE, null, values);
+ }
+
+ public void createDataTable(SQLiteDatabase db) {
+ db.execSQL(CREATE_DATA_TABLE_SQL);
+ reCreateDataTableTriggers(db);
+ db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL);
+ Log.d(TAG, "data table has been created");
+ }
+
+ private void reCreateDataTableTriggers(SQLiteDatabase db) {
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert");
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update");
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_delete");
+
+ db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER);
+ db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER);
+ db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER);
+ }
+
+ static synchronized NotesDatabaseHelper getInstance(Context context) {
+ if (mInstance == null) {
+ mInstance = new NotesDatabaseHelper(context);
+ }
+ return mInstance;
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ createNoteTable(db);
+ createDataTable(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ boolean reCreateTriggers = false;
+ boolean skipV2 = false;
+
+ if (oldVersion == 1) {
+ upgradeToV2(db);
+ skipV2 = true; // this upgrade including the upgrade from v2 to v3
+ oldVersion++;
+ }
+
+ if (oldVersion == 2 && !skipV2) {
+ upgradeToV3(db);
+ reCreateTriggers = true;
+ oldVersion++;
+ }
+
+ if (oldVersion == 3) {
+ upgradeToV4(db);
+ oldVersion++;
+ }
+
+ if (reCreateTriggers) {
+ reCreateNoteTableTriggers(db);
+ reCreateDataTableTriggers(db);
+ }
+
+ if (oldVersion != newVersion) {
+ throw new IllegalStateException("Upgrade notes database to version " + newVersion
+ + "fails");
+ }
+ }
+
+ private void upgradeToV2(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA);
+ createNoteTable(db);
+ createDataTable(db);
+ }
+
+ private void upgradeToV3(SQLiteDatabase db) {
+ // drop unused triggers
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert");
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_delete");
+ db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_update");
+ // add a column for gtask id
+ db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID
+ + " TEXT NOT NULL DEFAULT ''");
+ // add a trash system folder
+ ContentValues values = new ContentValues();
+ values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER);
+ values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ db.insert(TABLE.NOTE, null, values);
+ }
+
+ private void upgradeToV4(SQLiteDatabase db) {
+ db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION
+ + " INTEGER NOT NULL DEFAULT 0");
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/NotesProvider.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/NotesProvider.java
new file mode 100644
index 0000000..edb0a60
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/data/NotesProvider.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.data;
+
+
+import android.app.SearchManager;
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.UriMatcher;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.data.NotesDatabaseHelper.TABLE;
+
+
+public class NotesProvider extends ContentProvider {
+ private static final UriMatcher mMatcher;
+
+ private NotesDatabaseHelper mHelper;
+
+ private static final String TAG = "NotesProvider";
+
+ private static final int URI_NOTE = 1;
+ private static final int URI_NOTE_ITEM = 2;
+ private static final int URI_DATA = 3;
+ private static final int URI_DATA_ITEM = 4;
+
+ private static final int URI_SEARCH = 5;
+ private static final int URI_SEARCH_SUGGEST = 6;
+
+ static {
+ mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
+ mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM);
+ mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
+ mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM);
+ mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH);
+ mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST);
+ mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST);
+ }
+
+ /**
+ * 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 String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
+ + " FROM " + TABLE.NOTE
+ + " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
+ + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER
+ + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
+
+ @Override
+ public boolean onCreate() {
+ mHelper = NotesDatabaseHelper.getInstance(getContext());
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ Cursor c = null;
+ SQLiteDatabase db = mHelper.getReadableDatabase();
+ String id = null;
+ switch (mMatcher.match(uri)) {
+ case URI_NOTE:
+ c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
+ sortOrder);
+ break;
+ case URI_NOTE_ITEM:
+ id = uri.getPathSegments().get(1);
+ c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id
+ + parseSelection(selection), selectionArgs, null, null, sortOrder);
+ break;
+ case URI_DATA:
+ c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null,
+ sortOrder);
+ break;
+ case URI_DATA_ITEM:
+ id = uri.getPathSegments().get(1);
+ c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id
+ + parseSelection(selection), selectionArgs, null, null, sortOrder);
+ break;
+ 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");
+ }
+
+ String searchString = null;
+ if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) {
+ if (uri.getPathSegments().size() > 1) {
+ searchString = uri.getPathSegments().get(1);
+ }
+ } else {
+ searchString = uri.getQueryParameter("pattern");
+ }
+
+ if (TextUtils.isEmpty(searchString)) {
+ return null;
+ }
+
+ try {
+ searchString = String.format("%%%s%%", searchString);
+ c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY,
+ new String[] { searchString });
+ } catch (IllegalStateException ex) {
+ Log.e(TAG, "got exception: " + ex.toString());
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ if (c != null) {
+ c.setNotificationUri(getContext().getContentResolver(), uri);
+ }
+ return c;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ 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;
+ case URI_DATA:
+ if (values.containsKey(DataColumns.NOTE_ID)) {
+ noteId = values.getAsLong(DataColumns.NOTE_ID);
+ } else {
+ Log.d(TAG, "Wrong data format without note id:" + values.toString());
+ }
+ insertedId = dataId = db.insert(TABLE.DATA, null, values);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ // Notify the note uri
+ if (noteId > 0) {
+ getContext().getContentResolver().notifyChange(
+ ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null);
+ }
+
+ // Notify the data uri
+ if (dataId > 0) {
+ getContext().getContentResolver().notifyChange(
+ ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
+ }
+
+ return ContentUris.withAppendedId(uri, insertedId);
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int count = 0;
+ String id = null;
+ SQLiteDatabase db = mHelper.getWritableDatabase();
+ boolean deleteData = false;
+ switch (mMatcher.match(uri)) {
+ case URI_NOTE:
+ selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 ";
+ count = db.delete(TABLE.NOTE, selection, selectionArgs);
+ break;
+ case URI_NOTE_ITEM:
+ id = uri.getPathSegments().get(1);
+ /**
+ * ID that smaller than 0 is system folder which is not allowed to
+ * trash
+ */
+ long noteId = Long.valueOf(id);
+ if (noteId <= 0) {
+ break;
+ }
+ count = db.delete(TABLE.NOTE,
+ NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs);
+ break;
+ case URI_DATA:
+ count = db.delete(TABLE.DATA, selection, selectionArgs);
+ deleteData = true;
+ break;
+ case URI_DATA_ITEM:
+ id = uri.getPathSegments().get(1);
+ count = db.delete(TABLE.DATA,
+ DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs);
+ deleteData = true;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+ if (count > 0) {
+ if (deleteData) {
+ getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ }
+ return count;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ int count = 0;
+ String id = null;
+ SQLiteDatabase db = mHelper.getWritableDatabase();
+ boolean updateData = false;
+ switch (mMatcher.match(uri)) {
+ case URI_NOTE:
+ increaseNoteVersion(-1, selection, selectionArgs);
+ count = db.update(TABLE.NOTE, values, selection, selectionArgs);
+ break;
+ case URI_NOTE_ITEM:
+ id = uri.getPathSegments().get(1);
+ increaseNoteVersion(Long.valueOf(id), selection, selectionArgs);
+ count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id
+ + parseSelection(selection), selectionArgs);
+ break;
+ case URI_DATA:
+ count = db.update(TABLE.DATA, values, selection, selectionArgs);
+ updateData = true;
+ break;
+ case URI_DATA_ITEM:
+ id = uri.getPathSegments().get(1);
+ count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id
+ + parseSelection(selection), selectionArgs);
+ updateData = true;
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown URI " + uri);
+ }
+
+ if (count > 0) {
+ if (updateData) {
+ getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null);
+ }
+ getContext().getContentResolver().notifyChange(uri, null);
+ }
+ return count;
+ }
+
+ private String parseSelection(String selection) {
+ return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
+ }
+
+ private void increaseNoteVersion(long id, String selection, String[] selectionArgs) {
+ StringBuilder sql = new StringBuilder(120);
+ sql.append("UPDATE ");
+ sql.append(TABLE.NOTE);
+ sql.append(" SET ");
+ sql.append(NoteColumns.VERSION);
+ sql.append("=" + NoteColumns.VERSION + "+1 ");
+
+ if (id > 0 || !TextUtils.isEmpty(selection)) {
+ sql.append(" WHERE ");
+ }
+ if (id > 0) {
+ sql.append(NoteColumns.ID + "=" + String.valueOf(id));
+ }
+ if (!TextUtils.isEmpty(selection)) {
+ String selectString = id > 0 ? parseSelection(selection) : selection;
+ for (String args : selectionArgs) {
+ selectString = selectString.replaceFirst("\\?", args);
+ }
+ sql.append(selectString);
+ }
+
+ mHelper.getWritableDatabase().execSQL(sql.toString());
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/MetaData.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/MetaData.java
new file mode 100644
index 0000000..5034e8e
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/MetaData.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.data;
+// 声明代码所属的包路径。
+
+import android.database.Cursor;
+import android.util.Log;
+// 导入所需的Android类。
+
+import net.micode.notes.tool.GTaskStringUtils;
+// 导入工具类,用于处理GTask相关的字符串常量。
+
+import org.json.JSONException;
+import org.json.JSONObject;
+// 导入JSON处理类。
+
+public class MetaData extends Task {
+ // 定义MetaData类,继承自Task类。
+
+ private final static String TAG = MetaData.class.getSimpleName();
+ // 定义日志标签。
+
+ private String mRelatedGid = null;
+ // 定义与GID相关的字符串变量。
+
+ public void setMeta(String gid, JSONObject metaInfo) {
+ // 设置元数据的方法。
+ try {
+ metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
+ // 将GID添加到元信息中。
+ } catch (JSONException e) {
+ Log.e(TAG, "failed to put related gid");
+ // 记录错误日志。
+ }
+ setNotes(metaInfo.toString());
+ // 将元信息转换为字符串并设置到笔记中。
+ setName(GTaskStringUtils.META_NOTE_NAME);
+ // 设置元数据的名称。
+ }
+
+ public String getRelatedGid() {
+ // 获取与GID相关的字符串。
+ return mRelatedGid;
+ }
+
+ @Override
+ public boolean isWorthSaving() {
+ // 判断元数据是否值得保存。
+ return getNotes() != null;
+ }
+
+ @Override
+ public void setContentByRemoteJSON(JSONObject js) {
+ // 从远程JSON设置内容的方法。
+ super.setContentByRemoteJSON(js);
+ // 调用父类的方法。
+ if (getNotes() != null) {
+ try {
+ JSONObject metaInfo = new JSONObject(getNotes().trim());
+ mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
+ // 从笔记中提取相关的GID。
+ } catch (JSONException e) {
+ Log.w(TAG, "failed to get related gid");
+ // 记录警告日志。
+ mRelatedGid = null;
+ }
+ }
+ }
+
+ @Override
+ public void setContentByLocalJSON(JSONObject js) {
+ // 此方法不应被调用,抛出异常。
+ throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
+ }
+
+ @Override
+ public JSONObject getLocalJSONFromContent() {
+ // 此方法不应被调用,抛出异常。
+ throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
+ }
+
+ @Override
+ public int getSyncAction(Cursor c) {
+ // 此方法不应被调用,抛出异常。
+ throw new IllegalAccessError("MetaData:getSyncAction should not be called");
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/Node.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/Node.java
new file mode 100644
index 0000000..b23e8fd
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/Node.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.data;
+// 声明代码所属的包路径。
+
+import android.database.Cursor;
+// 导入Android的Cursor类。
+
+import org.json.JSONObject;
+// 导入JSON处理类。
+
+public abstract class Node {
+ // 定义Node类,作为抽象类,表示GTask中的节点。
+
+ // 定义同步操作类型常量。
+ public static final int SYNC_ACTION_NONE = 0;
+ public static final int SYNC_ACTION_ADD_REMOTE = 1;
+ public static final int SYNC_ACTION_ADD_LOCAL = 2;
+ public static final int SYNC_ACTION_DEL_REMOTE = 3;
+ public static final int SYNC_ACTION_DEL_LOCAL = 4;
+ public static final int SYNC_ACTION_UPDATE_REMOTE = 5;
+ public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
+ public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
+ public static final int SYNC_ACTION_ERROR = 8;
+
+ private String mGid;
+ // 定义GID,用于唯一标识节点。
+ private String mName;
+ // 定义名称,用于描述节点。
+ private long mLastModified;
+ // 定义最后修改时间。
+ private boolean mDeleted;
+ // 定义删除标志。
+
+ public Node() {
+ // 构造函数,初始化节点的属性。
+ mGid = null;
+ mName = "";
+ mLastModified = 0;
+ mDeleted = false;
+ }
+
+ // 抽象方法,获取创建操作的JSON对象。
+ public abstract JSONObject getCreateAction(int actionId);
+
+ // 抽象方法,获取更新操作的JSON对象。
+ public abstract JSONObject getUpdateAction(int actionId);
+
+ // 抽象方法,从远程JSON设置内容。
+ public abstract void setContentByRemoteJSON(JSONObject js);
+
+ // 抽象方法,从本地JSON设置内容。
+ public abstract void setContentByLocalJSON(JSONObject js);
+
+ // 抽象方法,获取本地内容的JSON对象。
+ public abstract JSONObject getLocalJSONFromContent();
+
+ // 抽象方法,根据Cursor获取同步操作类型。
+ public abstract int getSyncAction(Cursor c);
+
+ // 设置GID。
+ public void setGid(String gid) {
+ this.mGid = gid;
+ }
+
+ // 设置名称。
+ public void setName(String name) {
+ this.mName = name;
+ }
+
+ // 设置最后修改时间。
+ public void setLastModified(long lastModified) {
+ this.mLastModified = lastModified;
+ }
+
+ // 设置删除状态。
+ public void setDeleted(boolean deleted) {
+ this.mDeleted = deleted;
+ }
+
+ // 获取GID。
+ public String getGid() {
+ return this.mGid;
+ }
+
+ // 获取名称。
+ public String getName() {
+ return this.mName;
+ }
+
+ // 获取最后修改时间。
+ public long getLastModified() {
+ return this.mLastModified;
+ }
+
+ // 获取删除状态。
+ public boolean getDeleted() {
+ return this.mDeleted;
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/SqlData.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/SqlData.java
new file mode 100644
index 0000000..d3ec3be
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/SqlData.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.gtask.data;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.DataConstants;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.data.NotesDatabaseHelper.TABLE;
+import net.micode.notes.gtask.exception.ActionFailureException;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+
+public class SqlData {
+ private static final String TAG = SqlData.class.getSimpleName();
+
+ private static final int INVALID_ID = -99999;
+
+ public static final String[] PROJECTION_DATA = new String[] {
+ DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
+ DataColumns.DATA3
+ };
+
+ public static final int DATA_ID_COLUMN = 0;
+
+ public static final int DATA_MIME_TYPE_COLUMN = 1;
+
+ public static final int DATA_CONTENT_COLUMN = 2;
+
+ public static final int DATA_CONTENT_DATA_1_COLUMN = 3;
+
+ public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
+
+ private ContentResolver mContentResolver;
+
+ private boolean mIsCreate;
+
+ private long mDataId;
+
+ private String mDataMimeType;
+
+ private String mDataContent;
+
+ private long mDataContentData1;
+
+ private String mDataContentData3;
+
+ private ContentValues mDiffDataValues;
+
+ public SqlData(Context context) {
+ mContentResolver = context.getContentResolver();
+ mIsCreate = true;
+ mDataId = INVALID_ID;
+ mDataMimeType = DataConstants.NOTE;
+ mDataContent = "";
+ mDataContentData1 = 0;
+ mDataContentData3 = "";
+ mDiffDataValues = new ContentValues();
+ }
+
+ public SqlData(Context context, Cursor c) {
+ mContentResolver = context.getContentResolver();
+ mIsCreate = false;
+ loadFromCursor(c);
+ mDiffDataValues = new ContentValues();
+ }
+
+ private void loadFromCursor(Cursor c) {
+ mDataId = c.getLong(DATA_ID_COLUMN);
+ mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
+ mDataContent = c.getString(DATA_CONTENT_COLUMN);
+ mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN);
+ mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
+ }
+
+ public void setContent(JSONObject js) throws JSONException {
+ long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
+ if (mIsCreate || mDataId != dataId) {
+ mDiffDataValues.put(DataColumns.ID, dataId);
+ }
+ mDataId = dataId;
+
+ String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE)
+ : DataConstants.NOTE;
+ if (mIsCreate || !mDataMimeType.equals(dataMimeType)) {
+ mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType);
+ }
+ mDataMimeType = dataMimeType;
+
+ String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : "";
+ if (mIsCreate || !mDataContent.equals(dataContent)) {
+ mDiffDataValues.put(DataColumns.CONTENT, dataContent);
+ }
+ mDataContent = dataContent;
+
+ long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0;
+ if (mIsCreate || mDataContentData1 != dataContentData1) {
+ mDiffDataValues.put(DataColumns.DATA1, dataContentData1);
+ }
+ mDataContentData1 = dataContentData1;
+
+ String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : "";
+ if (mIsCreate || !mDataContentData3.equals(dataContentData3)) {
+ mDiffDataValues.put(DataColumns.DATA3, dataContentData3);
+ }
+ mDataContentData3 = dataContentData3;
+ }
+
+ 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);
+ js.put(DataColumns.MIME_TYPE, mDataMimeType);
+ js.put(DataColumns.CONTENT, mDataContent);
+ js.put(DataColumns.DATA1, mDataContentData1);
+ js.put(DataColumns.DATA3, mDataContentData3);
+ return js;
+ }
+
+ public void commit(long noteId, boolean validateVersion, long version) {
+
+ if (mIsCreate) {
+ if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
+ mDiffDataValues.remove(DataColumns.ID);
+ }
+
+ 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 {
+ if (mDiffDataValues.size() > 0) {
+ int result = 0;
+ if (!validateVersion) {
+ result = mContentResolver.update(ContentUris.withAppendedId(
+ Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
+ } else {
+ result = mContentResolver.update(ContentUris.withAppendedId(
+ Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
+ " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE
+ + " WHERE " + NoteColumns.VERSION + "=?)", new String[] {
+ String.valueOf(noteId), String.valueOf(version)
+ });
+ }
+ if (result == 0) {
+ Log.w(TAG, "there is no update. maybe user updates note when syncing");
+ }
+ }
+ }
+
+ mDiffDataValues.clear();
+ mIsCreate = false;
+ }
+
+ public long getId() {
+ return mDataId;
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java
new file mode 100644
index 0000000..79a4095
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.gtask.data;
+
+import android.appwidget.AppWidgetManager;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.gtask.exception.ActionFailureException;
+import net.micode.notes.tool.GTaskStringUtils;
+import net.micode.notes.tool.ResourceParser;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+
+
+public class SqlNote {
+ private static final String TAG = SqlNote.class.getSimpleName();
+
+ private static final int INVALID_ID = -99999;
+
+ public static final String[] PROJECTION_NOTE = new String[] {
+ NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID,
+ NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE,
+ NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE,
+ NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID,
+ NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID,
+ NoteColumns.VERSION
+ };
+
+ public static final int ID_COLUMN = 0;
+
+ public static final int ALERTED_DATE_COLUMN = 1;
+
+ public static final int BG_COLOR_ID_COLUMN = 2;
+
+ public static final int CREATED_DATE_COLUMN = 3;
+
+ public static final int HAS_ATTACHMENT_COLUMN = 4;
+
+ public static final int MODIFIED_DATE_COLUMN = 5;
+
+ public static final int NOTES_COUNT_COLUMN = 6;
+
+ public static final int PARENT_ID_COLUMN = 7;
+
+ public static final int SNIPPET_COLUMN = 8;
+
+ public static final int TYPE_COLUMN = 9;
+
+ public static final int WIDGET_ID_COLUMN = 10;
+
+ public static final int WIDGET_TYPE_COLUMN = 11;
+
+ public static final int SYNC_ID_COLUMN = 12;
+
+ public static final int LOCAL_MODIFIED_COLUMN = 13;
+
+ public static final int ORIGIN_PARENT_ID_COLUMN = 14;
+
+ public static final int GTASK_ID_COLUMN = 15;
+
+ public static final int VERSION_COLUMN = 16;
+
+ private Context mContext;
+
+ private ContentResolver mContentResolver;
+
+ private boolean mIsCreate;
+
+ private long mId;
+
+ private long mAlertDate;
+
+ private int mBgColorId;
+
+ private long mCreatedDate;
+
+ private int mHasAttachment;
+
+ private long mModifiedDate;
+
+ private long mParentId;
+
+ private String mSnippet;
+
+ private int mType;
+
+ private int mWidgetId;
+
+ private int mWidgetType;
+
+ private long mOriginParent;
+
+ private long mVersion;
+
+ private ContentValues mDiffNoteValues;
+
+ private ArrayList mDataList;
+
+ public SqlNote(Context context) {
+ mContext = context;
+ mContentResolver = context.getContentResolver();
+ mIsCreate = true;
+ mId = INVALID_ID;
+ mAlertDate = 0;
+ mBgColorId = ResourceParser.getDefaultBgId(context);
+ mCreatedDate = System.currentTimeMillis();
+ mHasAttachment = 0;
+ mModifiedDate = System.currentTimeMillis();
+ mParentId = 0;
+ mSnippet = "";
+ mType = Notes.TYPE_NOTE;
+ mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
+ mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
+ mOriginParent = 0;
+ mVersion = 0;
+ mDiffNoteValues = new ContentValues();
+ mDataList = new ArrayList();
+ }
+
+ public SqlNote(Context context, Cursor c) {
+ mContext = context;
+ mContentResolver = context.getContentResolver();
+ mIsCreate = false;
+ loadFromCursor(c);
+ mDataList = new ArrayList();
+ if (mType == Notes.TYPE_NOTE)
+ loadDataContent();
+ mDiffNoteValues = new ContentValues();
+ }
+
+ public SqlNote(Context context, long id) {
+ mContext = context;
+ mContentResolver = context.getContentResolver();
+ mIsCreate = false;
+ loadFromCursor(id);
+ mDataList = new ArrayList();
+ if (mType == Notes.TYPE_NOTE)
+ loadDataContent();
+ mDiffNoteValues = new ContentValues();
+
+ }
+
+ private void loadFromCursor(long id) {
+ Cursor c = null;
+ try {
+ c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",
+ new String[] {
+ String.valueOf(id)
+ }, null);
+ if (c != null) {
+ c.moveToNext();
+ loadFromCursor(c);
+ } else {
+ Log.w(TAG, "loadFromCursor: cursor = null");
+ }
+ } finally {
+ if (c != null)
+ c.close();
+ }
+ }
+
+ private void loadFromCursor(Cursor c) {
+ mId = c.getLong(ID_COLUMN);
+ mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
+ mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);
+ mCreatedDate = c.getLong(CREATED_DATE_COLUMN);
+ mHasAttachment = c.getInt(HAS_ATTACHMENT_COLUMN);
+ mModifiedDate = c.getLong(MODIFIED_DATE_COLUMN);
+ mParentId = c.getLong(PARENT_ID_COLUMN);
+ mSnippet = c.getString(SNIPPET_COLUMN);
+ mType = c.getInt(TYPE_COLUMN);
+ mWidgetId = c.getInt(WIDGET_ID_COLUMN);
+ mWidgetType = c.getInt(WIDGET_TYPE_COLUMN);
+ mVersion = c.getLong(VERSION_COLUMN);
+ }
+
+ private void loadDataContent() {
+ Cursor c = null;
+ mDataList.clear();
+ try {
+ c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA,
+ "(note_id=?)", new String[] {
+ String.valueOf(mId)
+ }, null);
+ if (c != null) {
+ if (c.getCount() == 0) {
+ Log.w(TAG, "it seems that the note has not data");
+ return;
+ }
+ while (c.moveToNext()) {
+ SqlData data = new SqlData(mContext, c);
+ mDataList.add(data);
+ }
+ } else {
+ Log.w(TAG, "loadDataContent: cursor = null");
+ }
+ } finally {
+ if (c != null)
+ c.close();
+ }
+ }
+
+ public boolean setContent(JSONObject js) {
+ try {
+ JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
+ if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
+ Log.w(TAG, "cannot set system folder");
+ } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
+ // for folder we can only update the snnipet and type
+ String snippet = note.has(NoteColumns.SNIPPET) ? note
+ .getString(NoteColumns.SNIPPET) : "";
+ if (mIsCreate || !mSnippet.equals(snippet)) {
+ mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);
+ }
+ mSnippet = snippet;
+
+ int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE)
+ : Notes.TYPE_NOTE;
+ if (mIsCreate || mType != type) {
+ mDiffNoteValues.put(NoteColumns.TYPE, type);
+ }
+ mType = type;
+ } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) {
+ JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
+ long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID;
+ if (mIsCreate || mId != id) {
+ mDiffNoteValues.put(NoteColumns.ID, id);
+ }
+ mId = id;
+
+ long alertDate = note.has(NoteColumns.ALERTED_DATE) ? note
+ .getLong(NoteColumns.ALERTED_DATE) : 0;
+ if (mIsCreate || mAlertDate != alertDate) {
+ mDiffNoteValues.put(NoteColumns.ALERTED_DATE, alertDate);
+ }
+ mAlertDate = alertDate;
+
+ int bgColorId = note.has(NoteColumns.BG_COLOR_ID) ? note
+ .getInt(NoteColumns.BG_COLOR_ID) : ResourceParser.getDefaultBgId(mContext);
+ if (mIsCreate || mBgColorId != bgColorId) {
+ mDiffNoteValues.put(NoteColumns.BG_COLOR_ID, bgColorId);
+ }
+ mBgColorId = bgColorId;
+
+ long createDate = note.has(NoteColumns.CREATED_DATE) ? note
+ .getLong(NoteColumns.CREATED_DATE) : System.currentTimeMillis();
+ if (mIsCreate || mCreatedDate != createDate) {
+ mDiffNoteValues.put(NoteColumns.CREATED_DATE, createDate);
+ }
+ mCreatedDate = createDate;
+
+ int hasAttachment = note.has(NoteColumns.HAS_ATTACHMENT) ? note
+ .getInt(NoteColumns.HAS_ATTACHMENT) : 0;
+ if (mIsCreate || mHasAttachment != hasAttachment) {
+ mDiffNoteValues.put(NoteColumns.HAS_ATTACHMENT, hasAttachment);
+ }
+ mHasAttachment = hasAttachment;
+
+ long modifiedDate = note.has(NoteColumns.MODIFIED_DATE) ? note
+ .getLong(NoteColumns.MODIFIED_DATE) : System.currentTimeMillis();
+ if (mIsCreate || mModifiedDate != modifiedDate) {
+ mDiffNoteValues.put(NoteColumns.MODIFIED_DATE, modifiedDate);
+ }
+ mModifiedDate = modifiedDate;
+
+ long parentId = note.has(NoteColumns.PARENT_ID) ? note
+ .getLong(NoteColumns.PARENT_ID) : 0;
+ if (mIsCreate || mParentId != parentId) {
+ mDiffNoteValues.put(NoteColumns.PARENT_ID, parentId);
+ }
+ mParentId = parentId;
+
+ String snippet = note.has(NoteColumns.SNIPPET) ? note
+ .getString(NoteColumns.SNIPPET) : "";
+ if (mIsCreate || !mSnippet.equals(snippet)) {
+ mDiffNoteValues.put(NoteColumns.SNIPPET, snippet);
+ }
+ mSnippet = snippet;
+
+ int type = note.has(NoteColumns.TYPE) ? note.getInt(NoteColumns.TYPE)
+ : Notes.TYPE_NOTE;
+ if (mIsCreate || mType != type) {
+ mDiffNoteValues.put(NoteColumns.TYPE, type);
+ }
+ mType = type;
+
+ int widgetId = note.has(NoteColumns.WIDGET_ID) ? note.getInt(NoteColumns.WIDGET_ID)
+ : AppWidgetManager.INVALID_APPWIDGET_ID;
+ if (mIsCreate || mWidgetId != widgetId) {
+ mDiffNoteValues.put(NoteColumns.WIDGET_ID, widgetId);
+ }
+ mWidgetId = widgetId;
+
+ int widgetType = note.has(NoteColumns.WIDGET_TYPE) ? note
+ .getInt(NoteColumns.WIDGET_TYPE) : Notes.TYPE_WIDGET_INVALIDE;
+ if (mIsCreate || mWidgetType != widgetType) {
+ mDiffNoteValues.put(NoteColumns.WIDGET_TYPE, widgetType);
+ }
+ mWidgetType = widgetType;
+
+ long originParent = note.has(NoteColumns.ORIGIN_PARENT_ID) ? note
+ .getLong(NoteColumns.ORIGIN_PARENT_ID) : 0;
+ if (mIsCreate || mOriginParent != originParent) {
+ mDiffNoteValues.put(NoteColumns.ORIGIN_PARENT_ID, originParent);
+ }
+ mOriginParent = originParent;
+
+ for (int i = 0; i < dataArray.length(); i++) {
+ JSONObject data = dataArray.getJSONObject(i);
+ SqlData sqlData = null;
+ if (data.has(DataColumns.ID)) {
+ long dataId = data.getLong(DataColumns.ID);
+ for (SqlData temp : mDataList) {
+ if (dataId == temp.getId()) {
+ sqlData = temp;
+ }
+ }
+ }
+
+ if (sqlData == null) {
+ sqlData = new SqlData(mContext);
+ mDataList.add(sqlData);
+ }
+
+ sqlData.setContent(data);
+ }
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ return false;
+ }
+ return true;
+ }
+
+ public JSONObject getContent() {
+ try {
+ JSONObject js = new JSONObject();
+
+ if (mIsCreate) {
+ Log.e(TAG, "it seems that we haven't created this in database yet");
+ return null;
+ }
+
+ JSONObject note = new JSONObject();
+ if (mType == Notes.TYPE_NOTE) {
+ note.put(NoteColumns.ID, mId);
+ note.put(NoteColumns.ALERTED_DATE, mAlertDate);
+ note.put(NoteColumns.BG_COLOR_ID, mBgColorId);
+ note.put(NoteColumns.CREATED_DATE, mCreatedDate);
+ note.put(NoteColumns.HAS_ATTACHMENT, mHasAttachment);
+ note.put(NoteColumns.MODIFIED_DATE, mModifiedDate);
+ note.put(NoteColumns.PARENT_ID, mParentId);
+ note.put(NoteColumns.SNIPPET, mSnippet);
+ note.put(NoteColumns.TYPE, mType);
+ note.put(NoteColumns.WIDGET_ID, mWidgetId);
+ note.put(NoteColumns.WIDGET_TYPE, mWidgetType);
+ note.put(NoteColumns.ORIGIN_PARENT_ID, mOriginParent);
+ js.put(GTaskStringUtils.META_HEAD_NOTE, note);
+
+ JSONArray dataArray = new JSONArray();
+ for (SqlData sqlData : mDataList) {
+ JSONObject data = sqlData.getContent();
+ if (data != null) {
+ dataArray.put(data);
+ }
+ }
+ js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
+ } else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) {
+ note.put(NoteColumns.ID, mId);
+ note.put(NoteColumns.TYPE, mType);
+ note.put(NoteColumns.SNIPPET, mSnippet);
+ js.put(GTaskStringUtils.META_HEAD_NOTE, note);
+ }
+
+ return js;
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public void setParentId(long id) {
+ mParentId = id;
+ mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
+ }
+
+ public void setGtaskId(String gid) {
+ mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
+ }
+
+ public void setSyncId(long syncId) {
+ mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
+ }
+
+ public void resetLocalModified() {
+ mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
+ }
+
+ public long getId() {
+ return mId;
+ }
+
+ public long getParentId() {
+ return mParentId;
+ }
+
+ public String getSnippet() {
+ return mSnippet;
+ }
+
+ public boolean isNoteType() {
+ return mType == Notes.TYPE_NOTE;
+ }
+
+ public void commit(boolean validateVersion) {
+ if (mIsCreate) {
+ if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
+ mDiffNoteValues.remove(NoteColumns.ID);
+ }
+
+ Uri uri = mContentResolver.insert(Notes.CONTENT_NOTE_URI, mDiffNoteValues);
+ try {
+ mId = Long.valueOf(uri.getPathSegments().get(1));
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Get note id error :" + e.toString());
+ throw new ActionFailureException("create note failed");
+ }
+ if (mId == 0) {
+ throw new IllegalStateException("Create thread id failed");
+ }
+
+ if (mType == Notes.TYPE_NOTE) {
+ for (SqlData sqlData : mDataList) {
+ sqlData.commit(mId, false, -1);
+ }
+ }
+ } else {
+ if (mId <= 0 && mId != Notes.ID_ROOT_FOLDER && mId != Notes.ID_CALL_RECORD_FOLDER) {
+ Log.e(TAG, "No such note");
+ throw new IllegalStateException("Try to update note with invalid id");
+ }
+ if (mDiffNoteValues.size() > 0) {
+ mVersion ++;
+ int result = 0;
+ if (!validateVersion) {
+ result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ + NoteColumns.ID + "=?)", new String[] {
+ String.valueOf(mId)
+ });
+ } else {
+ result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ + NoteColumns.ID + "=?) AND (" + NoteColumns.VERSION + "<=?)",
+ new String[] {
+ String.valueOf(mId), String.valueOf(mVersion)
+ });
+ }
+ if (result == 0) {
+ Log.w(TAG, "there is no update. maybe user updates note when syncing");
+ }
+ }
+
+ if (mType == Notes.TYPE_NOTE) {
+ for (SqlData sqlData : mDataList) {
+ sqlData.commit(mId, validateVersion, mVersion);
+ }
+ }
+ }
+
+ // refresh local info
+ loadFromCursor(mId);
+ if (mType == Notes.TYPE_NOTE)
+ loadDataContent();
+
+ mDiffNoteValues.clear();
+ mIsCreate = false;
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/Task.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/Task.java
new file mode 100644
index 0000000..6a19454
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/Task.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.gtask.data;
+
+import android.database.Cursor;
+import android.text.TextUtils;
+import android.util.Log;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.DataConstants;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.gtask.exception.ActionFailureException;
+import net.micode.notes.tool.GTaskStringUtils;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+
+public class Task extends Node {
+ private static final String TAG = Task.class.getSimpleName();
+
+ private boolean mCompleted;
+
+ private String mNotes;
+
+ private JSONObject mMetaInfo;
+
+ private Task mPriorSibling;
+
+ private TaskList mParent;
+
+ public Task() {
+ super();
+ mCompleted = false;
+ mNotes = null;
+ mPriorSibling = null;
+ mParent = null;
+ mMetaInfo = null;
+ }
+
+ public JSONObject getCreateAction(int actionId) {
+ JSONObject js = new JSONObject();
+
+ try {
+ // action_type
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
+ GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
+
+ // action_id
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
+
+ // index
+ js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
+
+ // entity_delta
+ JSONObject entity = new JSONObject();
+ entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
+ entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
+ entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
+ GTaskStringUtils.GTASK_JSON_TYPE_TASK);
+ if (getNotes() != null) {
+ entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
+ }
+ js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
+
+ // parent_id
+ js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid());
+
+ // dest_parent_type
+ js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE,
+ GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
+
+ // list_id
+ js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
+
+ // prior_sibling_id
+ if (mPriorSibling != null) {
+ js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
+ }
+
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ throw new ActionFailureException("fail to generate task-create jsonobject");
+ }
+
+ return js;
+ }
+
+ public JSONObject getUpdateAction(int actionId) {
+ JSONObject js = new JSONObject();
+
+ try {
+ // action_type
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
+ GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
+
+ // action_id
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
+
+ // id
+ js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
+
+ // entity_delta
+ JSONObject entity = new JSONObject();
+ entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
+ if (getNotes() != null) {
+ entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
+ }
+ entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
+ js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
+
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ throw new ActionFailureException("fail to generate task-update jsonobject");
+ }
+
+ return js;
+ }
+
+ public void setContentByRemoteJSON(JSONObject js) {
+ if (js != null) {
+ try {
+ // id
+ if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
+ setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
+ }
+
+ // last_modified
+ if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
+ setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
+ }
+
+ // name
+ if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
+ setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
+ }
+
+ // notes
+ if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
+ setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
+ }
+
+ // deleted
+ if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
+ setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
+ }
+
+ // completed
+ if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
+ setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED));
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ throw new ActionFailureException("fail to get task content from jsonobject");
+ }
+ }
+ }
+
+ 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");
+ }
+
+ 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) {
+ Log.e(TAG, "invalid type");
+ return;
+ }
+
+ for (int i = 0; i < dataArray.length(); i++) {
+ JSONObject data = dataArray.getJSONObject(i);
+ if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
+ setName(data.getString(DataColumns.CONTENT));
+ break;
+ }
+ }
+
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ }
+ }
+
+ public JSONObject getLocalJSONFromContent() {
+ String name = getName();
+ try {
+ if (mMetaInfo == null) {
+ // new task created from web
+ if (name == null) {
+ Log.w(TAG, "the note seems to be an empty one");
+ return null;
+ }
+
+ JSONObject js = new JSONObject();
+ JSONObject note = new JSONObject();
+ JSONArray dataArray = new JSONArray();
+ JSONObject data = new JSONObject();
+ data.put(DataColumns.CONTENT, name);
+ dataArray.put(data);
+ js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
+ note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
+ js.put(GTaskStringUtils.META_HEAD_NOTE, note);
+ return js;
+ } else {
+ // synced task
+ JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
+ JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
+
+ for (int i = 0; i < dataArray.length(); i++) {
+ JSONObject data = dataArray.getJSONObject(i);
+ if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
+ data.put(DataColumns.CONTENT, getName());
+ break;
+ }
+ }
+
+ note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
+ return mMetaInfo;
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public void setMetaInfo(MetaData metaData) {
+ if (metaData != null && metaData.getNotes() != null) {
+ try {
+ mMetaInfo = new JSONObject(metaData.getNotes());
+ } catch (JSONException e) {
+ Log.w(TAG, e.toString());
+ mMetaInfo = null;
+ }
+ }
+ }
+
+ public int getSyncAction(Cursor c) {
+ try {
+ JSONObject noteInfo = null;
+ if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
+ noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
+ }
+
+ if (noteInfo == null) {
+ Log.w(TAG, "it seems that note meta has been deleted");
+ return SYNC_ACTION_UPDATE_REMOTE;
+ }
+
+ if (!noteInfo.has(NoteColumns.ID)) {
+ Log.w(TAG, "remote note id seems to be deleted");
+ return SYNC_ACTION_UPDATE_LOCAL;
+ }
+
+ // validate the note id now
+ if (c.getLong(SqlNote.ID_COLUMN) != noteInfo.getLong(NoteColumns.ID)) {
+ Log.w(TAG, "note id doesn't match");
+ return SYNC_ACTION_UPDATE_LOCAL;
+ }
+
+ if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
+ // there is no local update
+ if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
+ // no update both side
+ return SYNC_ACTION_NONE;
+ } else {
+ // apply remote to local
+ return SYNC_ACTION_UPDATE_LOCAL;
+ }
+ } else {
+ // validate gtask id
+ if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) {
+ Log.e(TAG, "gtask id doesn't match");
+ return SYNC_ACTION_ERROR;
+ }
+ if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
+ // local modification only
+ return SYNC_ACTION_UPDATE_REMOTE;
+ } else {
+ return SYNC_ACTION_UPDATE_CONFLICT;
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ }
+
+ return SYNC_ACTION_ERROR;
+ }
+
+ public boolean isWorthSaving() {
+ return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
+ || (getNotes() != null && getNotes().trim().length() > 0);
+ }
+
+ public void setCompleted(boolean completed) {
+ this.mCompleted = completed;
+ }
+
+ public void setNotes(String notes) {
+ this.mNotes = notes;
+ }
+
+ public void setPriorSibling(Task priorSibling) {
+ this.mPriorSibling = priorSibling;
+ }
+
+ public void setParent(TaskList parent) {
+ this.mParent = parent;
+ }
+
+ public boolean getCompleted() {
+ return this.mCompleted;
+ }
+
+ public String getNotes() {
+ return this.mNotes;
+ }
+
+ public Task getPriorSibling() {
+ return this.mPriorSibling;
+ }
+
+ public TaskList getParent() {
+ return this.mParent;
+ }
+
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/TaskList.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/TaskList.java
new file mode 100644
index 0000000..4ea21c5
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/data/TaskList.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.gtask.data;
+
+import android.database.Cursor;
+import android.util.Log;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.gtask.exception.ActionFailureException;
+import net.micode.notes.tool.GTaskStringUtils;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+
+
+public class TaskList extends Node {
+ private static final String TAG = TaskList.class.getSimpleName();
+
+ private int mIndex;
+
+ private ArrayList mChildren;
+
+ public TaskList() {
+ super();
+ mChildren = new ArrayList();
+ mIndex = 1;
+ }
+
+ public JSONObject getCreateAction(int actionId) {
+ JSONObject js = new JSONObject();
+
+ try {
+ // action_type
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
+ GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
+
+ // action_id
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
+
+ // index
+ js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex);
+
+ // entity_delta
+ JSONObject entity = new JSONObject();
+ entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
+ entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
+ entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
+ GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
+ js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
+
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ throw new ActionFailureException("fail to generate tasklist-create jsonobject");
+ }
+
+ return js;
+ }
+
+ public JSONObject getUpdateAction(int actionId) {
+ JSONObject js = new JSONObject();
+
+ try {
+ // action_type
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
+ GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
+
+ // action_id
+ js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
+
+ // id
+ js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
+
+ // entity_delta
+ JSONObject entity = new JSONObject();
+ entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
+ entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
+ js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
+
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ throw new ActionFailureException("fail to generate tasklist-update jsonobject");
+ }
+
+ return js;
+ }
+
+ public void setContentByRemoteJSON(JSONObject js) {
+ if (js != null) {
+ try {
+ // id
+ if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
+ setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
+ }
+
+ // last_modified
+ if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
+ setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
+ }
+
+ // name
+ if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
+ setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
+ }
+
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ throw new ActionFailureException("fail to get tasklist content from jsonobject");
+ }
+ }
+ }
+
+ public void setContentByLocalJSON(JSONObject js) {
+ if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
+ Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
+ }
+
+ try {
+ JSONObject folder = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
+
+ if (folder.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) {
+ 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)
+ setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT);
+ else if (folder.getLong(NoteColumns.ID) == Notes.ID_CALL_RECORD_FOLDER)
+ setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX
+ + GTaskStringUtils.FOLDER_CALL_NOTE);
+ else
+ Log.e(TAG, "invalid system folder");
+ } else {
+ Log.e(TAG, "error type");
+ }
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ }
+ }
+
+ public JSONObject getLocalJSONFromContent() {
+ try {
+ JSONObject js = new JSONObject();
+ JSONObject folder = new JSONObject();
+
+ String folderName = getName();
+ if (getName().startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX))
+ folderName = folderName.substring(GTaskStringUtils.MIUI_FOLDER_PREFFIX.length(),
+ folderName.length());
+ folder.put(NoteColumns.SNIPPET, folderName);
+ if (folderName.equals(GTaskStringUtils.FOLDER_DEFAULT)
+ || folderName.equals(GTaskStringUtils.FOLDER_CALL_NOTE))
+ folder.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
+ else
+ folder.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
+
+ js.put(GTaskStringUtils.META_HEAD_NOTE, folder);
+
+ return js;
+ } catch (JSONException e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public int getSyncAction(Cursor c) {
+ try {
+ if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) {
+ // there is no local update
+ if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
+ // no update both side
+ return SYNC_ACTION_NONE;
+ } else {
+ // apply remote to local
+ return SYNC_ACTION_UPDATE_LOCAL;
+ }
+ } else {
+ // validate gtask id
+ if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) {
+ Log.e(TAG, "gtask id doesn't match");
+ return SYNC_ACTION_ERROR;
+ }
+ if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
+ // local modification only
+ return SYNC_ACTION_UPDATE_REMOTE;
+ } else {
+ // for folder conflicts, just apply local modification
+ return SYNC_ACTION_UPDATE_REMOTE;
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, e.toString());
+ e.printStackTrace();
+ }
+
+ return SYNC_ACTION_ERROR;
+ }
+
+ public int getChildTaskCount() {
+ return mChildren.size();
+ }
+
+ public boolean addChildTask(Task task) {
+ boolean ret = false;
+ if (task != null && !mChildren.contains(task)) {
+ ret = mChildren.add(task);
+ if (ret) {
+ // need to set prior sibling and parent
+ task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
+ .get(mChildren.size() - 1));
+ task.setParent(this);
+ }
+ }
+ return ret;
+ }
+
+ public boolean addChildTask(Task task, int index) {
+ if (index < 0 || index > mChildren.size()) {
+ Log.e(TAG, "add child task: invalid index");
+ return false;
+ }
+
+ int pos = mChildren.indexOf(task);
+ if (task != null && pos == -1) {
+ mChildren.add(index, task);
+
+ // update the task list
+ Task preTask = null;
+ Task afterTask = null;
+ if (index != 0)
+ preTask = mChildren.get(index - 1);
+ if (index != mChildren.size() - 1)
+ afterTask = mChildren.get(index + 1);
+
+ task.setPriorSibling(preTask);
+ if (afterTask != null)
+ afterTask.setPriorSibling(task);
+ }
+
+ return true;
+ }
+
+ public boolean removeChildTask(Task task) {
+ boolean ret = false;
+ int index = mChildren.indexOf(task);
+ if (index != -1) {
+ ret = mChildren.remove(task);
+
+ if (ret) {
+ // reset prior sibling and parent
+ task.setPriorSibling(null);
+ task.setParent(null);
+
+ // update the task list
+ if (index != mChildren.size()) {
+ mChildren.get(index).setPriorSibling(
+ index == 0 ? null : mChildren.get(index - 1));
+ }
+ }
+ }
+ return ret;
+ }
+
+ public boolean moveChildTask(Task task, int index) {
+
+ if (index < 0 || index >= mChildren.size()) {
+ Log.e(TAG, "move child task: invalid index");
+ return false;
+ }
+
+ int pos = mChildren.indexOf(task);
+ if (pos == -1) {
+ Log.e(TAG, "move child task: the task should in the list");
+ return false;
+ }
+
+ if (pos == index)
+ return true;
+ return (removeChildTask(task) && addChildTask(task, index));
+ }
+
+ public Task findChildTaskByGid(String gid) {
+ for (int i = 0; i < mChildren.size(); i++) {
+ Task t = mChildren.get(i);
+ if (t.getGid().equals(gid)) {
+ return t;
+ }
+ }
+ return null;
+ }
+
+ public int getChildTaskIndex(Task task) {
+ return mChildren.indexOf(task);
+ }
+
+ public Task getChildTaskByIndex(int index) {
+ if (index < 0 || index >= mChildren.size()) {
+ Log.e(TAG, "getTaskByIndex: invalid index");
+ return null;
+ }
+ return mChildren.get(index);
+ }
+
+ public Task getChilTaskByGid(String gid) {
+ for (Task task : mChildren) {
+ if (task.getGid().equals(gid))
+ return task;
+ }
+ return null;
+ }
+
+ public ArrayList getChildTaskList() {
+ return this.mChildren;
+ }
+
+ public void setIndex(int index) {
+ this.mIndex = index;
+ }
+
+ public int getIndex() {
+ return this.mIndex;
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java
new file mode 100644
index 0000000..15504be
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.gtask.exception;
+
+public class ActionFailureException extends RuntimeException {
+ private static final long serialVersionUID = 4425249765923293627L;
+
+ public ActionFailureException() {
+ super();
+ }
+
+ public ActionFailureException(String paramString) {
+ super(paramString);
+ }
+
+ public ActionFailureException(String paramString, Throwable paramThrowable) {
+ super(paramString, paramThrowable);
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java
new file mode 100644
index 0000000..254450a
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.exception;
+// 声明代码所属的包路径。
+
+public class NetworkFailureException extends Exception {
+ // 定义NetworkFailureException类,继承自Exception类。
+
+ private static final long serialVersionUID = 2107610287180234136L;
+ // 定义序列化ID,用于序列化和反序列化异常对象。
+
+ public NetworkFailureException() {
+ super();
+ }
+ // 构造函数,无参数,调用父类的构造函数。
+
+ public NetworkFailureException(String paramString) {
+ super(paramString);
+ }
+ // 构造函数,接受一个字符串参数,调用父类的构造函数,并传递该字符串。
+
+ public NetworkFailureException(String paramString, Throwable paramThrowable) {
+ super(paramString, paramThrowable);
+ }
+ // 构造函数,接受一个字符串和一个Throwable对象作为参数,调用父类的构造函数,并传递这两个参数。
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskASyncTask.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskASyncTask.java
new file mode 100644
index 0000000..3d426c9
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskASyncTask.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.remote;
+// 声明代码所属的包路径。
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+// 导入所需的Android类和接口。
+
+import net.micode.notes.R;
+import net.micode.notes.ui.NotesListActivity;
+import net.micode.notes.ui.NotesPreferenceActivity;
+// 导入应用程序的资源类和其他Activity类。
+
+public class GTaskASyncTask extends AsyncTask {
+ // 定义GTaskASyncTask类,继承自AsyncTask,用于执行后台任务。
+
+ private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
+ // 定义一个用于通知的ID。
+
+ public interface OnCompleteListener {
+ void onComplete();
+ }
+ // 定义一个回调接口,用于通知任务完成。
+
+ private Context mContext;
+ private NotificationManager mNotifiManager;
+ private GTaskManager mTaskManager;
+ private OnCompleteListener mOnCompleteListener;
+ // 定义上下文、通知管理器、任务管理器和回调接口的成员变量。
+
+ public GTaskASyncTask(Context context, OnCompleteListener listener) {
+ // 构造函数,初始化成员变量。
+ mContext = context;
+ mOnCompleteListener = listener;
+ mNotifiManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ mTaskManager = GTaskManager.getInstance();
+ }
+
+ public void cancelSync() {
+ // 提供一个方法来取消同步。
+ mTaskManager.cancelSync();
+ }
+
+ public void publishProgess(String message) {
+ // 提供一个方法来发布进度消息。
+ publishProgress(new String[] { message });
+ }
+
+ private void showNotification(int tickerId, String content) {
+ // 私有方法,用于显示通知。
+ Notification notification = new Notification(R.drawable.notification, mContext.getString(tickerId), System.currentTimeMillis());
+ notification.defaults = Notification.DEFAULT_LIGHTS;
+ notification.flags = Notification.FLAG_AUTO_CANCEL;
+ PendingIntent pendingIntent;
+ if (tickerId != R.string.ticker_success) {
+ pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, NotesPreferenceActivity.class), 0);
+ } else {
+ pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, NotesListActivity.class), 0);
+ }
+ notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content, pendingIntent);
+ mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
+ }
+
+ @Override
+ protected Integer doInBackground(Void... unused) {
+ // 覆写doInBackground方法,执行实际的同步操作。
+ publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity.getSyncAccountName(mContext)));
+ return mTaskManager.sync(mContext, this);
+ }
+
+ @Override
+ protected void onProgressUpdate(String... progress) {
+ // 覆写onProgressUpdate方法,显示进度通知。
+ showNotification(R.string.ticker_syncing, progress[0]);
+ if (mContext instanceof GTaskSyncService) {
+ ((GTaskSyncService) mContext).sendBroadcast(progress[0]);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(Integer result) {
+ // 覆写onPostExecute方法,处理同步完成后的操作。
+ if (result == GTaskManager.STATE_SUCCESS) {
+ showNotification(R.string.ticker_success, mContext.getString(R.string.success_sync_account, mTaskManager.getSyncAccount()));
+ NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis());
+ } else if (result == GTaskManager.STATE_NETWORK_ERROR) {
+ showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network));
+ } else if (result == GTaskManager.STATE_INTERNAL_ERROR) {
+ showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal));
+ } else if (result == GTaskManager.STATE_SYNC_CANCELLED) {
+ showNotification(R.string.ticker_cancel, mContext.getString(R.string.error_sync_cancelled));
+ }
+ if (mOnCompleteListener != null) {
+ new Thread(new Runnable() {
+ public void run() {
+ mOnCompleteListener.onComplete();
+ }
+ }).start();
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java
new file mode 100644
index 0000000..fe68c7b
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskClient.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.remote;
+// 声明代码所属的包路径。
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+// ...
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+// 导入所需的Android类、数据模型类和JSON处理类。
+
+public class GTaskClient {
+ // 定义GTaskClient类,用于与Google任务服务进行交互。
+
+ private static final String TAG = GTaskClient.class.getSimpleName();
+ // 定义日志标签。
+
+ private static final String GTASK_URL = "https://mail.google.com/tasks/";
+ // 定义GTask的URL。
+
+ private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig";
+ // 定义GTask的GET请求URL。
+
+ private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig";
+ // 定义GTask的POST请求URL。
+
+ private static GTaskClient mInstance = null;
+ // 定义GTaskClient的单例。
+
+ private DefaultHttpClient mHttpClient;
+ // 定义HttpClient,用于发送HTTP请求。
+
+ private String mGetUrl;
+ private String mPostUrl;
+ // 定义GET和POST请求的URL。
+
+ private long mClientVersion;
+ private boolean mLoggedin;
+ private long mLastLoginTime;
+ private int mActionId;
+ private Account mAccount;
+ private JSONArray mUpdateArray;
+ // 定义客户端版本、登录状态、最后登录时间、操作ID、账户和更新数组。
+
+ private GTaskClient() {
+ // 私有构造函数,用于创建GTaskClient的单例。
+ mHttpClient = null;
+ mGetUrl = GTASK_GET_URL;
+ mPostUrl = GTASK_POST_URL;
+ mClientVersion = -1;
+ mLoggedin = false;
+ mLastLoginTime = 0;
+ mActionId = 1;
+ mAccount = null;
+ mUpdateArray = null;
+ }
+
+ public static synchronized GTaskClient getInstance() {
+ // 提供一个方法来获取GTaskClient的单例。
+ if (mInstance == null) {
+ mInstance = new GTaskClient();
+ }
+ return mInstance;
+ }
+
+ public boolean login(Activity activity) {
+ // 提供一个方法来登录GTask服务。
+ // ...
+ }
+
+ private String loginGoogleAccount(Activity activity, boolean invalidateToken) {
+ // 私有方法,用于登录Google账户并获取授权令牌。
+ // ...
+ }
+
+ private boolean tryToLoginGtask(Activity activity, String authToken) {
+ // 私有方法,尝试登录GTask服务。
+ // ...
+ }
+
+ private boolean loginGtask(String authToken) {
+ // 私有方法,用于执行登录GTask的操作。
+ // ...
+ }
+
+ private int getActionId() {
+ // 提供一个方法来获取操作ID。
+ return mActionId++;
+ }
+
+ private HttpPost createHttpPost() {
+ // 私有方法,用于创建一个HttpPost对象。
+ // ...
+ }
+
+ private String getResponseContent(HttpEntity entity) throws IOException {
+ // 私有方法,用于获取响应内容。
+ // ...
+ }
+
+ private JSONObject postRequest(JSONObject js) throws NetworkFailureException {
+ // 私有方法,用于执行POST请求。
+ // ...
+ }
+
+ public void createTask(Task task) throws NetworkFailureException {
+ // 提供一个方法来创建任务。
+ // ...
+ }
+
+ public void createTaskList(TaskList tasklist) throws NetworkFailureException {
+ // 提供一个方法来创建任务列表。
+ // ...
+ }
+
+ public void commitUpdate() throws NetworkFailureException {
+ // 提供一个方法来提交更新。
+ // ...
+ }
+
+ public void addUpdateNode(Node node) throws NetworkFailureException {
+ // 提供一个方法来添加更新节点。
+ // ...
+ }
+
+ public void moveTask(Task task, TaskList preParent, TaskList curParent)
+ throws NetworkFailureException {
+ // 提供一个方法来移动任务。
+ // ...
+ }
+
+ public void deleteNode(Node node) throws NetworkFailureException {
+ // 提供一个方法来删除节点。
+ // ...
+ }
+
+ public JSONArray getTaskLists() throws NetworkFailureException {
+ // 提供一个方法来获取任务列表。
+ // ...
+ }
+
+ public JSONArray getTaskList(String listGid) throws NetworkFailureException {
+ // 提供一个方法来获取指定的任务列表。
+ // ...
+ }
+
+ public Account getSyncAccount() {
+ // 提供一个方法来获取同步账户。
+ return mAccount;
+ }
+
+ public void resetUpdateArray() {
+ // 提供一个方法来重置更新数组。
+ mUpdateArray = null;
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java
new file mode 100644
index 0000000..355394f
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskManager.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.remote;
+// 声明代码所属的包路径。
+
+import android.app.Activity;
+// ...
+import java.util.Map;
+// 导入所需的Android类、数据模型类和Java工具类。
+
+public class GTaskManager {
+ // 定义GTaskManager类,用于管理与Google任务同步相关的操作。
+
+ private static final String TAG = GTaskManager.class.getSimpleName();
+ // 定义日志标签。
+
+ public static final int STATE_SUCCESS = 0;
+ // 定义同步状态常量:成功。
+
+ public static final int STATE_NETWORK_ERROR = 1;
+ // 定义同步状态常量:网络错误。
+
+ public static final int STATE_INTERNAL_ERROR = 2;
+ // 定义同步状态常量:内部错误。
+
+ public static final int STATE_SYNC_IN_PROGRESS = 3;
+ // 定义同步状态常量:同步进行中。
+
+ public static final int STATE_SYNC_CANCELLED = 4;
+ // 定义同步状态常量:同步已取消。
+
+ private static GTaskManager mInstance = null;
+ // 定义GTaskManager的单例。
+
+ private Activity mActivity;
+ private Context mContext;
+ private ContentResolver mContentResolver;
+ // 定义Activity、Context和ContentResolver成员变量。
+
+ private boolean mSyncing;
+ private boolean mCancelled;
+ // 定义同步状态和取消标志。
+
+ private HashMap mGTaskListHashMap;
+ private HashMap mGTaskHashMap;
+ private HashMap mMetaHashMap;
+ // 定义任务列表、节点和元数据的哈希映射。
+
+ private TaskList mMetaList;
+ private HashSet mLocalDeleteIdMap;
+ // 定义元数据列表和本地删除ID集合。
+
+ private HashMap mGidToNid;
+ private HashMap mNidToGid;
+ // 定义GID到NID和NID到GID的映射。
+
+ private GTaskManager() {
+ // 私有构造函数,用于创建GTaskManager的单例。
+ mSyncing = false;
+ mCancelled = false;
+ // 初始化哈希映射、集合和映射。
+ }
+
+ public static synchronized GTaskManager getInstance() {
+ // 提供一个方法来获取GTaskManager的单例。
+ if (mInstance == null) {
+ mInstance = new GTaskManager();
+ }
+ return mInstance;
+ }
+
+ public synchronized void setActivityContext(Activity activity) {
+ // 提供一个方法来设置Activity上下文。
+ mActivity = activity;
+ }
+
+ public int sync(Context context, GTaskASyncTask asyncTask) {
+ // 提供一个方法来执行同步操作。
+ // ...
+ }
+
+ private void initGTaskList() throws NetworkFailureException {
+ // 私有方法,用于初始化GTask列表。
+ // ...
+ }
+
+ private void syncContent() throws NetworkFailureException {
+ // 私有方法,用于同步内容。
+ // ...
+ }
+
+ private void syncFolder() throws NetworkFailureException {
+ // 私有方法,用于同步文件夹。
+ // ...
+ }
+
+ private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException {
+ // 私有方法,用于执行内容同步操作。
+ // ...
+ }
+
+ private void addLocalNode(Node node) throws NetworkFailureException {
+ // 私有方法,用于添加本地节点。
+ // ...
+ }
+
+ private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException {
+ // 私有方法,用于更新本地节点。
+ // ...
+ }
+
+ private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException {
+ // 私有方法,用于添加远程节点。
+ // ...
+ }
+
+ private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException {
+ // 私有方法,用于更新远程节点。
+ // ...
+ }
+
+ private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException {
+ // 私有方法,用于更新远程元数据。
+ // ...
+ }
+
+ private void refreshLocalSyncId() throws NetworkFailureException {
+ // 私有方法,用于刷新本地同步ID。
+ // ...
+ }
+
+ public String getSyncAccount() {
+ // 提供一个方法来获取同步账户。
+ return GTaskClient.getInstance().getSyncAccount().name;
+ }
+
+ public void cancelSync() {
+ // 提供一个方法来取消同步操作。
+ mCancelled = true;
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskSyncService.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskSyncService.java
new file mode 100644
index 0000000..7c449da
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/gtask/remote/GTaskSyncService.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.gtask.remote;
+// 声明代码所属的包路径。
+
+import android.app.Activity;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+// 导入所需的Android类。
+
+public class GTaskSyncService extends Service {
+ // 定义GTaskSyncService类,继承自Service。
+
+ public final static String ACTION_STRING_NAME = "sync_action_type";
+ // 定义同步操作类型的字符串常量。
+
+ public final static int ACTION_START_SYNC = 0;
+ // 定义开始同步的操作常量。
+
+ public final static int ACTION_CANCEL_SYNC = 1;
+ // 定义取消同步的操作常量。
+
+ public final static int ACTION_INVALID = 2;
+ // 定义无效操作的常量。
+
+ public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service";
+ // 定义GTask服务的广播名称。
+
+ public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing";
+ // 定义广播中表示同步状态的键。
+
+ public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg";
+ // 定义广播中表示进度消息的键。
+
+ private static GTaskASyncTask mSyncTask = null;
+ // 定义静态同步任务实例。
+
+ private static String mSyncProgress = "";
+ // 定义静态同步进度消息。
+
+ private void startSync() {
+ // 私有方法,用于开始同步。
+ if (mSyncTask == null) {
+ mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() {
+ public void onComplete() {
+ mSyncTask = null;
+ sendBroadcast("");
+ stopSelf();
+ }
+ });
+ sendBroadcast("");
+ mSyncTask.execute();
+ }
+ }
+
+ private void cancelSync() {
+ // 私有方法,用于取消同步。
+ if (mSyncTask != null) {
+ mSyncTask.cancelSync();
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ // 创建服务时调用。
+ mSyncTask = null;
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ // 当服务启动时调用。
+ Bundle bundle = intent.getExtras();
+ if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) {
+ switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) {
+ case ACTION_START_SYNC:
+ startSync();
+ break;
+ case ACTION_CANCEL_SYNC:
+ cancelSync();
+ break;
+ default:
+ break;
+ }
+ return START_STICKY;
+ }
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ public void onLowMemory() {
+ // 当系统内存不足时调用。
+ if (mSyncTask != null) {
+ mSyncTask.cancelSync();
+ }
+ }
+
+ public IBinder onBind(Intent intent) {
+ // 返回null,因为这是一个不绑定的服务。
+ return null;
+ }
+
+ public void sendBroadcast(String msg) {
+ // 私有方法,用于发送广播。
+ mSyncProgress = msg;
+ Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME);
+ intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null);
+ intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg);
+ sendBroadcast(intent);
+ }
+
+ public static void startSync(Activity activity) {
+ // 提供一个静态方法来启动同步。
+ GTaskManager.getInstance().setActivityContext(activity);
+ Intent intent = new Intent(activity, GTaskSyncService.class);
+ intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC);
+ activity.startService(intent);
+ }
+
+ public static void cancelSync(Context context) {
+ // 提供一个静态方法来取消同步。
+ Intent intent = new Intent(context, GTaskSyncService.class);
+ intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC);
+ context.startService(intent);
+ }
+
+ public static boolean isSyncing() {
+ // 提供一个静态方法来检查是否正在同步。
+ return mSyncTask != null;
+ }
+
+ public static String getProgressString() {
+ // 提供一个静态方法来获取同步进度消息。
+ return mSyncProgress;
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/model/Note.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/model/Note.java
new file mode 100644
index 0000000..28ce047
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/model/Note.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.model;
+// 声明代码所属的包路径。
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.util.Log;
+// 导入所需的Android类。
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.CallNote;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.data.Notes.TextNote;
+// 导入数据模型类。
+
+import java.util.ArrayList;
+// 导入Java的集合类。
+
+public class Note {
+ // 定义Note类,用于管理笔记数据。
+
+ private ContentValues mNoteDiffValues;
+ // 定义ContentValues对象,用于存储笔记的差异数据。
+ private NoteData mNoteData;
+ // 定义NoteData对象,用于存储笔记的文本和其他数据。
+ private static final String TAG = "Note";
+ // 定义日志标签。
+
+ /**
+ * Create a new note id for adding a new note to databases
+ */
+ public static synchronized long getNewNoteId(Context context, long folderId) {
+ // 创建一个新的笔记ID并将其添加到数据库中。
+ ContentValues values = new ContentValues();
+ long createdTime = System.currentTimeMillis();
+ values.put(NoteColumns.CREATED_DATE, createdTime);
+ values.put(NoteColumns.MODIFIED_DATE, createdTime);
+ values.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
+ values.put(NoteColumns.LOCAL_MODIFIED, 1);
+ values.put(NoteColumns.PARENT_ID, folderId);
+ Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
+
+ long noteId = 0;
+ try {
+ noteId = Long.valueOf(uri.getPathSegments().get(1));
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Get note id error :" + e.toString());
+ noteId = 0;
+ }
+ if (noteId == -1) {
+ throw new IllegalStateException("Wrong note id:" + noteId);
+ }
+ return noteId;
+ }
+
+ public Note() {
+ // 构造函数,初始化笔记数据。
+ mNoteDiffValues = new ContentValues();
+ mNoteData = new NoteData();
+ }
+
+ public void setNoteValue(String key, String value) {
+ // 设置笔记的值。
+ mNoteDiffValues.put(key, value);
+ mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
+ mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
+ }
+
+ public void setTextData(String key, String value) {
+ // 设置文本数据。
+ mNoteData.setTextData(key, value);
+ }
+
+ public void setTextDataId(long id) {
+ // 设置文本数据ID。
+ mNoteData.setTextDataId(id);
+ }
+
+ public long getTextDataId() {
+ // 获取文本数据ID。
+ return mNoteData.mTextDataId;
+ }
+
+ public void setCallDataId(long id) {
+ // 设置通话数据ID。
+ mNoteData.setCallDataId(id);
+ }
+
+ public void setCallData(String key, String value) {
+ // 设置通话数据。
+ mNoteData.setCallData(key, value);
+ }
+
+ public boolean isLocalModified() {
+ // 检查笔记是否被本地修改。
+ return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified();
+ }
+
+ public boolean syncNote(Context context, long noteId) {
+ // 同步笔记到数据库。
+ if (noteId <= 0) {
+ throw new IllegalArgumentException("Wrong note id:" + noteId);
+ }
+
+ if (!isLocalModified()) {
+ return true;
+ }
+
+ // 更新笔记数据
+ if (context.getContentResolver().update(
+ ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null,
+ null) == 0) {
+ Log.e(TAG, "Update note error, should not happen");
+ // Do not return, fall through
+ }
+ mNoteDiffValues.clear();
+
+ if (mNoteData.isLocalModified()
+ && (mNoteData.pushIntoContentResolver(context, noteId) == null)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private class NoteData {
+ // 内部类,用于存储笔记的文本和通话数据。
+ private long mTextDataId;
+ private ContentValues mTextDataValues;
+ private long mCallDataId;
+ private ContentValues mCallDataValues;
+ private static final String TAG = "NoteData";
+
+ public NoteData() {
+ // 构造函数,初始化数据。
+ mTextDataValues = new ContentValues();
+ mCallDataValues = new ContentValues();
+ mTextDataId = 0;
+ mCallDataId = 0;
+ }
+
+ boolean isLocalModified() {
+ // 检查文本或通话数据是否被本地修改。
+ return mTextDataValues.size() > 0 || mCallDataValues.size() > 0;
+ }
+
+ void setTextDataId(long id) {
+ // 设置文本数据ID。
+ if(id <= 0) {
+ throw new IllegalArgumentException("Text data id should larger than 0");
+ }
+ mTextDataId = id;
+ }
+
+ void setCallDataId(long id) {
+ // 设置通话数据ID。
+ if (id <= 0) {
+ throw new IllegalArgumentException("Call data id should larger than 0");
+ }
+ mCallDataId = id;
+ }
+
+ void setCallData(String key, String value) {
+ // 设置通话数据。
+ mCallDataValues.put(key, value);
+ mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
+ mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
+ }
+
+ void setTextData(String key, String value) {
+ // 设置文本数据。
+ mTextDataValues.put(key, value);
+ mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
+ mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
+ }
+
+ Uri pushIntoContentResolver(Context context, long noteId) {
+ // 将数据推送到内容解析器。
+ // ...
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/model/WorkingNote.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/model/WorkingNote.java
new file mode 100644
index 0000000..be081e4
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/model/WorkingNote.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.model;
+
+import android.appwidget.AppWidgetManager;
+import android.content.ContentUris;
+import android.content.Context;
+import android.database.Cursor;
+import android.text.TextUtils;
+import android.util.Log;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.CallNote;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.DataConstants;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.data.Notes.TextNote;
+import net.micode.notes.tool.ResourceParser.NoteBgResources;
+
+
+public class WorkingNote {
+ // Note for the working note
+ private Note mNote;
+ // Note Id
+ private long mNoteId;
+ // Note content
+ private String mContent;
+ // Note mode
+ private int mMode;
+
+ private long mAlertDate;
+
+ private long mModifiedDate;
+
+ private int mBgColorId;
+
+ private int mWidgetId;
+
+ private int mWidgetType;
+
+ private long mFolderId;
+
+ private Context mContext;
+
+ private static final String TAG = "WorkingNote";
+
+ private boolean mIsDeleted;
+
+ private NoteSettingChangedListener mNoteSettingStatusListener;
+
+ public static final String[] DATA_PROJECTION = new String[] {
+ DataColumns.ID,
+ DataColumns.CONTENT,
+ DataColumns.MIME_TYPE,
+ DataColumns.DATA1,
+ DataColumns.DATA2,
+ DataColumns.DATA3,
+ DataColumns.DATA4,
+ };
+
+ public static final String[] NOTE_PROJECTION = new String[] {
+ NoteColumns.PARENT_ID,
+ NoteColumns.ALERTED_DATE,
+ NoteColumns.BG_COLOR_ID,
+ NoteColumns.WIDGET_ID,
+ NoteColumns.WIDGET_TYPE,
+ NoteColumns.MODIFIED_DATE
+ };
+
+ private static final int DATA_ID_COLUMN = 0;
+
+ private static final int DATA_CONTENT_COLUMN = 1;
+
+ private static final int DATA_MIME_TYPE_COLUMN = 2;
+
+ private static final int DATA_MODE_COLUMN = 3;
+
+ private static final int NOTE_PARENT_ID_COLUMN = 0;
+
+ private static final int NOTE_ALERTED_DATE_COLUMN = 1;
+
+ private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
+
+ private static final int NOTE_WIDGET_ID_COLUMN = 3;
+
+ private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
+
+ private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
+
+ // New note construct
+ private WorkingNote(Context context, long folderId) {
+ mContext = context;
+ mAlertDate = 0;
+ mModifiedDate = System.currentTimeMillis();
+ mFolderId = folderId;
+ mNote = new Note();
+ mNoteId = 0;
+ mIsDeleted = false;
+ mMode = 0;
+ mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
+ }
+
+ // Existing note construct
+ private WorkingNote(Context context, long noteId, long folderId) {
+ mContext = context;
+ mNoteId = noteId;
+ mFolderId = folderId;
+ mIsDeleted = false;
+ mNote = new Note();
+ loadNote();
+ }
+
+ private void loadNote() {
+ Cursor cursor = mContext.getContentResolver().query(
+ ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,
+ null, null);
+
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);
+ mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);
+ mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);
+ mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
+ mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
+ mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
+ }
+ cursor.close();
+ } else {
+ Log.e(TAG, "No note with id:" + mNoteId);
+ throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
+ }
+ loadNoteData();
+ }
+
+ private void loadNoteData() {
+ Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
+ DataColumns.NOTE_ID + "=?", new String[] {
+ String.valueOf(mNoteId)
+ }, null);
+
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ do {
+ String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
+ if (DataConstants.NOTE.equals(type)) {
+ mContent = cursor.getString(DATA_CONTENT_COLUMN);
+ mMode = cursor.getInt(DATA_MODE_COLUMN);
+ mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
+ } else if (DataConstants.CALL_NOTE.equals(type)) {
+ mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));
+ } else {
+ Log.d(TAG, "Wrong note type with type:" + type);
+ }
+ } while (cursor.moveToNext());
+ }
+ cursor.close();
+ } else {
+ Log.e(TAG, "No data with id:" + mNoteId);
+ throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);
+ }
+ }
+
+ public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
+ int widgetType, int defaultBgColorId) {
+ WorkingNote note = new WorkingNote(context, folderId);
+ note.setBgColorId(defaultBgColorId);
+ note.setWidgetId(widgetId);
+ note.setWidgetType(widgetType);
+ return note;
+ }
+
+ public static WorkingNote load(Context context, long id) {
+ return new WorkingNote(context, id, 0);
+ }
+
+ public synchronized boolean saveNote() {
+ if (isWorthSaving()) {
+ if (!existInDatabase()) {
+ if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
+ Log.e(TAG, "Create new note fail with id:" + mNoteId);
+ return false;
+ }
+ }
+
+ mNote.syncNote(mContext, mNoteId);
+
+ /**
+ * Update widget content if there exist any widget of this note
+ */
+ if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
+ && mWidgetType != Notes.TYPE_WIDGET_INVALIDE
+ && mNoteSettingStatusListener != null) {
+ mNoteSettingStatusListener.onWidgetChanged();
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public boolean existInDatabase() {
+ return mNoteId > 0;
+ }
+
+ private boolean isWorthSaving() {
+ if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))
+ || (existInDatabase() && !mNote.isLocalModified())) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
+ mNoteSettingStatusListener = l;
+ }
+
+ public void setAlertDate(long date, boolean set) {
+ if (date != mAlertDate) {
+ mAlertDate = date;
+ mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));
+ }
+ if (mNoteSettingStatusListener != null) {
+ mNoteSettingStatusListener.onClockAlertChanged(date, set);
+ }
+ }
+
+ public void markDeleted(boolean mark) {
+ mIsDeleted = mark;
+ if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
+ && mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
+ mNoteSettingStatusListener.onWidgetChanged();
+ }
+ }
+
+ public void setBgColorId(int id) {
+ if (id != mBgColorId) {
+ mBgColorId = id;
+ if (mNoteSettingStatusListener != null) {
+ mNoteSettingStatusListener.onBackgroundColorChanged();
+ }
+ mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));
+ }
+ }
+
+ public void setCheckListMode(int mode) {
+ if (mMode != mode) {
+ if (mNoteSettingStatusListener != null) {
+ mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
+ }
+ mMode = mode;
+ mNote.setTextData(TextNote.MODE, String.valueOf(mMode));
+ }
+ }
+
+ public void setWidgetType(int type) {
+ if (type != mWidgetType) {
+ mWidgetType = type;
+ mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType));
+ }
+ }
+
+ public void setWidgetId(int id) {
+ if (id != mWidgetId) {
+ mWidgetId = id;
+ mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
+ }
+ }
+
+ public void setWorkingText(String text) {
+ if (!TextUtils.equals(mContent, text)) {
+ mContent = text;
+ mNote.setTextData(DataColumns.CONTENT, mContent);
+ }
+ }
+
+ public void convertToCallNote(String phoneNumber, long callDate) {
+ mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));
+ mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);
+ mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER));
+ }
+
+ public boolean hasClockAlert() {
+ return (mAlertDate > 0 ? true : false);
+ }
+
+ public String getContent() {
+ return mContent;
+ }
+
+ public long getAlertDate() {
+ return mAlertDate;
+ }
+
+ public long getModifiedDate() {
+ return mModifiedDate;
+ }
+
+ public int getBgColorResId() {
+ return NoteBgResources.getNoteBgResource(mBgColorId);
+ }
+
+ public int getBgColorId() {
+ return mBgColorId;
+ }
+
+ public int getTitleBgResId() {
+ return NoteBgResources.getNoteTitleBgResource(mBgColorId);
+ }
+
+ public int getCheckListMode() {
+ return mMode;
+ }
+
+ public long getNoteId() {
+ return mNoteId;
+ }
+
+ public long getFolderId() {
+ return mFolderId;
+ }
+
+ public int getWidgetId() {
+ return mWidgetId;
+ }
+
+ public int getWidgetType() {
+ return mWidgetType;
+ }
+
+ public interface NoteSettingChangedListener {
+ /**
+ * Called when the background color of current note has just changed
+ */
+ void onBackgroundColorChanged();
+
+ /**
+ * Called when user set clock
+ */
+ void onClockAlertChanged(long date, boolean set);
+
+ /**
+ * Call when user create note from widget
+ */
+ void onWidgetChanged();
+
+ /**
+ * Call when switch between check list mode and normal mode
+ * @param oldMode is previous mode before change
+ * @param newMode is new mode
+ */
+ void onCheckListModeChanged(int oldMode, int newMode);
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/BackupUtils.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/BackupUtils.java
new file mode 100644
index 0000000..39f6ec4
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/BackupUtils.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.tool;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.os.Environment;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.util.Log;
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.DataConstants;
+import net.micode.notes.data.Notes.NoteColumns;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+
+
+public class BackupUtils {
+ private static final String TAG = "BackupUtils";
+ // Singleton stuff
+ private static BackupUtils sInstance;
+
+ public static synchronized BackupUtils getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new BackupUtils(context);
+ }
+ return sInstance;
+ }
+
+ /**
+ * Following states are signs to represents backup or restore
+ * status
+ */
+ // Currently, the sdcard is not mounted
+ public static final int STATE_SD_CARD_UNMOUONTED = 0;
+ // The backup file not exist
+ public static final int STATE_BACKUP_FILE_NOT_EXIST = 1;
+ // The data is not well formated, may be changed by other programs
+ public static final int STATE_DATA_DESTROIED = 2;
+ // Some run-time exception which causes restore or backup fails
+ public static final int STATE_SYSTEM_ERROR = 3;
+ // Backup or restore success
+ public static final int STATE_SUCCESS = 4;
+
+ private TextExport mTextExport;
+
+ private BackupUtils(Context context) {
+ mTextExport = new TextExport(context);
+ }
+
+ private static boolean externalStorageAvailable() {
+ return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
+ }
+
+ public int exportToText() {
+ return mTextExport.exportToText();
+ }
+
+ public String getExportedTextFileName() {
+ return mTextExport.mFileName;
+ }
+
+ public String getExportedTextFileDir() {
+ return mTextExport.mFileDirectory;
+ }
+
+ private static class TextExport {
+ private static final String[] NOTE_PROJECTION = {
+ NoteColumns.ID,
+ NoteColumns.MODIFIED_DATE,
+ NoteColumns.SNIPPET,
+ NoteColumns.TYPE
+ };
+
+ private static final int NOTE_COLUMN_ID = 0;
+
+ private static final int NOTE_COLUMN_MODIFIED_DATE = 1;
+
+ private static final int NOTE_COLUMN_SNIPPET = 2;
+
+ private static final String[] DATA_PROJECTION = {
+ DataColumns.CONTENT,
+ DataColumns.MIME_TYPE,
+ DataColumns.DATA1,
+ DataColumns.DATA2,
+ DataColumns.DATA3,
+ DataColumns.DATA4,
+ };
+
+ private static final int DATA_COLUMN_CONTENT = 0;
+
+ private static final int DATA_COLUMN_MIME_TYPE = 1;
+
+ private static final int DATA_COLUMN_CALL_DATE = 2;
+
+ private static final int DATA_COLUMN_PHONE_NUMBER = 4;
+
+ private final String [] TEXT_FORMAT;
+ private static final int FORMAT_FOLDER_NAME = 0;
+ private static final int FORMAT_NOTE_DATE = 1;
+ private static final int FORMAT_NOTE_CONTENT = 2;
+
+ private Context mContext;
+ private String mFileName;
+ private String mFileDirectory;
+
+ public TextExport(Context context) {
+ TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note);
+ mContext = context;
+ mFileName = "";
+ mFileDirectory = "";
+ }
+
+ private String getFormat(int id) {
+ return TEXT_FORMAT[id];
+ }
+
+ /**
+ * Export the folder identified by folder id to text
+ */
+ private void exportFolderToText(String folderId, PrintStream ps) {
+ // Query notes belong to this folder
+ Cursor notesCursor = mContext.getContentResolver().query(Notes.CONTENT_NOTE_URI,
+ NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[] {
+ folderId
+ }, null);
+
+ if (notesCursor != null) {
+ if (notesCursor.moveToFirst()) {
+ do {
+ // Print note's last modified date
+ ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format(
+ mContext.getString(R.string.format_datetime_mdhm),
+ notesCursor.getLong(NOTE_COLUMN_MODIFIED_DATE))));
+ // Query data belong to this note
+ String noteId = notesCursor.getString(NOTE_COLUMN_ID);
+ exportNoteToText(noteId, ps);
+ } while (notesCursor.moveToNext());
+ }
+ notesCursor.close();
+ }
+ }
+
+ /**
+ * Export note identified by id to a print stream
+ */
+ private void exportNoteToText(String noteId, PrintStream ps) {
+ Cursor dataCursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI,
+ DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[] {
+ noteId
+ }, null);
+
+ if (dataCursor != null) {
+ if (dataCursor.moveToFirst()) {
+ do {
+ String mimeType = dataCursor.getString(DATA_COLUMN_MIME_TYPE);
+ if (DataConstants.CALL_NOTE.equals(mimeType)) {
+ // Print phone number
+ String phoneNumber = dataCursor.getString(DATA_COLUMN_PHONE_NUMBER);
+ long callDate = dataCursor.getLong(DATA_COLUMN_CALL_DATE);
+ String location = dataCursor.getString(DATA_COLUMN_CONTENT);
+
+ if (!TextUtils.isEmpty(phoneNumber)) {
+ ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
+ phoneNumber));
+ }
+ // Print call date
+ ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), DateFormat
+ .format(mContext.getString(R.string.format_datetime_mdhm),
+ callDate)));
+ // Print call attachment location
+ if (!TextUtils.isEmpty(location)) {
+ ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
+ location));
+ }
+ } else if (DataConstants.NOTE.equals(mimeType)) {
+ String content = dataCursor.getString(DATA_COLUMN_CONTENT);
+ if (!TextUtils.isEmpty(content)) {
+ ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT),
+ content));
+ }
+ }
+ } while (dataCursor.moveToNext());
+ }
+ dataCursor.close();
+ }
+ // print a line separator between note
+ try {
+ ps.write(new byte[] {
+ Character.LINE_SEPARATOR, Character.LETTER_NUMBER
+ });
+ } catch (IOException e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+
+ /**
+ * Note will be exported as text which is user readable
+ */
+ public int exportToText() {
+ if (!externalStorageAvailable()) {
+ Log.d(TAG, "Media was not mounted");
+ return STATE_SD_CARD_UNMOUONTED;
+ }
+
+ PrintStream ps = getExportToTextPrintStream();
+ if (ps == null) {
+ Log.e(TAG, "get print stream error");
+ return STATE_SYSTEM_ERROR;
+ }
+ // First export folder and its notes
+ Cursor folderCursor = mContext.getContentResolver().query(
+ Notes.CONTENT_NOTE_URI,
+ NOTE_PROJECTION,
+ "(" + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + " AND "
+ + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + ") OR "
+ + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER, null, null);
+
+ if (folderCursor != null) {
+ if (folderCursor.moveToFirst()) {
+ do {
+ // Print folder's name
+ String folderName = "";
+ if(folderCursor.getLong(NOTE_COLUMN_ID) == Notes.ID_CALL_RECORD_FOLDER) {
+ folderName = mContext.getString(R.string.call_record_folder_name);
+ } else {
+ folderName = folderCursor.getString(NOTE_COLUMN_SNIPPET);
+ }
+ if (!TextUtils.isEmpty(folderName)) {
+ ps.println(String.format(getFormat(FORMAT_FOLDER_NAME), folderName));
+ }
+ String folderId = folderCursor.getString(NOTE_COLUMN_ID);
+ exportFolderToText(folderId, ps);
+ } while (folderCursor.moveToNext());
+ }
+ folderCursor.close();
+ }
+
+ // Export notes in root's folder
+ Cursor noteCursor = mContext.getContentResolver().query(
+ Notes.CONTENT_NOTE_URI,
+ NOTE_PROJECTION,
+ NoteColumns.TYPE + "=" + +Notes.TYPE_NOTE + " AND " + NoteColumns.PARENT_ID
+ + "=0", null, null);
+
+ if (noteCursor != null) {
+ if (noteCursor.moveToFirst()) {
+ do {
+ ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format(
+ mContext.getString(R.string.format_datetime_mdhm),
+ noteCursor.getLong(NOTE_COLUMN_MODIFIED_DATE))));
+ // Query data belong to this note
+ String noteId = noteCursor.getString(NOTE_COLUMN_ID);
+ exportNoteToText(noteId, ps);
+ } while (noteCursor.moveToNext());
+ }
+ noteCursor.close();
+ }
+ ps.close();
+
+ return STATE_SUCCESS;
+ }
+
+ /**
+ * Get a print stream pointed to the file {@generateExportedTextFile}
+ */
+ private PrintStream getExportToTextPrintStream() {
+ File file = generateFileMountedOnSDcard(mContext, R.string.file_path,
+ R.string.file_name_txt_format);
+ if (file == null) {
+ Log.e(TAG, "create file to exported failed");
+ return null;
+ }
+ mFileName = file.getName();
+ mFileDirectory = mContext.getString(R.string.file_path);
+ PrintStream ps = null;
+ try {
+ FileOutputStream fos = new FileOutputStream(file);
+ ps = new PrintStream(fos);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ } catch (NullPointerException e) {
+ e.printStackTrace();
+ return null;
+ }
+ return ps;
+ }
+ }
+
+ /**
+ * Generate the text file to store imported data
+ */
+ private static File generateFileMountedOnSDcard(Context context, int filePathResId, int fileNameFormatResId) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(Environment.getExternalStorageDirectory());
+ sb.append(context.getString(filePathResId));
+ File filedir = new File(sb.toString());
+ sb.append(context.getString(
+ fileNameFormatResId,
+ DateFormat.format(context.getString(R.string.format_date_ymd),
+ System.currentTimeMillis())));
+ File file = new File(sb.toString());
+
+ try {
+ if (!filedir.exists()) {
+ filedir.mkdir();
+ }
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ return file;
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+}
+
+
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/DataUtils.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/DataUtils.java
new file mode 100644
index 0000000..2a14982
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/DataUtils.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.tool;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.OperationApplicationException;
+import android.database.Cursor;
+import android.os.RemoteException;
+import android.util.Log;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.CallNote;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+
+public class DataUtils {
+ public static final String TAG = "DataUtils";
+ public static boolean batchDeleteNotes(ContentResolver resolver, HashSet ids) {
+ if (ids == null) {
+ Log.d(TAG, "the ids is null");
+ return true;
+ }
+ if (ids.size() == 0) {
+ Log.d(TAG, "no id is in the hashset");
+ return true;
+ }
+
+ ArrayList operationList = new ArrayList();
+ for (long id : ids) {
+ if(id == Notes.ID_ROOT_FOLDER) {
+ Log.e(TAG, "Don't delete system folder root");
+ continue;
+ }
+ ContentProviderOperation.Builder builder = ContentProviderOperation
+ .newDelete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id));
+ operationList.add(builder.build());
+ }
+ try {
+ ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList);
+ if (results == null || results.length == 0 || results[0] == null) {
+ Log.d(TAG, "delete notes failed, ids:" + ids.toString());
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+ } catch (OperationApplicationException e) {
+ Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+ }
+ return false;
+ }
+
+ public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) {
+ ContentValues values = new ContentValues();
+ values.put(NoteColumns.PARENT_ID, desFolderId);
+ values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId);
+ values.put(NoteColumns.LOCAL_MODIFIED, 1);
+ resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null);
+ }
+
+ public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids,
+ long folderId) {
+ if (ids == null) {
+ Log.d(TAG, "the ids is null");
+ return true;
+ }
+
+ ArrayList operationList = new ArrayList();
+ for (long id : ids) {
+ ContentProviderOperation.Builder builder = ContentProviderOperation
+ .newUpdate(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id));
+ builder.withValue(NoteColumns.PARENT_ID, folderId);
+ builder.withValue(NoteColumns.LOCAL_MODIFIED, 1);
+ operationList.add(builder.build());
+ }
+
+ try {
+ ContentProviderResult[] results = resolver.applyBatch(Notes.AUTHORITY, operationList);
+ if (results == null || results.length == 0 || results[0] == null) {
+ Log.d(TAG, "delete notes failed, ids:" + ids.toString());
+ return false;
+ }
+ return true;
+ } catch (RemoteException e) {
+ Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+ } catch (OperationApplicationException e) {
+ Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
+ }
+ return false;
+ }
+
+ /**
+ * Get the all folder count except system folders {@link Notes#TYPE_SYSTEM}}
+ */
+ public static int getUserFolderCount(ContentResolver resolver) {
+ Cursor cursor =resolver.query(Notes.CONTENT_NOTE_URI,
+ new String[] { "COUNT(*)" },
+ NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>?",
+ new String[] { String.valueOf(Notes.TYPE_FOLDER), String.valueOf(Notes.ID_TRASH_FOLER)},
+ null);
+
+ int count = 0;
+ if(cursor != null) {
+ if(cursor.moveToFirst()) {
+ try {
+ count = cursor.getInt(0);
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "get folder count failed:" + e.toString());
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+ return count;
+ }
+
+ public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) {
+ Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
+ null,
+ NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER,
+ new String [] {String.valueOf(type)},
+ null);
+
+ boolean exist = false;
+ if (cursor != null) {
+ if (cursor.getCount() > 0) {
+ exist = true;
+ }
+ cursor.close();
+ }
+ return exist;
+ }
+
+ public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) {
+ Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
+ null, null, null, null);
+
+ boolean exist = false;
+ if (cursor != null) {
+ if (cursor.getCount() > 0) {
+ exist = true;
+ }
+ cursor.close();
+ }
+ return exist;
+ }
+
+ public static boolean existInDataDatabase(ContentResolver resolver, long dataId) {
+ Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId),
+ null, null, null, null);
+
+ boolean exist = false;
+ if (cursor != null) {
+ if (cursor.getCount() > 0) {
+ exist = true;
+ }
+ cursor.close();
+ }
+ return exist;
+ }
+
+ public static boolean checkVisibleFolderName(ContentResolver resolver, String name) {
+ Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, null,
+ NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER +
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER +
+ " AND " + NoteColumns.SNIPPET + "=?",
+ new String[] { name }, null);
+ boolean exist = false;
+ if(cursor != null) {
+ if(cursor.getCount() > 0) {
+ exist = true;
+ }
+ cursor.close();
+ }
+ return exist;
+ }
+
+ public static HashSet getFolderNoteWidget(ContentResolver resolver, long folderId) {
+ Cursor c = resolver.query(Notes.CONTENT_NOTE_URI,
+ new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE },
+ NoteColumns.PARENT_ID + "=?",
+ new String[] { String.valueOf(folderId) },
+ null);
+
+ HashSet set = null;
+ if (c != null) {
+ if (c.moveToFirst()) {
+ set = new HashSet();
+ do {
+ try {
+ AppWidgetAttribute widget = new AppWidgetAttribute();
+ widget.widgetId = c.getInt(0);
+ widget.widgetType = c.getInt(1);
+ set.add(widget);
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, e.toString());
+ }
+ } while (c.moveToNext());
+ }
+ c.close();
+ }
+ return set;
+ }
+
+ public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) {
+ Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
+ new String [] { CallNote.PHONE_NUMBER },
+ CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?",
+ new String [] { String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE },
+ null);
+
+ if (cursor != null && cursor.moveToFirst()) {
+ try {
+ return cursor.getString(0);
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "Get call number fails " + e.toString());
+ } finally {
+ cursor.close();
+ }
+ }
+ return "";
+ }
+
+ public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) {
+ Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
+ new String [] { CallNote.NOTE_ID },
+ CallNote.CALL_DATE + "=? AND " + CallNote.MIME_TYPE + "=? AND PHONE_NUMBERS_EQUAL("
+ + CallNote.PHONE_NUMBER + ",?)",
+ new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber },
+ null);
+
+ if (cursor != null) {
+ if (cursor.moveToFirst()) {
+ try {
+ return cursor.getLong(0);
+ } catch (IndexOutOfBoundsException e) {
+ Log.e(TAG, "Get call note id fails " + e.toString());
+ }
+ }
+ cursor.close();
+ }
+ return 0;
+ }
+
+ public static String getSnippetById(ContentResolver resolver, long noteId) {
+ Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI,
+ new String [] { NoteColumns.SNIPPET },
+ NoteColumns.ID + "=?",
+ new String [] { String.valueOf(noteId)},
+ null);
+
+ if (cursor != null) {
+ String snippet = "";
+ if (cursor.moveToFirst()) {
+ snippet = cursor.getString(0);
+ }
+ cursor.close();
+ return snippet;
+ }
+ throw new IllegalArgumentException("Note is not found with id: " + noteId);
+ }
+
+ public static String getFormattedSnippet(String snippet) {
+ if (snippet != null) {
+ snippet = snippet.trim();
+ int index = snippet.indexOf('\n');
+ if (index != -1) {
+ snippet = snippet.substring(0, index);
+ }
+ }
+ return snippet;
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/GTaskStringUtils.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/GTaskStringUtils.java
new file mode 100644
index 0000000..c1bfa6e
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/GTaskStringUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.tool;
+// 声明代码所属的包路径。
+
+public class GTaskStringUtils {
+ // 定义GTaskStringUtils类,用于存储GTask相关的字符串常量。
+
+ // 定义GTask JSON相关常量。
+ public final static String GTASK_JSON_ACTION_ID = "action_id";
+ public final static String GTASK_JSON_ACTION_LIST = "action_list";
+ public final static String GTASK_JSON_ACTION_TYPE = "action_type";
+ // ...
+
+ // 定义GTask操作类型常量。
+ public final static String GTASK_JSON_ACTION_TYPE_CREATE = "create";
+ public final static String GTASK_JSON_ACTION_TYPE_GETALL = "get_all";
+ public final static String GTASK_JSON_ACTION_TYPE_MOVE = "move";
+ public final static String GTASK_JSON_ACTION_TYPE_UPDATE = "update";
+ // ...
+
+ // 定义GTask其他相关常量。
+ public final static String GTASK_JSON_CREATOR_ID = "creator_id";
+ public final static String GTASK_JSON_CHILD_ENTITY = "child_entity";
+ public final static String GTASK_JSON_CLIENT_VERSION = "client_version";
+ // ...
+
+ // 定义MIUI文件夹前缀和特殊文件夹名称。
+ public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]";
+ public final static String FOLDER_DEFAULT = "Default";
+ public final static String FOLDER_CALL_NOTE = "Call_Note";
+ public final static String FOLDER_META = "METADATA";
+ // ...
+
+ // 定义元数据相关常量。
+ public final static String META_HEAD_GTASK_ID = "meta_gid";
+ public final static String META_HEAD_NOTE = "meta_note";
+ public final static String META_HEAD_DATA = "meta_data";
+ public final static String META_NOTE_NAME = "[META INFO] DON'T UPDATE AND DELETE";
+ // ...
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/ResourceParser.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/ResourceParser.java
new file mode 100644
index 0000000..1ad3ad6
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/tool/ResourceParser.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.tool;
+
+import android.content.Context;
+import android.preference.PreferenceManager;
+
+import net.micode.notes.R;
+import net.micode.notes.ui.NotesPreferenceActivity;
+
+public class ResourceParser {
+
+ public static final int YELLOW = 0;
+ public static final int BLUE = 1;
+ public static final int WHITE = 2;
+ public static final int GREEN = 3;
+ public static final int RED = 4;
+
+ public static final int BG_DEFAULT_COLOR = YELLOW;
+
+ public static final int TEXT_SMALL = 0;
+ public static final int TEXT_MEDIUM = 1;
+ public static final int TEXT_LARGE = 2;
+ public static final int TEXT_SUPER = 3;
+
+ public static final int BG_DEFAULT_FONT_SIZE = TEXT_MEDIUM;
+
+ public static class NoteBgResources {
+ private final static int [] BG_EDIT_RESOURCES = new int [] {
+ R.drawable.edit_yellow,
+ R.drawable.edit_blue,
+ R.drawable.edit_white,
+ R.drawable.edit_green,
+ R.drawable.edit_red
+ };
+
+ private final static int [] BG_EDIT_TITLE_RESOURCES = new int [] {
+ R.drawable.edit_title_yellow,
+ R.drawable.edit_title_blue,
+ R.drawable.edit_title_white,
+ R.drawable.edit_title_green,
+ R.drawable.edit_title_red
+ };
+
+ public static int getNoteBgResource(int id) {
+ return BG_EDIT_RESOURCES[id];
+ }
+
+ public static int getNoteTitleBgResource(int id) {
+ return BG_EDIT_TITLE_RESOURCES[id];
+ }
+ }
+
+ public static int getDefaultBgId(Context context) {
+ if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
+ NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) {
+ return (int) (Math.random() * NoteBgResources.BG_EDIT_RESOURCES.length);
+ } else {
+ return BG_DEFAULT_COLOR;
+ }
+ }
+
+ public static class NoteItemBgResources {
+ private final static int [] BG_FIRST_RESOURCES = new int [] {
+ R.drawable.list_yellow_up,
+ R.drawable.list_blue_up,
+ R.drawable.list_white_up,
+ R.drawable.list_green_up,
+ R.drawable.list_red_up
+ };
+
+ private final static int [] BG_NORMAL_RESOURCES = new int [] {
+ R.drawable.list_yellow_middle,
+ R.drawable.list_blue_middle,
+ R.drawable.list_white_middle,
+ R.drawable.list_green_middle,
+ R.drawable.list_red_middle
+ };
+
+ private final static int [] BG_LAST_RESOURCES = new int [] {
+ R.drawable.list_yellow_down,
+ R.drawable.list_blue_down,
+ R.drawable.list_white_down,
+ R.drawable.list_green_down,
+ R.drawable.list_red_down,
+ };
+
+ private final static int [] BG_SINGLE_RESOURCES = new int [] {
+ R.drawable.list_yellow_single,
+ R.drawable.list_blue_single,
+ R.drawable.list_white_single,
+ R.drawable.list_green_single,
+ R.drawable.list_red_single
+ };
+
+ public static int getNoteBgFirstRes(int id) {
+ return BG_FIRST_RESOURCES[id];
+ }
+
+ public static int getNoteBgLastRes(int id) {
+ return BG_LAST_RESOURCES[id];
+ }
+
+ public static int getNoteBgSingleRes(int id) {
+ return BG_SINGLE_RESOURCES[id];
+ }
+
+ public static int getNoteBgNormalRes(int id) {
+ return BG_NORMAL_RESOURCES[id];
+ }
+
+ public static int getFolderBgRes() {
+ return R.drawable.list_folder;
+ }
+ }
+
+ public static class WidgetBgResources {
+ private final static int [] BG_2X_RESOURCES = new int [] {
+ R.drawable.widget_2x_yellow,
+ R.drawable.widget_2x_blue,
+ R.drawable.widget_2x_white,
+ R.drawable.widget_2x_green,
+ R.drawable.widget_2x_red,
+ };
+
+ public static int getWidget2xBgResource(int id) {
+ return BG_2X_RESOURCES[id];
+ }
+
+ private final static int [] BG_4X_RESOURCES = new int [] {
+ R.drawable.widget_4x_yellow,
+ R.drawable.widget_4x_blue,
+ R.drawable.widget_4x_white,
+ R.drawable.widget_4x_green,
+ R.drawable.widget_4x_red
+ };
+
+ public static int getWidget4xBgResource(int id) {
+ return BG_4X_RESOURCES[id];
+ }
+ }
+
+ public static class TextAppearanceResources {
+ private final static int [] TEXTAPPEARANCE_RESOURCES = new int [] {
+ R.style.TextAppearanceNormal,
+ R.style.TextAppearanceMedium,
+ R.style.TextAppearanceLarge,
+ R.style.TextAppearanceSuper
+ };
+
+ public static int getTexAppearanceResource(int id) {
+ /**
+ * HACKME: Fix bug of store the resource id in shared preference.
+ * The id may larger than the length of resources, in this case,
+ * return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
+ */
+ if (id >= TEXTAPPEARANCE_RESOURCES.length) {
+ return BG_DEFAULT_FONT_SIZE;
+ }
+ return TEXTAPPEARANCE_RESOURCES[id];
+ }
+
+ public static int getResourcesSize() {
+ return TEXTAPPEARANCE_RESOURCES.length;
+ }
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java
new file mode 100644
index 0000000..d24cf2c
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmAlertActivity.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2010 - 2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE 2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// 包声明,表明该类所在的包名,这里是笔记应用相关的UI包
+package net.micode.notes.ui;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.provider.Settings;
+import android.view.Window;
+import android.view.WindowManager;
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.tool.DataUtils;
+
+import java.io.IOException;
+
+// AlarmAlertActivity类继承自Activity,用于处理闹钟提醒相关的界面展示和操作逻辑,同时实现了OnClickListener和OnDismissListener接口来处理对话框的点击和关闭事件
+public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
+ // 记录笔记的ID,用于后续查找对应的笔记等相关操作
+ private long mNoteId;
+ // 笔记内容的摘要信息,用于在提醒对话框中展示
+ private String mSnippet;
+ // 摘要信息最大长度限制,超过这个长度会进行截断处理并添加额外提示信息
+ private static final int SNIPPET_PREW_MAX_LEN = 60;
+ // 用于播放闹钟提醒声音的MediaPlayer对象
+ MediaPlayer mPlayer;
+
+ // Activity创建时调用的方法,进行一些初始化操作
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 设置窗口特性,去除标题栏
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ final Window win = getWindow();
+ // 设置窗口属性,使得在屏幕锁定时也能显示该Activity
+ 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 {
+ // 从传入的Intent中获取数据部分,解析出笔记的ID,这里假设传入的数据格式是特定的路径形式,从中提取第二个路径段作为笔记ID
+ mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
+ // 通过工具类DataUtils根据笔记ID获取笔记的摘要内容
+ mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
+ // 如果摘要内容长度超过最大限制长度,进行截断处理,并添加相应的提示字符串(比如表示内容还有更多等提示)
+ 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;
+ }
+
+ // 创建MediaPlayer对象,用于播放声音
+ mPlayer = new MediaPlayer();
+ // 判断笔记是否在笔记数据库中可见(通过DataUtils工具类的方法进行判断),如果可见则展示操作对话框并播放闹钟声音,否则直接结束该Activity
+ if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
+ showActionDialog();
+ playAlarmSound();
+ } else {
+ finish();
+ }
+ }
+
+ // 判断屏幕是否处于开启状态的方法,通过获取PowerManager服务并调用其isScreenOn方法来判断
+ private boolean isScreenOn() {
+ PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ return pm.isScreenOn();
+ }
+
+ // 播放闹钟提醒声音的方法
+ private void playAlarmSound() {
+ // 获取系统默认的闹钟铃声的Uri
+ Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
+
+ // 获取系统设置中受静音模式影响的音频流相关设置
+ int silentModeStreams = Settings.System.getInt(getContentResolver(),
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
+
+ // 根据静音模式相关设置来决定设置MediaPlayer的音频流类型,如果闹钟音频流在受影响的范围内则按该设置,否则设置为常规的闹钟音频流类型
+ if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM))!= 0) {
+ mPlayer.setAudioStreamType(silentModeStreams);
+ } else {
+ mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
+ }
+
+ try {
+ // 设置MediaPlayer要播放的数据源为获取到的铃声Uri
+ mPlayer.setDataSource(this, url);
+ // 准备MediaPlayer,使其处于可播放状态(可能会涉及加载音频资源等操作)
+ mPlayer.prepare();
+ // 设置为循环播放
+ mPlayer.setLooping(true);
+ // 开始播放声音
+ mPlayer.start();
+ } catch (IllegalArgumentException e) {
+ // 捕获非法参数异常并打印堆栈信息,通常是参数设置不符合要求等情况导致
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ // 捕获安全相关异常并打印堆栈信息,比如可能缺少相应权限等情况导致
+ e.printStackTrace();
+ } catch (IllegalStateException e) {
+ // 捕获非法状态异常并打印堆栈信息,比如在不恰当的状态下调用方法等情况导致
+ e.printStackTrace();
+ } catch (IOException e) {
+ // 捕获输入输出相关异常并打印堆栈信息,比如读取音频数据源出错等情况导致
+ e.printStackTrace();
+ }
+ }
+
+ // 展示操作对话框的方法,对话框中包含笔记摘要信息等内容以及相应的操作按钮
+ private void showActionDialog() {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(this);
+ // 设置对话框标题为应用名称(通过资源文件中的字符串资源获取)
+ dialog.setTitle(R.string.app_name);
+ // 设置对话框消息内容为笔记摘要信息
+ dialog.setMessage(mSnippet);
+ // 设置对话框的确认按钮(通常表示知晓、确认等操作)以及对应的点击事件监听器(当前类实现了该监听器接口)
+ dialog.setPositiveButton(R.string.notealert_ok, this);
+ // 如果屏幕处于开启状态,设置对话框的进入按钮(可能用于进入笔记编辑等相关操作)以及对应的点击事件监听器
+ if (isScreenOn()) {
+ dialog.setNegativeButton(R.string.notealert_enter, this);
+ }
+ // 构建并显示对话框,并设置对话框关闭的监听器(当前类也实现了该监听器接口)
+ dialog.show().setOnDismissListener(this);
+ }
+
+ // 实现OnClickListener接口的方法,用于处理对话框按钮点击事件
+ public void onClick(DialogInterface dialog, int which) {
+ switch (which) {
+ // 如果点击的是对话框的否定按钮(比如进入按钮)
+ case DialogInterface.BUTTON_NEGATIVE:
+ // 创建一个Intent,用于启动笔记编辑Activity(NoteEditActivity),设置查看操作的Action,并将笔记ID作为额外数据传递过去
+ Intent intent = new Intent(this, NoteEditActivity.class);
+ intent.setAction(Intent.ACTION_VIEW);
+ intent.putExtra(Intent.EXTRA_UID, mNoteId);
+ startActivity(intent);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // 实现OnDismissListener接口的方法,用于处理对话框关闭事件
+ public void onDismiss(DialogInterface dialog) {
+ // 调用停止闹钟声音的方法,关闭并释放MediaPlayer资源
+ stopAlarmSound();
+ // 结束当前Activity
+ finish();
+ }
+
+ // 停止闹钟声音的方法,释放MediaPlayer相关资源
+ private void stopAlarmSound() {
+ if (mPlayer!= null) {
+ mPlayer.stop();
+ mPlayer.release();
+ mPlayer = null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java
new file mode 100644
index 0000000..0c18e87
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmInitReceiver.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包。
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.NoteColumns;
+// 导入所需的Android类和接口,以及应用程序特定的类。
+
+public class AlarmInitReceiver extends BroadcastReceiver {
+ // 定义一个继承自BroadcastReceiver的类,用于处理闹钟初始化。
+
+ private static final String [] PROJECTION = new String [] {
+ NoteColumns.ID,
+ NoteColumns.ALERTED_DATE
+ };
+ // 定义一个数组,指定查询数据库时需要返回的列。
+
+ private static final int COLUMN_ID = 0;
+ private static final int COLUMN_ALERTED_DATE = 1;
+ // 定义列索引常量,用于在查询结果中快速定位到特定的列。
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 实现onReceive方法,这是BroadcastReceiver的核心方法,当接收到广播时会被调用。
+ long currentDate = System.currentTimeMillis();
+ // 获取当前时间的毫秒值。
+
+ Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
+ PROJECTION,
+ NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
+ new String[] { String.valueOf(currentDate) },
+ null);
+ // 查询数据库,获取所有未提醒且类型为笔记的记录。
+
+ if (c != null) {
+ if (c.moveToFirst()) {
+ do {
+ long alertDate = c.getLong(COLUMN_ALERTED_DATE);
+ // 获取每条记录的提醒日期。
+ Intent sender = new Intent(context, AlarmReceiver.class);
+ // 创建一个新的Intent,用于触发AlarmReceiver。
+ sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID)));
+ // 设置Intent的数据,包含笔记的ID。
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0);
+ // 创建一个PendingIntent,用于AlarmManager设置闹钟。
+ AlarmManager alermManager = (AlarmManager) context
+ .getSystemService(Context.ALARM_SERVICE);
+ // 获取AlarmManager服务。
+ alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);
+ // 设置闹钟,当到达提醒日期时,AlarmManager将调用AlarmReceiver。
+ } while (c.moveToNext());
+ // 遍历查询结果中的所有记录。
+ }
+ c.close();
+ // 关闭游标。
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java
new file mode 100644
index 0000000..4e74dba
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/AlarmReceiver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+// 导入所需的BroadcastReceiver、Context和Intent类。
+
+public class AlarmReceiver extends BroadcastReceiver {
+ // 定义一个继承自BroadcastReceiver的类,用于处理闹钟提醒。
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // 实现onReceive方法,这是BroadcastReceiver的核心方法,当接收到广播时会被调用。
+
+ intent.setClass(context, AlarmAlertActivity.class);
+ // 修改接收到的Intent,设置其目标为AlarmAlertActivity。
+
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ // 为Intent添加一个标志,表示这个Activity是一个新任务的开始。
+
+ context.startActivity(intent);
+ // 使用context启动设置好的Intent,即启动AlarmAlertActivity。
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DateTimePicker.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DateTimePicker.java
new file mode 100644
index 0000000..5c8979a
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DateTimePicker.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import java.text.DateFormatSymbols;
+import java.util.Calendar;
+// 导入所需的Java类。
+
+import net.micode.notes.R;
+// 导入应用程序的资源类。
+
+import android.content.Context;
+import android.text.format.DateFormat;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.NumberPicker;
+// 导入所需的Android类。
+
+public class DateTimePicker extends FrameLayout {
+ // 定义DateTimePicker类,继承自FrameLayout。
+
+ // 定义一系列常量,用于NumberPicker的最小值和最大值。
+ private static final boolean DEFAULT_ENABLE_STATE = true;
+ private static final int HOURS_IN_HALF_DAY = 12;
+ private static final int HOURS_IN_ALL_DAY = 24;
+ private static final int DAYS_IN_ALL_WEEK = 7;
+ private static final int DATE_SPINNER_MIN_VAL = 0;
+ private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1;
+ private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0;
+ private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23;
+ private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1;
+ private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12;
+ private static final int MINUT_SPINNER_MIN_VAL = 0;
+ 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;
+
+ // 定义NumberPicker变量,用于日期、小时、分钟和上午/下午的选择。
+ private final NumberPicker mDateSpinner;
+ private final NumberPicker mHourSpinner;
+ private final NumberPicker mMinuteSpinner;
+ private final NumberPicker mAmPmSpinner;
+ private Calendar mDate;
+
+ // 定义日期显示值数组。
+ private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK];
+
+ // 定义是否为上午和是否为24小时视图的标志。
+ private boolean mIsAm;
+ private boolean mIs24HourView;
+
+ // 定义是否启用控件的标志。
+ private boolean mIsEnabled = DEFAULT_ENABLE_STATE;
+
+ // 定义初始化标志。
+ private boolean mInitialising;
+
+ // 定义日期时间改变监听器。
+ private OnDateTimeChangedListener mOnDateTimeChangedListener;
+
+ // 定义日期改变监听器。
+ private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ // 当日期改变时,更新日期。
+ mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal);
+ updateDateControl();
+ onDateTimeChanged();
+ }
+ };
+
+ // 定义小时改变监听器。
+ private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ // 当小时改变时,更新小时。
+ // 省略了部分代码...
+ }
+ };
+
+ // 定义分钟改变监听器。
+ private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ // 当分钟改变时,更新分钟。
+ // 省略了部分代码...
+ }
+ };
+
+ // 定义上午/下午改变监听器。
+ private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
+ @Override
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ // 当上午/下午改变时,更新时间。
+ mIsAm = !mIsAm;
+ if (mIsAm) {
+ mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY);
+ } else {
+ mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY);
+ }
+ updateAmPmControl();
+ onDateTimeChanged();
+ }
+ };
+
+ // 定义日期时间改变监听器接口。
+ public interface OnDateTimeChangedListener {
+ void onDateTimeChanged(DateTimePicker view, int year, int month,
+ int dayOfMonth, int hourOfDay, int minute);
+ }
+
+ // DateTimePicker构造函数,初始化视图和控件。
+ public DateTimePicker(Context context) {
+ this(context, System.currentTimeMillis());
+ }
+
+ public DateTimePicker(Context context, long date) {
+ this(context, date, DateFormat.is24HourFormat(context));
+ }
+
+ 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);
+
+ // 初始化NumberPicker控件,并设置监听器。
+ mDateSpinner = (NumberPicker) findViewById(R.id.date);
+ mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL);
+ mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL);
+ mDateSpinner.setOnValueChangedListener(mOnDateChangedListener);
+
+ mHourSpinner = (NumberPicker) findViewById(R.id.hour);
+ mHourSpinner.setOnValueChangedListener(mOnHourChangedListener);
+ mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
+ mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL);
+ mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL);
+ mMinuteSpinner.setOnLongPressUpdateInterval(100);
+ mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);
+
+ // 初始化上午/下午选择器。
+ String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();
+ mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
+ mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL);
+ mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL);
+ mAmPmSpinner.setDisplayedValues(stringsForAmPm);
+ mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener);
+
+ // 更新控件到初始状态。
+ updateDateControl();
+ updateHourControl();
+ updateAmPmControl();
+
+ set24HourView(is24HourView);
+
+ // 设置当前时间。
+ setCurrentDate(date);
+
+ setEnabled(isEnabled());
+
+ // 设置内容描述。
+ mInitialising = false;
+ }
+
+ // 设置控件是否可用。
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (mIsEnabled == enabled) {
+ return;
+ }
+ super.setEnabled(enabled);
+ mDateSpinner.setEnabled(enabled);
+ mMinuteSpinner.setEnabled(enabled);
+ mHourSpinner.setEnabled(enabled);
+ mAmPmSpinner.setEnabled(enabled);
+ mIsEnabled = enabled;
+ }
+
+ // 获取控件是否可用。
+ @Override
+ public boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ // 获取当前日期(毫秒)。
+ public long getCurrentDateInTimeMillis() {
+ return mDate.getTimeInMillis();
+ }
+
+ // 设置当前日期。
+ public void setCurrentDate(long date) {
+ Calendar cal = Calendar.getInstance();
+ 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));
+ }
+
+ // 设置当前日期。
+ public void setCurrentDate(int year, int month,
+ int dayOfMonth, int hourOfDay, int minute) {
+ setCurrentYear(year);
+ setCurrentMonth(month);
+ setCurrentDay(dayOfMonth);
+ setCurrentHour(hourOfDay);
+ setCurrentMinute(minute);
+ }
+
+ // 获取当前年份。
+ public int getCurrentYear() {
+ return mDate.get(Calendar.YEAR);
+ }
+
+ // 设置当前年份。
+ public void setCurrentYear(int year) {
+ if (!mInitialising && year == getCurrentYear()) {
+ return;
+ }
+ mDate.set(Calendar.YEAR, year);
+ updateDateControl();
+ onDateTimeChanged();
+ }
+
+ // 获取当前月份。
+ public int getCurrentMonth() {
+ return mDate.get(Calendar.MONTH);
+ }
+
+ // 设置当前月份。
+ public void setCurrentMonth(int month) {
+ if (!mInitialising && month == getCurrentMonth()) {
+ return;
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java
new file mode 100644
index 0000000..f0c8179
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import java.util.Calendar;
+// 导入所需的Java类。
+
+import net.micode.notes.R;
+import net.micode.notes.ui.DateTimePicker;
+import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener;
+// 导入应用程序的资源类和自定义控件类。
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+// 导入所需的Android类。
+
+public class DateTimePickerDialog extends AlertDialog implements OnClickListener {
+ // 定义DateTimePickerDialog类,继承自AlertDialog并实现OnClickListener接口。
+
+ private Calendar mDate = Calendar.getInstance();
+ // 创建一个Calendar实例,用于存储日期时间数据。
+ private boolean mIs24HourView;
+ // 定义一个标志,用于标识是否为24小时制视图。
+ private OnDateTimeSetListener mOnDateTimeSetListener;
+ // 定义一个监听器,用于处理日期时间设置事件。
+ private DateTimePicker mDateTimePicker;
+ // 创建DateTimePicker实例,用于选择日期时间。
+
+ public interface OnDateTimeSetListener {
+ void OnDateTimeSet(AlertDialog dialog, long date);
+ }
+ // 定义一个内部接口,用于回调日期时间设置事件。
+
+ // DateTimePickerDialog构造函数,初始化对话框视图和事件。
+ public DateTimePickerDialog(Context context, long date) {
+ super(context);
+ mDateTimePicker = new DateTimePicker(context);
+ setView(mDateTimePicker);
+ // 设置对话框内容视图为DateTimePicker。
+ mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
+ public void onDateTimeChanged(DateTimePicker view, int year, int month,
+ int dayOfMonth, int hourOfDay, int minute) {
+ mDate.set(Calendar.YEAR, year);
+ mDate.set(Calendar.MONTH, month);
+ 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);
+ mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
+ // 设置DateTimePicker的初始日期时间。
+ setButton(context.getString(R.string.datetime_dialog_ok), this);
+ // 设置“确定”按钮。
+ setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null);
+ // 设置“取消”按钮,无操作。
+ set24HourView(DateFormat.is24HourFormat(this.getContext()));
+ // 设置24小时制视图。
+ updateTitle(mDate.getTimeInMillis());
+ // 更新对话框标题。
+ }
+
+ // 设置24小时制视图。
+ public void set24HourView(boolean is24HourView) {
+ mIs24HourView = is24HourView;
+ }
+
+ // 设置日期时间设置监听器。
+ public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
+ mOnDateTimeSetListener = callBack;
+ }
+
+ // 更新对话框标题。
+ private void updateTitle(long date) {
+ int flag =
+ DateUtils.FORMAT_SHOW_YEAR |
+ DateUtils.FORMAT_SHOW_DATE |
+ DateUtils.FORMAT_SHOW_TIME;
+ flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_12HOUR;
+ setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
+ }
+
+ // 点击事件处理。
+ public void onClick(DialogInterface arg0, int arg1) {
+ if (mOnDateTimeSetListener != null) {
+ mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DropdownMenu.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DropdownMenu.java
new file mode 100644
index 0000000..15bab7f
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/DropdownMenu.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.PopupMenu;
+import android.widget.PopupMenu.OnMenuItemClickListener;
+// 导入所需的Android类和接口。
+
+import net.micode.notes.R;
+// 导入应用程序的资源类。
+
+public class DropdownMenu {
+ // 定义DropdownMenu类。
+
+ private Button mButton;
+ // 定义一个Button成员变量,用于显示弹出菜单的按钮。
+ private PopupMenu mPopupMenu;
+ // 定义一个PopupMenu成员变量,用于弹出菜单。
+ private Menu mMenu;
+ // 定义一个Menu成员变量,用于菜单项。
+
+ public DropdownMenu(Context context, Button button, int menuId) {
+ // 构造函数,初始化DropdownMenu。
+ mButton = button;
+ mButton.setBackgroundResource(R.drawable.dropdown_icon);
+ // 设置按钮的背景资源。
+ mPopupMenu = new PopupMenu(context, mButton);
+ // 创建PopupMenu实例。
+ mMenu = mPopupMenu.getMenu();
+ // 获取PopupMenu的Menu。
+ mPopupMenu.getMenuInflater().inflate(menuId, mMenu);
+ // 从指定的资源文件中充气菜单项。
+ mButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ mPopupMenu.show();
+ }
+ });
+ // 设置按钮的点击事件监听器,点击时显示PopupMenu。
+ }
+
+ public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) {
+ // 设置PopupMenu项点击事件监听器。
+ if (mPopupMenu != null) {
+ mPopupMenu.setOnMenuItemClickListener(listener);
+ }
+ }
+
+ public MenuItem findItem(int id) {
+ // 查找具有指定ID的菜单项。
+ return mMenu.findItem(id);
+ }
+
+ public void setTitle(CharSequence title) {
+ // 设置按钮的标题。
+ mButton.setText(title);
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java
new file mode 100644
index 0000000..0b62f63
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.Context;
+import android.database.Cursor;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CursorAdapter;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+// 导入所需的Android类和接口。
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.NoteColumns;
+// 导入应用程序的资源类和数据模型类。
+
+public class FoldersListAdapter extends CursorAdapter {
+ // 定义FoldersListAdapter类,继承自CursorAdapter。
+
+ public static final String [] PROJECTION = {
+ NoteColumns.ID,
+ NoteColumns.SNIPPET
+ };
+ // 定义查询数据库时需要的列。
+
+ public static final int ID_COLUMN = 0;
+ public static final int NAME_COLUMN = 1;
+ // 定义列索引常量。
+
+ public FoldersListAdapter(Context context, Cursor c) {
+ super(context, c);
+ // 调用父类的构造函数进行初始化。
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ // 创建新的列表项视图。
+ return new FolderListItem(context);
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ // 将数据绑定到视图上。
+ if (view instanceof FolderListItem) {
+ String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
+ .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);
+ }
+
+ private class FolderListItem extends LinearLayout {
+ // 定义一个内部类,表示列表中的单个文件夹项。
+ private TextView mName;
+
+ public FolderListItem(Context context) {
+ super(context);
+ inflate(context, R.layout.folder_list_item, this);
+ // inflate文件夹项的布局。
+ mName = (TextView) findViewById(R.id.tv_folder_name);
+ // 初始化名称文本视图。
+ }
+
+ public void bind(String name) {
+ // 将文件夹名称绑定到视图上。
+ mName.setText(name);
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
new file mode 100644
index 0000000..1c86731
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+// 导入所需的Android类和接口。
+import android.app.Activity;
+// ...
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class NoteEditActivity extends Activity implements OnClickListener,
+ NoteSettingChangedListener, OnTextViewChangeListener {
+ // 定义NoteEditActivity类,继承自Activity并实现多个接口。
+
+ private class HeadViewHolder {
+ // 内部类,用于持有标题栏的视图元素。
+ public TextView tvModified;
+ public ImageView ivAlertIcon;
+ public TextView tvAlertDate;
+ public ImageView ibSetBgColor;
+ }
+
+ // 定义背景颜色选择器和字体大小选择器的映射。
+ private static final Map sBgSelectorBtnsMap = new HashMap();
+ static {
+ // 初始化背景颜色按钮映射。
+ }
+ // ...
+
+ private static final String TAG = "NoteEditActivity";
+ // 定义日志标签。
+
+ private HeadViewHolder mNoteHeaderHolder;
+ // 定义标题栏视图元素的引用。
+ private View mHeadViewPanel;
+ // 定义标题面板视图。
+ private View mNoteBgColorSelector;
+ // 定义背景颜色选择器视图。
+ private View mFontSizeSelector;
+ // 定义字体大小选择器视图。
+ private EditText mNoteEditor;
+ // 定义笔记编辑器文本框。
+ private View mNoteEditorPanel;
+ // 定义笔记编辑器面板视图。
+ private WorkingNote mWorkingNote;
+ // 定义正在编辑的笔记对象。
+ private SharedPreferences mSharedPrefs;
+ // 定义共享偏好设置。
+ private int mFontSizeId;
+ // 定义字体大小ID。
+ private static final String PREFERENCE_FONT_SIZE = "pref_font_size";
+ // 定义字体大小偏好设置的键。
+ // ...
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ // onCreate方法,初始化Activity。
+ super.onCreate(savedInstanceState);
+ this.setContentView(R.layout.note_edit);
+ if (savedInstanceState == null && !initActivityState(getIntent())) {
+ finish();
+ return;
+ }
+ initResources();
+ }
+
+ // ...
+ // 省略部分代码以节省空间,包括onRestoreInstanceState、initActivityState等方法。
+
+ private void initNoteScreen() {
+ // 初始化笔记屏幕。
+ mNoteEditor.setTextAppearance(this, TextAppearanceResources
+ .getTexAppearanceResource(mFontSizeId));
+ // 设置文本样式。
+ // ...
+ }
+
+ // ...
+ // 省略部分代码以节省空间,包括onResume、initNoteScreen等方法。
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // 处理菜单项点击事件。
+ switch (item.getItemId()) {
+ case R.id.menu_new_note:
+ createNewNote();
+ break;
+ // ...
+ }
+ return true;
+ }
+
+ // ...
+ // 省略部分代码以节省空间,包括setReminder、sendTo等方法。
+
+ private boolean saveNote() {
+ // 保存笔记。
+ getWorkingText();
+ boolean saved = mWorkingNote.saveNote();
+ if (saved) {
+ setResult(RESULT_OK);
+ }
+ return saved;
+ }
+
+ // ...
+ // sendToDesktop、makeShortcutIconTitle等方法。
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteEditText.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteEditText.java
new file mode 100644
index 0000000..107779b
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteEditText.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.text.Layout;
+import android.text.Selection;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.style.URLSpan;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
+import android.view.MotionEvent;
+import android.widget.EditText;
+// 导入所需的Android类和接口。
+
+import net.micode.notes.R;
+// 导入应用程序的资源类。
+
+import java.util.HashMap;
+import java.util.Map;
+// 导入Java的Map类。
+
+public class NoteEditText extends EditText {
+ // 定义NoteEditText类,继承自EditText。
+
+ private static final String TAG = "NoteEditText";
+ // 定义日志标签。
+ private int mIndex;
+ // 定义索引,用于标识文本编辑框的位置。
+ private int mSelectionStartBeforeDelete;
+ // 定义删除前的选择起始位置。
+
+ // 定义协议方案常量。
+ private static final String SCHEME_TEL = "tel:" ;
+ private static final String SCHEME_HTTP = "http:" ;
+ private static final String SCHEME_EMAIL = "mailto:" ;
+
+ // 定义协议方案到资源ID的映射。
+ private static final Map sSchemaActionResMap = new HashMap();
+ static {
+ sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel);
+ sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web);
+ sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email);
+ }
+
+ // 定义文本变化监听器接口。
+ public interface OnTextViewChangeListener {
+ void onEditTextDelete(int index, String text);
+ void onEditTextEnter(int index, String text);
+ void onTextChange(int index, boolean hasText);
+ }
+
+ private OnTextViewChangeListener mOnTextViewChangeListener;
+ // 定义文本变化监听器。
+
+ public NoteEditText(Context context) {
+ super(context, null);
+ mIndex = 0;
+ }
+ // 构造函数,初始化索引。
+
+ public void setIndex(int index) {
+ mIndex = index;
+ }
+ // 设置索引。
+
+ public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
+ mOnTextViewChangeListener = listener;
+ }
+ // 设置文本变化监听器。
+
+ // 省略其他构造函数...
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ // 处理触摸事件,设置光标位置。
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ // ...
+ break;
+ }
+ return super.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ // 处理按键按下事件,记录删除前的选择起始位置。
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_ENTER:
+ // ...
+ break;
+ case KeyEvent.KEYCODE_DEL:
+ mSelectionStartBeforeDelete = getSelectionStart();
+ break;
+ }
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ // 处理按键抬起事件,执行删除或添加文本操作。
+ switch(keyCode) {
+ case KeyEvent.KEYCODE_DEL:
+ // ...
+ break;
+ case KeyEvent.KEYCODE_ENTER:
+ // ...
+ break;
+ }
+ return super.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+ // 处理焦点变化事件,通知文本变化监听器。
+ if (mOnTextViewChangeListener != null) {
+ // ...
+ }
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+ }
+
+ @Override
+ protected void onCreateContextMenu(ContextMenu menu) {
+ // 创建上下文菜单,处理超链接点击事件。
+ if (getText() instanceof Spanned) {
+ // ...
+ }
+ super.onCreateContextMenu(menu);
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteItemData.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteItemData.java
new file mode 100644
index 0000000..eebbfca
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NoteItemData.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.Context;
+import android.database.Cursor;
+import android.text.TextUtils;
+
+import net.micode.notes.data.Contact;
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.tool.DataUtils;
+// 导入所需的Android类和应用程序特定的类。
+
+public class NoteItemData {
+ // 定义NoteItemData类,用于封装笔记项数据。
+
+ // 定义查询数据库时需要的列。
+ static final String [] PROJECTION = new String [] {
+ NoteColumns.ID,
+ NoteColumns.ALERTED_DATE,
+ // ...
+ };
+
+ // 定义列索引常量。
+ private static final int ID_COLUMN = 0;
+ private static final int ALERTED_DATE_COLUMN = 1;
+ // ...
+
+ // 定义成员变量,用于存储笔记项的数据。
+ private long mId;
+ private long mAlertDate;
+ private int mBgColorId;
+ // ...
+
+ // 定义成员变量,用于存储笔记项的位置信息。
+ private boolean mIsLastItem;
+ private boolean mIsFirstItem;
+ // ...
+
+ // 构造函数,从Cursor中初始化笔记项数据。
+ public NoteItemData(Context context, Cursor cursor) {
+ // 从Cursor中获取数据并赋值给成员变量。
+ mId = cursor.getLong(ID_COLUMN);
+ mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN);
+ // ...
+ checkPostion(cursor);
+ }
+
+ // 检查笔记项的位置,并设置相应的标志。
+ private void checkPostion(Cursor cursor) {
+ // 实现检查笔记项位置的逻辑。
+ mIsLastItem = cursor.isLast() ? true : false;
+ mIsFirstItem = cursor.isFirst() ? true : false;
+ // ...
+ }
+
+ // 定义一系列getter方法,用于获取笔记项的数据。
+ public boolean isOneFollowingFolder() {
+ return mIsOneNoteFollowingFolder;
+ }
+ // ...
+
+ public long getId() {
+ return mId;
+ }
+ // ...
+
+ // 定义一个静态方法,用于从Cursor中获取笔记类型。
+ public static int getNoteType(Cursor cursor) {
+ return cursor.getInt(TYPE_COLUMN);
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
new file mode 100644
index 0000000..50440e7
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+// 导入所需的Android类和接口。
+import android.app.Activity;
+// ...
+
+public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
+ // 定义NotesListActivity类,继承自Activity并实现OnClickListener和OnItemLongClickListener接口。
+
+ private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
+ // 定义查询令牌常量。
+ private static final int FOLDER_LIST_QUERY_TOKEN = 1;
+ // ...
+
+ private ListEditState mState;
+ // 定义当前列表编辑状态。
+ private BackgroundQueryHandler mBackgroundQueryHandler;
+ // 定义后台查询处理器。
+ private NotesListAdapter mNotesListAdapter;
+ // 定义笔记列表适配器。
+ private ListView mNotesListView;
+ // 定义笔记列表视图。
+ private Button mAddNewNote;
+ // 定义添加新笔记按钮。
+ private boolean mDispatch;
+ // 定义分发标志。
+ private int mOriginY;
+ // 定义原始Y坐标。
+ private int mDispatchY;
+ // 定义分发Y坐标。
+ private TextView mTitleBar;
+ // 定义标题栏。
+ private long mCurrentFolderId;
+ // 定义当前文件夹ID。
+ private ContentResolver mContentResolver;
+ // 定义内容解析器。
+ private ModeCallback mModeCallBack;
+ // 定义模式回调。
+ private static final String TAG = "NotesListActivity";
+ // 定义日志标签。
+
+ // 省略其他成员变量...
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.note_list);
+ initResources();
+ // 在创建时初始化资源。
+ }
+
+ // 省略其他方法...
+
+ private void initResources() {
+ mContentResolver = this.getContentResolver();
+ mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver());
+ // 初始化后台查询处理器。
+ mCurrentFolderId = Notes.ID_ROOT_FOLDER;
+ mNotesListView = (ListView) findViewById(R.id.notes_list);
+ // 初始化笔记列表视图。
+ mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null), null, false);
+ mNotesListView.setOnItemClickListener(new OnListItemClickListener());
+ // 设置列表项点击事件监听器。
+ mNotesListView.setOnItemLongClickListener(this);
+ // 设置列表项长按事件监听器。
+ mNotesListAdapter = new NotesListAdapter(this);
+ mNotesListView.setAdapter(mNotesListAdapter);
+ // 设置笔记列表适配器。
+ mAddNewNote = (Button) findViewById(R.id.btn_new_note);
+ mAddNewNote.setOnClickListener(this);
+ // 设置添加新笔记按钮点击事件监听器。
+ mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());
+ // 设置添加新笔记按钮触摸事件监听器。
+ mDispatch = false;
+ mDispatchY = 0;
+ mOriginY = 0;
+ mTitleBar = (TextView) findViewById(R.id.tv_title_bar);
+ mState = ListEditState.NOTE_LIST;
+ mModeCallBack = new ModeCallback();
+ }
+
+ // 省略其他方法...
+
+ public void onClick(View v) {
+ // 处理点击事件。
+ switch (v.getId()) {
+ case R.id.btn_new_note:
+ createNewNote();
+ break;
+ // 当点击添加新笔记按钮时,创建新笔记。
+ default:
+ break;
+ }
+ }
+
+ // 省略其他方法...
+
+ private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener {
+ // 定义模式回调类,实现多选模式监听器和菜单项点击事件监听器接口。
+ // 省略ModeCallback类实现...
+ }
+
+ private class NewNoteOnTouchListener implements OnTouchListener {
+ // 定义新笔记触摸事件监听器类。
+ public boolean onTouch(View v, MotionEvent event) {
+ // 处理触摸事件。
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ // 当按下时,分发事件到列表视图。
+ // 省略实现...
+ case MotionEvent.ACTION_MOVE:
+ // 当移动时,分发事件到列表视图。
+ // 省略实现...
+ default:
+ // 默认情况,分发事件到列表视图。
+ // 省略实现...
+ }
+ return false;
+ }
+ }
+
+ //
+
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java
new file mode 100644
index 0000000..509ba5f
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.Context;
+import android.database.Cursor;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CursorAdapter;
+// 导入所需的Android类和接口。
+
+import net.micode.notes.data.Notes;
+// 导入应用程序的数据模型类。
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+// 导入Java的集合类。
+
+public class NotesListAdapter extends CursorAdapter {
+ // 定义NotesListAdapter类,继承自CursorAdapter。
+
+ private static final String TAG = "NotesListAdapter";
+ // 定义日志标签。
+ private Context mContext;
+ // 定义上下文引用。
+ private HashMap mSelectedIndex;
+ // 定义选中状态的哈希映射。
+ private int mNotesCount;
+ // 定义笔记计数。
+ private boolean mChoiceMode;
+ // 定义选择模式标志。
+
+ public static class AppWidgetAttribute {
+ // 定义内部类,用于存储应用小部件属性。
+ public int widgetId;
+ public int widgetType;
+ };
+
+ public NotesListAdapter(Context context) {
+ // 构造函数,初始化适配器。
+ super(context, null);
+ mSelectedIndex = new HashMap();
+ mContext = context;
+ mNotesCount = 0;
+ }
+
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ // 创建新的列表项视图。
+ return new NotesListItem(context);
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ // 将数据绑定到视图上。
+ if (view instanceof NotesListItem) {
+ NoteItemData itemData = new NoteItemData(context, cursor);
+ ((NotesListItem) view).bind(context, itemData, mChoiceMode, isSelectedItem(cursor.getPosition()));
+ }
+ }
+
+ public void setCheckedItem(final int position, final boolean checked) {
+ // 设置列表项的选中状态。
+ mSelectedIndex.put(position, checked);
+ notifyDataSetChanged();
+ }
+
+ public boolean isInChoiceMode() {
+ // 获取选择模式状态。
+ return mChoiceMode;
+ }
+
+ public void setChoiceMode(boolean mode) {
+ // 设置选择模式。
+ mSelectedIndex.clear();
+ mChoiceMode = mode;
+ }
+
+ public void selectAll(boolean checked) {
+ // 全选或全不选所有列表项。
+ Cursor cursor = getCursor();
+ for (int i = 0; i < getCount(); i++) {
+ if (cursor.moveToPosition(i)) {
+ if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) {
+ setCheckedItem(i, checked);
+ }
+ }
+ }
+ }
+
+ public HashSet getSelectedItemIds() {
+ // 获取选中的笔记ID集合。
+ HashSet itemSet = new HashSet();
+ for (Integer position : mSelectedIndex.keySet()) {
+ if (mSelectedIndex.get(position) == true) {
+ Long id = getItemId(position);
+ if (id == Notes.ID_ROOT_FOLDER) {
+ Log.d(TAG, "Wrong item id, should not happen");
+ } else {
+ itemSet.add(id);
+ }
+ }
+ }
+ return itemSet;
+ }
+
+ public HashSet getSelectedWidget() {
+ // 获取选中的应用小部件属性集合。
+ HashSet itemSet = new HashSet();
+ for (Integer position : mSelectedIndex.keySet()) {
+ if (mSelectedIndex.get(position) == true) {
+ Cursor c = (Cursor) getItem(position);
+ if (c != null) {
+ AppWidgetAttribute widget = new AppWidgetAttribute();
+ NoteItemData item = new NoteItemData(mContext, c);
+ widget.widgetId = item.getWidgetId();
+ widget.widgetType = item.getWidgetType();
+ itemSet.add(widget);
+ } else {
+ Log.e(TAG, "Invalid cursor");
+ return null;
+ }
+ }
+ }
+ return itemSet;
+ }
+
+ public int getSelectedCount() {
+ // 获取选中的笔记数量。
+ Collection values = mSelectedIndex.values();
+ if (null == values) {
+ return 0;
+ }
+ Iterator iter = values.iterator();
+ int count = 0;
+ while (iter.hasNext()) {
+ if (true == iter.next()) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ public boolean isAllSelected() {
+ // 检查是否所有笔记都被选中。
+ int checkedCount = getSelectedCount();
+ return (checkedCount != 0 && checkedCount == mNotesCount);
+ }
+
+ public boolean isSelectedItem(final int position) {
+ // 检查指定位置的笔记是否被选中。
+ if (null == mSelectedIndex.get(position)) {
+ return false;
+ }
+ return mSelectedIndex.get(position);
+ }
+
+ @Override
+ protected void onContentChanged() {
+ // 当内容变化时调用。
+ super.onContentChanged();
+ calcNotesCount();
+ }
+
+ @Override
+ public void changeCursor(Cursor cursor) {
+ // 当游标变化时调用。
+ super.changeCursor(cursor);
+ calcNotesCount();
+ }
+
+ private void calcNotesCount() {
+ // 计算笔记数量。
+ mNotesCount = 0;
+ for (int i = 0; i < getCount(); i++) {
+ Cursor c = (Cursor) getItem(i);
+ if (c != null) {
+ if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) {
+ mNotesCount++;
+ }
+ } else {
+ Log.e(TAG, "Invalid cursor");
+ return;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListItem.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListItem.java
new file mode 100644
index 0000000..ad33a79
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesListItem.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.content.Context;
+import android.text.format.DateUtils;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+// 导入所需的Android类和接口。
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.tool.DataUtils;
+import net.micode.notes.tool.ResourceParser.NoteItemBgResources;
+// 导入应用程序的资源类和工具类。
+
+public class NotesListItem extends LinearLayout {
+ // 定义NotesListItem类,继承自LinearLayout。
+
+ private ImageView mAlert;
+ private TextView mTitle;
+ private TextView mTime;
+ private TextView mCallName;
+ private NoteItemData mItemData;
+ private CheckBox mCheckBox;
+ // 定义视图元素和数据模型。
+
+ public NotesListItem(Context context) {
+ super(context);
+ inflate(context, R.layout.note_item, this);
+ // inflate笔记项布局。
+ mAlert = (ImageView) findViewById(R.id.iv_alert_icon);
+ mTitle = (TextView) findViewById(R.id.tv_title);
+ mTime = (TextView) findViewById(R.id.tv_time);
+ mCallName = (TextView) findViewById(R.id.tv_name);
+ mCheckBox = (CheckBox) findViewById(android.R.id.checkbox);
+ // 初始化视图元素。
+ }
+
+ public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) {
+ // 绑定数据到视图。
+ if (choiceMode && data.getType() == Notes.TYPE_NOTE) {
+ mCheckBox.setVisibility(View.VISIBLE);
+ mCheckBox.setChecked(checked);
+ } else {
+ mCheckBox.setVisibility(View.GONE);
+ }
+
+ mItemData = data;
+ // 设置数据模型。
+ // 根据数据模型的类型和属性设置视图元素的显示。
+ // 省略部分代码...
+
+ mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
+ // 设置修改时间。
+ setBackground(data);
+ // 设置背景。
+ }
+
+ private void setBackground(NoteItemData data) {
+ // 设置背景资源。
+ int id = data.getBgColorId();
+ // 省略部分代码...
+ }
+
+ public NoteItemData getItemData() {
+ return mItemData;
+ }
+ // 获取数据模型。
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java
new file mode 100644
index 0000000..1972995
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// 版权声明,说明该代码由MiCode开源社区持有,并在Apache License 2.0下授权。
+
+package net.micode.notes.ui;
+// 声明代码所属的包路径。
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+// ...
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.gtask.remote.GTaskSyncService;
+// 导入应用程序的资源类、数据模型类和同步服务类。
+
+public class NotesPreferenceActivity extends PreferenceActivity {
+ // 定义NotesPreferenceActivity类,继承自PreferenceActivity。
+
+ // 定义偏好设置的键和名称。
+ public static final String PREFERENCE_NAME = "notes_preferences";
+ // ...
+
+ private PreferenceCategory mAccountCategory;
+ private GTaskReceiver mReceiver;
+ private Account[] mOriAccounts;
+ private boolean mHasAddedAccount;
+ // 定义账户类别、接收器、原始账户数组和账户添加标志。
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ // 调用父类的onCreate方法。
+
+ // 设置ActionBar的返回图标。
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ // 从资源文件中添加偏好设置。
+ addPreferencesFromResource(R.xml.preferences);
+ mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);
+ // 初始化账户类别。
+ mReceiver = new GTaskReceiver();
+ // 创建GTask接收器。
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME);
+ registerReceiver(mReceiver, filter);
+ // 注册接收器以监听GTask服务的广播。
+
+ mOriAccounts = null;
+ // 初始化原始账户数组。
+ View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null);
+ getListView().addHeaderView(header, null, true);
+ // 添加设置头部视图。
+ }
+
+ // ...
+ // 省略部分代码以节省空间,包括onResume、onDestroy等方法。
+
+ private void loadAccountPreference() {
+ // 加载账户偏好设置。
+ mAccountCategory.removeAll();
+ // 移除所有账户偏好项。
+
+ Preference accountPref = new Preference(this);
+ // 创建账户偏好项。
+ final String defaultAccount = getSyncAccountName(this);
+ // 获取默认同步账户名。
+ accountPref.setTitle(getString(R.string.preferences_account_title));
+ accountPref.setSummary(getString(R.string.preferences_account_summary));
+ accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ // 处理账户偏好项的点击事件。
+ // ...
+ return true;
+ }
+ });
+ mAccountCategory.addPreference(accountPref);
+ // 将账户偏好项添加到账户类别中。
+ }
+
+ private void loadSyncButton() {
+ // 加载同步按钮。
+ Button syncButton = (Button) findViewById(R.id.preference_sync_button);
+ TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview);
+ // 获取同步按钮和最后同步时间视图。
+
+ // 设置按钮状态和最后同步时间。
+ // ...
+ }
+
+ private void refreshUI() {
+ // 刷新用户界面。
+ loadAccountPreference();
+ loadSyncButton();
+ }
+
+ // ...
+ // 省略部分代码以节省空间,包括showSelectAccountAlertDialog、showChangeAccountConfirmAlertDialog等方法。
+
+ private Account[] getGoogleAccounts() {
+ // 获取Google账户。
+ AccountManager accountManager = AccountManager.get(this);
+ return accountManager.getAccountsByType("com.google");
+ }
+
+ private void setSyncAccount(String account) {
+ // 设置同步账户。
+ SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = settings.edit();
+ // ...
+ }
+
+ private void removeSyncAccount() {
+ // 移除同步账户。
+ SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = settings.edit();
+ // ...
+ }
+
+ public static String getSyncAccountName(Context context) {
+ // 获取同步账户名。
+ SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
+ Context.MODE_PRIVATE);
+ return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
+ }
+
+ public static void setLastSyncTime(Context context, long time) {
+ // 设置最后同步时间。
+ SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = settings.edit();
+ editor.putLong(PREFERENCE_LAST_SYNC_TIME, time);
+ editor.commit();
+ }
+
+ public static long getLastSyncTime(Context context) {
+ // 获取最后同步时间。
+ SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
+ Context.MODE_PRIVATE);
+ return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0);
+ }
+
+ private class GTaskReceiver extends BroadcastReceiver {
+ // 定义GTask接收器类,用于接收GTask服务的广播。
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ refreshUI();
+ // 刷新用户界面。
+ // ...
+ }
+ }
+
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // 处理选项菜单项的点击事件。
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ // 当点击返回图标时,返回到笔记列表活动。
+ Intent intent = new Intent(this, NotesListActivity.class);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(intent);
+ return true;
+ default:
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider.java
new file mode 100644
index 0000000..ec6f819
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.widget;
+import android.app.PendingIntent;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.tool.ResourceParser;
+import net.micode.notes.ui.NoteEditActivity;
+import net.micode.notes.ui.NotesListActivity;
+
+public abstract class NoteWidgetProvider extends AppWidgetProvider {
+ public static final String [] PROJECTION = new String [] {
+ NoteColumns.ID,
+ NoteColumns.BG_COLOR_ID,
+ NoteColumns.SNIPPET
+ };
+
+ public static final int COLUMN_ID = 0;
+ public static final int COLUMN_BG_COLOR_ID = 1;
+ public static final int COLUMN_SNIPPET = 2;
+
+ private static final String TAG = "NoteWidgetProvider";
+
+ @Override
+ public void onDeleted(Context context, int[] appWidgetIds) {
+ ContentValues values = new ContentValues();
+ values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
+ for (int i = 0; i < appWidgetIds.length; i++) {
+ context.getContentResolver().update(Notes.CONTENT_NOTE_URI,
+ values,
+ NoteColumns.WIDGET_ID + "=?",
+ new String[] { String.valueOf(appWidgetIds[i])});
+ }
+ }
+
+ private Cursor getNoteWidgetInfo(Context context, int widgetId) {
+ return context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
+ PROJECTION,
+ NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?",
+ new String[] { String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER) },
+ null);
+ }
+
+ protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+ update(context, appWidgetManager, appWidgetIds, false);
+ }
+
+ private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds,
+ boolean privacyMode) {
+ for (int i = 0; i < appWidgetIds.length; i++) {
+ if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) {
+ int bgId = ResourceParser.getDefaultBgId(context);
+ String snippet = "";
+ Intent intent = new Intent(context, NoteEditActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]);
+ intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType());
+
+ Cursor c = getNoteWidgetInfo(context, appWidgetIds[i]);
+ if (c != null && c.moveToFirst()) {
+ if (c.getCount() > 1) {
+ Log.e(TAG, "Multiple message with same widget id:" + appWidgetIds[i]);
+ c.close();
+ return;
+ }
+ snippet = c.getString(COLUMN_SNIPPET);
+ bgId = c.getInt(COLUMN_BG_COLOR_ID);
+ intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID));
+ intent.setAction(Intent.ACTION_VIEW);
+ } else {
+ snippet = context.getResources().getString(R.string.widget_havenot_content);
+ intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
+ }
+
+ if (c != null) {
+ c.close();
+ }
+
+ RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId());
+ rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId));
+ intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
+ /**
+ * Generate the pending intent to start host for the widget
+ */
+ PendingIntent pendingIntent = null;
+ if (privacyMode) {
+ rv.setTextViewText(R.id.widget_text,
+ context.getString(R.string.widget_under_visit_mode));
+ pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], new Intent(
+ context, NotesListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
+ } else {
+ rv.setTextViewText(R.id.widget_text, snippet);
+ pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent);
+ appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
+ }
+ }
+ }
+
+ protected abstract int getBgResourceId(int bgId);
+
+ protected abstract int getLayoutId();
+
+ protected abstract int getWidgetType();
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider_2x.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider_2x.java
new file mode 100644
index 0000000..adcb2f7
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider_2x.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.widget;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.tool.ResourceParser;
+
+
+public class NoteWidgetProvider_2x extends NoteWidgetProvider {
+ @Override
+ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+ super.update(context, appWidgetManager, appWidgetIds);
+ }
+
+ @Override
+ protected int getLayoutId() {
+ return R.layout.widget_2x;
+ }
+
+ @Override
+ protected int getBgResourceId(int bgId) {
+ return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId);
+ }
+
+ @Override
+ protected int getWidgetType() {
+ return Notes.TYPE_WIDGET_2X;
+ }
+}
diff --git a/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider_4x.java b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider_4x.java
new file mode 100644
index 0000000..c12a02e
--- /dev/null
+++ b/源程序代码-小米便签-Notes-master/Notes-master/src/net/micode/notes/widget/NoteWidgetProvider_4x.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.widget;
+
+import android.appwidget.AppWidgetManager;
+import android.content.Context;
+
+import net.micode.notes.R;
+import net.micode.notes.data.Notes;
+import net.micode.notes.tool.ResourceParser;
+
+
+public class NoteWidgetProvider_4x extends NoteWidgetProvider {
+ @Override
+ public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+ super.update(context, appWidgetManager, appWidgetIds);
+ }
+
+ protected int getLayoutId() {
+ return R.layout.widget_4x;
+ }
+
+ @Override
+ protected int getBgResourceId(int bgId) {
+ return ResourceParser.WidgetBgResources.getWidget4xBgResource(bgId);
+ }
+
+ @Override
+ protected int getWidgetType() {
+ return Notes.TYPE_WIDGET_4X;
+ }
+}