diff --git a/doc/~$便签泛读、标注和维护报告文档.docx b/doc/~$便签泛读、标注和维护报告文档.docx new file mode 100644 index 0000000..7306b70 Binary files /dev/null and b/doc/~$便签泛读、标注和维护报告文档.docx differ diff --git a/doc/~$便签质量分析报告.docx b/doc/~$便签质量分析报告.docx new file mode 100644 index 0000000..7115a73 Binary files /dev/null and b/doc/~$便签质量分析报告.docx differ diff --git a/doc/~WRL2503.tmp b/doc/~WRL2503.tmp new file mode 100644 index 0000000..2e90554 Binary files /dev/null and b/doc/~WRL2503.tmp differ diff --git a/doc/小米便签的代码标注.docx b/doc/小米便签的代码标注.docx deleted file mode 100644 index 9b86114..0000000 Binary files a/doc/小米便签的代码标注.docx and /dev/null differ diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index f8ccd9c..ba4f386 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -1,21 +1,4 @@ - - - - - - android:label="@string/app_name" - android:launchMode="singleTop" - android:theme="@style/NoteTheme" - android:windowSoftInputMode="adjustPan" > - - android:label="@string/app_name" > - + - - - diff --git a/src/main/java/net/micode/notes/data/Contact.java b/src/main/java/net/micode/notes/data/Contact.java index d65c239..95d8bce 100644 --- a/src/main/java/net/micode/notes/data/Contact.java +++ b/src/main/java/net/micode/notes/data/Contact.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package net.micode.notes.data;//属于data这个包 +package net.micode.notes.data; import android.content.Context; import android.database.Cursor; @@ -25,64 +25,63 @@ import android.util.Log; import java.util.HashMap; /** - * @Package: net.micode.notes.data - * @ClassName: Contact - * @Description: - * Contact类用于查询联系人信息并进行缓存。 - * 该类包含一个静态的HashMap作为缓存,存储电话号码和对应的联系人名字。 - * 通过调用getContact方法可以根据给定的电话号码查询联系人名字。 - * 如果缓存中已经存在该电话号码对应的联系人名字,则直接返回缓存中的结果,否则通过查询数据库获取联系人名字并更新缓存。 - * 该类还定义了一个私有的SQL筛选语句用于查询联系人信息。 - * 注意:该类是线程不安全的,如果需要在多线程环境下使用,请做好同步控制 - * @Author: YangYizhe - * @CreateDate: 12/17/2023 10:10 AM - * @Version: 1.0 + * @Package: net.micode.notes.data + * @ClassName: Contact + * @Description: + * @Author: WUSHUXIAN + * @CreateDate: 2023/12/20 23:26 + * @Version: 1.0 */ public class Contact { - /** - * 作为缓存,存储电话号码和对应的联系人名字 - */ private static HashMap sContactCache; - private static final String TAG = "Contact";//设置日志TAG标签 + private static final String TAG = "Contact"; - //查询联系人的SQL筛选语句 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 = '+')"; - //获取联系人 + /** + * @method getContact + * @description: + * @date: 2023/12/21 19:18 + * @author: WuShuxian + * @param: context + * @param: phoneNumber + * @return: String + */ public static String getContact(Context context, String phoneNumber) { - if(sContactCache == null) {/*如果缓存为空,就新建一个*/ + // + if(sContactCache == null) { sContactCache = new HashMap(); } - if(sContactCache.containsKey(phoneNumber)) {/*如果缓存中已经有该电话号码对应的联系人名字,就直接返回*/ + if(sContactCache.containsKey(phoneNumber)) { return sContactCache.get(phoneNumber); } String selection = CALLER_ID_SELECTION.replace("+", - PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));//将电话号码转换为最小匹配模式,用于筛选 + PhoneNumberUtils.toCallerIDMinMatch(phoneNumber)); Cursor cursor = context.getContentResolver().query( Data.CONTENT_URI, new String [] { Phone.DISPLAY_NAME }, - selection,//使用筛选条件 + selection, new String[] { phoneNumber }, null); - if (cursor != null && cursor.moveToFirst()) {//如果找到了符合条件的联系人 + if (cursor != null && cursor.moveToFirst()) { try { - String name = cursor.getString(0);//获取联系人名字 - sContactCache.put(phoneNumber, name);//将电话号码和联系人名字添加到缓存中 - return name;//返回联系人名字 + 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();//关闭游标 + cursor.close(); } - } else {/*没找到*/ + } else { Log.d(TAG, "No contact matched with number:" + phoneNumber); return null; } diff --git a/src/main/java/net/micode/notes/ui/NoteItemData.java b/src/main/java/net/micode/notes/ui/NoteItemData.java index 832cbe9..ca9bcbe 100644 --- a/src/main/java/net/micode/notes/ui/NoteItemData.java +++ b/src/main/java/net/micode/notes/ui/NoteItemData.java @@ -34,6 +34,7 @@ import net.micode.notes.tool.DataUtils; * @Version: 1.0 */ public class NoteItemData { + // 用于定义查询操作中要返回的列 static final String [] PROJECTION = new String [] { NoteColumns.ID, NoteColumns.ALERTED_DATE, diff --git a/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/main/java/net/micode/notes/ui/NotesListActivity.java index 2b0e901..5eea908 100644 --- a/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -85,6 +85,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; + /**三个状态,主页面,文件夹,通话记录文件夹*/ private enum ListEditState { NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER }; @@ -100,6 +101,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private Button mAddNewNote; private boolean mDispatch; + // 控制背景颜色,初始为亮 + private int mBackgroundColor = 1; private int mOriginY; @@ -117,6 +120,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; + /** 私密模式,初始为 0 开启为 1*/ + public static int mSecretMode = 0; + private NoteItemData mFocusNoteDataItem; private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; @@ -140,6 +146,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 调用父类的onCreate函数 setContentView(R.layout.note_list); + getWindow().setBackgroundDrawableResource(R.drawable.bg_light); initResources(); setAppInfoFromRawRes(); } @@ -463,10 +470,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt * @return */ private void startAsyncNotesListQuery() { - String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION : NORMAL_SELECTION; + String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION + : NORMAL_SELECTION; mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null, - Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {String.valueOf(mCurrentFolderId)}, - NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); + Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[]{ + String.valueOf(mCurrentFolderId) + }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); } /** * @Package: net.micode.notes.ui @@ -530,6 +539,98 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }); builder.show(); } + + /** + * @method switchBackground + * @description 用以切换背景颜色 + * @date: 1/3/2024 3:41 PM + * @author: YangYizhe + */ + private void switchBackground(){ + mBackgroundColor = (mBackgroundColor + 1) % 2; + View frameLayout = findViewById(R.id.frame_layout_id); + if (mBackgroundColor == 1){ + frameLayout.setBackgroundResource(R.drawable.bg_light); + } else{ + frameLayout.setBackgroundResource(R.drawable.bg_dark); + } + + } + + private boolean isSecretMode(){ + if(mSecretMode == 1){ + return true; + }else { + return false; + } + } + + /** + * @method enterSecertMode + * @description 实现进入隐私模式的功能 + * @date: 1/2/2024 8:18 PM + * @author: YangYizhe + */ + private void enterSecretMode(){ + AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this); + dialog.setTitle("重要提醒"); + dialog.setMessage("您确认进入隐私模式吗?"); + dialog.setCancelable(false); + dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mSecretMode = 1; + startAsyncNotesListQuery(); + Toast.makeText(NotesListActivity.this,"您已进入隐私模式",Toast.LENGTH_SHORT).show(); + } + }); + dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which){} + }); + dialog.show(); + } + + /** + * @method quitSecretMode + * @description 实现退出隐私模式的功能 + * @date: 1/2/2024 8:20 PM + * @author: YangYizhe + */ + private void quitSecretMode(){ + AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this); + dialog.setTitle("重要提醒"); + dialog.setMessage("您确认退出隐私模式吗?"); + dialog.setCancelable(false); + dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mSecretMode = 0; + startAsyncNotesListQuery(); + Toast.makeText(NotesListActivity.this,"您已退出隐私模式",Toast.LENGTH_SHORT).show(); + } + }); + dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which){} + }); + dialog.show(); + } + + /** + * @method restoreDeletedNodes + * @description 进入回收站 + * @date: 1/3/2024 8:11 PM + * @author: YangYizhe + */ + private void restoreDeletedNodes(){ + mState = ListEditState.SUB_FOLDER; + mCurrentFolderId = Notes.ID_TRASH_FOLER; + startAsyncNotesListQuery(); + mTitleBar.setText("回收站"); + mTitleBar.setVisibility(View.VISIBLE); + } + /** * @method createNewNote * @description 创建便签 @@ -544,6 +645,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId); this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); } + /** * @method batchDelete * @description: @@ -558,15 +660,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt new AsyncTask>() { protected HashSet doInBackground(Void... unused) { HashSet widgets = mNotesListAdapter.getSelectedWidget(); - //如果没有同步,直接删除 - if (!isSyncMode()) { + // 如果是回收站中的,直接删除 + if (mCurrentFolderId == Notes.ID_TRASH_FOLER) { if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter .getSelectedItemIds())) { } else { Log.e(TAG, "Delete notes error, should not happens"); } } - //已同步,将删除的便签移到垃圾桶 + // 将删除的便签移到回收站 else { if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { @@ -891,6 +993,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } @Override + /** + * @method onPrepareOptionsMenu + * @description 准备菜单选项的回调方法,menu是Android自带的对象 + * @date: 1/2/2024 7:40 PM + * @author: YangYizhe + * @param [menu] 菜单对象 + * @return boolean 返回值指示是否处理了菜单创建事件 + */ public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); if (mState == ListEditState.NOTE_LIST) { @@ -905,10 +1015,29 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } else { Log.e(TAG, "Wrong state:" + mState); } + // 若在隐私模式之中,则不显示进入隐私模式的选项,不在隐私模式之中,则不显示退出隐私模式选项 + if(isSecretMode()){ + menu.findItem(R.id.menu_secret).setVisible(false); + } else { + menu.findItem(R.id.menu_quit_secret).setVisible(false); + } + if(mBackgroundColor==1) { + menu.findItem(R.id.menu_light_mode).setVisible(false); + } else { + menu.findItem(R.id.menu_dark_mode).setVisible(false); + } return true; } @Override + /** + * @method onOptionsItemSelected + * @description 处理菜单选项的选择事件。根据被选择的菜单项不同,该方法会触发不同的操作。 + * @date: 1/2/2024 7:41 PM + * @author: YangYizhe + * @param [item] 被选择的菜单项 + * @return boolean 返回值指示是否处理了菜单选择事件 + */ public boolean onOptionsItemSelected(MenuItem item) { int itemId = item.getItemId(); if (itemId == R.id.menu_new_folder) { @@ -931,6 +1060,16 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt createNewNote(); } else if (itemId == R.id.menu_search) { onSearchRequested(); + } else if (itemId == R.id.menu_secret) { + enterSecretMode(); + } else if (itemId == R.id.menu_quit_secret){ + quitSecretMode(); + } else if(itemId == R.id.menu_light_mode) { + switchBackground(); + } else if(itemId == R.id.menu_dark_mode) { + switchBackground(); + } else if (itemId == R.id.menu_restore) { + restoreDeletedNodes(); } return true; } diff --git a/src/main/java/net/micode/notes/ui/NotesListItem.java b/src/main/java/net/micode/notes/ui/NotesListItem.java index d32a37b..5cf4b20 100644 --- a/src/main/java/net/micode/notes/ui/NotesListItem.java +++ b/src/main/java/net/micode/notes/ui/NotesListItem.java @@ -26,7 +26,7 @@ public class NotesListItem extends LinearLayout { private ImageView mAlert;//闹钟图片 private TextView mTitle; //标题 private TextView mTime; //时间 - private TextView mCallName; // + private TextView mCallName; private NoteItemData mItemData; //标签数据 private CheckBox mCheckBox; //打钩框 diff --git a/src/main/res/layout/note_edit.xml b/src/main/res/layout/note_edit.xml index 4f0126b..9aa4ad9 100644 --- a/src/main/res/layout/note_edit.xml +++ b/src/main/res/layout/note_edit.xml @@ -99,13 +99,13 @@ android:id="@+id/note_edit_view" android:layout_width="fill_parent" android:layout_height="wrap_content" - android:gravity="left|top" - android:background="@null" android:autoLink="all" + android:background="@null" + android:gravity="left|top" + android:lineSpacingMultiplier="1.2" android:linksClickable="false" android:minLines="12" - android:textAppearance="@style/TextAppearancePrimaryItem" - android:lineSpacingMultiplier="1.2" /> + android:textAppearance="@style/TextAppearancePrimaryItem" /> + android:background="@drawable/bg_light"> + + + + + + + + + + diff --git a/src/main/res/menu/sub_folder.xml b/src/main/res/menu/sub_folder.xml index b00de26..d81e568 100644 --- a/src/main/res/menu/sub_folder.xml +++ b/src/main/res/menu/sub_folder.xml @@ -21,4 +21,20 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 09f75ed..dacfe89 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -119,6 +119,14 @@ 便签 设置 取消 + 亮背景 + 暗背景 + 私密模式 + 退出私密模式 + 字符数 + 恢复 + 欢迎页面 + EAZZY\nNOTE %1$s 条符合“%2$s”的搜索结果 diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml index e29b79b..1bfa120 100644 --- a/src/main/res/values-zh-rTW/strings.xml +++ b/src/main/res/values-zh-rTW/strings.xml @@ -120,6 +120,14 @@ 便籤 設置 取消 + 亮背景 + 暗背景 + 私密模式 + 退出私密模式 + 字符数 + 恢复 + 欢迎页面 + EAZZY\nNOTE %1$s 條符合”%2$s“的搜尋結果 diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index 123ffbf..2496c0c 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -17,4 +17,9 @@ #335b5b5b + #FF039BE5 + #FF01579B + #FF40C4FF + #FF00B0FF + #66000000 diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 55df868..469b04c 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -15,8 +15,7 @@ limitations under the License. --> - + Notes Notes 2x2 Notes 4x4 @@ -126,10 +125,24 @@ Notes set cancel + + light mode + dark mode + + secret mode + quit secret mode + + length + restore + + SplashActivity + EAZZY\nNOTE + - %1$s result for \"%2$s\" + %1$s result for \"%2$s\" - %1$s results for \"%2$s\" + %1$s results for \"%2$s\" + diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index ad0d90d..db56d26 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -16,18 +16,22 @@ --> + + + + @@ -66,4 +70,13 @@ visible + + + + \ No newline at end of file