From 8f340506b7db82f06c2e85440e325cf63f2ce2fd Mon Sep 17 00:00:00 2001 From: mrh <3201397106@qq.com> Date: Thu, 26 Dec 2024 16:28:36 +0800 Subject: [PATCH] 1.0 --- src/net/micode/notes/model/Note.java | 334 ++++++++++---- src/net/micode/notes/model/WorkingNote.java | 412 ++++++------------ src/net/micode/notes/tool/BackupUtils.java | 281 ++++++------ src/net/micode/notes/tool/DataUtils.java | 178 ++++---- .../micode/notes/tool/GTaskStringUtils.java | 52 ++- src/net/micode/notes/tool/ResourceParser.java | 201 ++++++--- .../notes/widget/NoteWidgetProvider.java | 83 +++- .../notes/widget/NoteWidgetProvider_2x.java | 27 ++ .../notes/widget/NoteWidgetProvider_4x.java | 28 ++ 9 files changed, 917 insertions(+), 679 deletions(-) diff --git a/src/net/micode/notes/model/Note.java b/src/net/micode/notes/model/Note.java index 6706cf6..cc8a649 100644 --- a/src/net/micode/notes/model/Note.java +++ b/src/net/micode/notes/model/Note.java @@ -34,15 +34,24 @@ import net.micode.notes.data.Notes.TextNote; import java.util.ArrayList; + + + public class Note { private ContentValues mNoteDiffValues; private NoteData mNoteData; private static final String TAG = "Note"; + #selectedCode:C:\Users\Lenovo\Desktop\xiaomi\src\net\micode\notes\model\Note.java#L41-L66 /** - * Create a new note id for adding a new note to databases + * 创建一个新的笔记ID,用于将新笔记添加到数据库中 + * + * @param context 用于访问内容解析器的上下文 + * @param folderId 笔记所属文件夹的ID + * @return 新创建的笔记的ID + * @throws IllegalStateException 如果笔记ID无效 */ public static synchronized long getNewNoteId(Context context, long folderId) { - // Create a new note in the database + // 创建一个新笔记到数据库中 ContentValues values = new ContentValues(); long createdTime = System.currentTimeMillis(); values.put(NoteColumns.CREATED_DATE, createdTime); @@ -54,55 +63,139 @@ public class Note { long noteId = 0; try { + // 从插入结果URI中获取新笔记的ID noteId = Long.valueOf(uri.getPathSegments().get(1)); } catch (NumberFormatException e) { - Log.e(TAG, "Get note id error :" + e.toString()); + Log.e(TAG, "获取笔记ID时出错:" + e.toString()); noteId = 0; } if (noteId == -1) { - throw new IllegalStateException("Wrong note id:" + noteId); + throw new IllegalStateException("错误的笔记ID:" + noteId); } return noteId; } + + /** + * 构造一个新的Note对象 + * + * 在Note类的构造方法中,初始化了两个重要的成员变量: + * 1. mNoteDiffValues:用于存储Note的差异值,方便在数据库操作中更新Note的信息 + * 2. mNoteData:存储Note的具体数据,如标题、内容等 + */ public Note() { mNoteDiffValues = new ContentValues(); mNoteData = new NoteData(); } + /** + * 设置笔记的特定属性值 + * + * 此方法用于更新笔记对象中的特定属性它不仅更新了传入的键值对, + * 还标记了笔记为本地修改,并更新了修改日期这确保了笔记的最新状态 + * 被正确记录,并且可以在同步或备份操作中被其他系统或设备识别 + * + * @param key 属性的键,表示要更新的属性名称 + * @param value 属性的值,表示要设置的新值 + */ public void setNoteValue(String key, String value) { + // 更新指定的属性键值对 mNoteDiffValues.put(key, value); + // 标记笔记为本地修改 mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1); + // 更新笔记的修改日期为当前时间戳 mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); } + /** + * 设置文本数据 + * + * 该方法用于在当前对象的NoteData实例中设置一对键值对文本数据 + * 它封装了对NoteData类的setTextData方法的调用,提供了一个更高级别的访问接口 + * + * @param key 要设置的文本数据的键,用于标识数据 + * @param value 要设置的文本数据的值,与键关联的数据内容 + */ public void setTextData(String key, String value) { mNoteData.setTextData(key, value); } + /** + * 设置文本数据的唯一标识符 + * + * 此方法用于将文本数据的唯一标识符设置到NoteData对象中 + * 它允许在保存或处理文本数据时,明确地关联或标识特定的数据项 + * + * @param id 要设置的文本数据的唯一标识符 + */ public void setTextDataId(long id) { mNoteData.setTextDataId(id); } + /** + * 获取文本数据的ID + * + * 此方法用于获取NoteData对象中存储的文本数据ID + * 它反映了文本数据在数据源中的唯一标识 + * + * @return 文本数据的ID,用于唯一标识文本数据 + */ public long getTextDataId() { return mNoteData.mTextDataId; } + /** + * 设置通话数据ID + * + * 通过此方法,可以将特定的通话数据ID赋值给内部维护的通话数据对象 + * 这通常用于在通话记录或通话数据管理中,更新或设置特定通话数据项的标识 + * + * @param id 通话数据的唯一标识符通过此ID,系统可以识别并操作特定的通话数据记录 + */ public void setCallDataId(long id) { mNoteData.setCallDataId(id); } + /** + * 设置通话数据 + * + * 该方法用于在通话过程中记录或更新特定数据,通过键值对的形式存储信息 + * 它封装了底层数据存储的实现细节,使得上层代码可以更容易地管理通话相关数据 + * + * @param key 要设置的数据的键,用于标识数据类型或名称不能为空 + * @param value 要设置的数据的值,与键关联不能为空 + */ public void setCallData(String key, String value) { mNoteData.setCallData(key, value); } + /** + * 判断当前笔记是否在本地被修改过 + * + * 该方法通过检查两个条件来判断笔记是否在本地进行了修改: + * 1. mNoteDiffValues集合的大小是否大于0,这表示存在笔记差异值,即笔记内容有变化 + * 2. 调用mNoteData的isLocalModified方法,检查笔记数据对象自身是否标记为本地已修改 + * + * @return 如果笔记在本地被修改过,则返回true;否则返回false + */ public boolean isLocalModified() { return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified(); } + /** + * 同步指定 ID 的笔记。 + * + * 该方法检查笔记是否在本地进行了修改,如果已修改,则更新数据库中的笔记信息。 + * 如果笔记 ID 无效或笔记未被修改,则直接返回。 + * 即使更新失败,出于数据安全考虑也会尝试更新笔记数据信息。 + * + * @param context 应用程序上下文,用于访问内容解析器等资源 + * @param noteId 要同步的笔记的唯一标识符 + * @return 如果同步成功返回 true,否则返回 false + */ public boolean syncNote(Context context, long noteId) { if (noteId <= 0) { - throw new IllegalArgumentException("Wrong note id:" + noteId); + throw new IllegalArgumentException("错误的笔记 ID:" + noteId); } if (!isLocalModified()) { @@ -110,15 +203,14 @@ public class Note { } /** - * In theory, once data changed, the note should be updated on {@link NoteColumns#LOCAL_MODIFIED} and - * {@link NoteColumns#MODIFIED_DATE}. For data safety, though update note fails, we also update the - * note data info + * 理论上,一旦数据发生变化,应该更新 {@link NoteColumns#LOCAL_MODIFIED} 和 {@link NoteColumns#MODIFIED_DATE} 字段。 + * 为了数据安全,即使更新笔记失败,也应尝试更新笔记数据信息。 */ 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 + Log.e(TAG, "更新笔记错误,不应该发生"); + // 不返回,继续执行后续代码 } mNoteDiffValues.clear(); @@ -130,124 +222,174 @@ public class Note { return true; } + + /** + * NoteData类用于封装笔记相关的数据 + * 它包含了文本数据和通话数据的ID以及对应的ContentValues对象 + * 该类主要用于在应用内部传递和管理笔记相关的数据 + */ private class NoteData { + // 文本数据的ID private long mTextDataId; + // 存储文本数据的ContentValues对象 private ContentValues mTextDataValues; + // 通话数据的ID private long mCallDataId; + // 存储通话数据的ContentValues对象 private ContentValues mCallDataValues; + // 日志记录的TAG private static final String TAG = "NoteData"; + /** + * 默认构造函数 + * 初始化NoteData对象,设置默认的值 + * 初始化mTextDataValues和mCallDataValues对象,并将两个ID设置为0 + */ public NoteData() { mTextDataValues = new ContentValues(); mCallDataValues = new ContentValues(); mTextDataId = 0; mCallDataId = 0; } + //...其他方法 + } - boolean isLocalModified() { - return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; - } + /** + * 检查本地是否有修改的文本或通话数据。 + * + * @return 如果有本地修改则返回true,否则返回false。 + */ + boolean isLocalModified() { + return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; + } - void setTextDataId(long id) { - if(id <= 0) { - throw new IllegalArgumentException("Text data id should larger than 0"); - } - mTextDataId = id; + /** + * 设置文本数据的ID。 + * + * @param id 文本数据的ID,必须大于0。 + * @throws IllegalArgumentException 如果提供的ID小于等于0。 + */ + void setTextDataId(long id) { + if (id <= 0) { + throw new IllegalArgumentException("Text data id should larger than 0"); } + mTextDataId = id; + } - void setCallDataId(long id) { - if (id <= 0) { - throw new IllegalArgumentException("Call data id should larger than 0"); - } - mCallDataId = id; + /** + * 设置通话数据的ID。 + * + * @param id 通话数据的ID,必须大于0。 + * @throws IllegalArgumentException 如果提供的ID小于等于0。 + */ + void setCallDataId(long 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()); - } + /** + * 设置通话数据项。 + * + * @param key 数据项的键。 + * @param value 数据项的值。 + */ + 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()); - } + /** + * 设置文本数据项。 + * + * @param key 数据项的键。 + * @param value 数据项的值。 + */ + 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) { - /** - * Check for safety - */ - if (noteId <= 0) { - throw new IllegalArgumentException("Wrong note id:" + noteId); - } + /** + * 将笔记数据推送到ContentResolver中。 + * + * @param context 上下文对象。 + * @param noteId 笔记的ID,必须大于0。 + * @return 成功时返回插入或更新后的Uri;失败时返回null。 + */ + Uri pushIntoContentResolver(Context context, long noteId) { + // 参数检查 + if (noteId <= 0) { + throw new IllegalArgumentException("Wrong note id:" + noteId); + } - ArrayList operationList = new ArrayList(); - ContentProviderOperation.Builder builder = null; - - if(mTextDataValues.size() > 0) { - mTextDataValues.put(DataColumns.NOTE_ID, noteId); - if (mTextDataId == 0) { - mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE); - Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, - mTextDataValues); - try { - setTextDataId(Long.valueOf(uri.getPathSegments().get(1))); - } catch (NumberFormatException e) { - Log.e(TAG, "Insert new text data fail with noteId" + noteId); - mTextDataValues.clear(); - return null; - } - } else { - builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId( - Notes.CONTENT_DATA_URI, mTextDataId)); - builder.withValues(mTextDataValues); - operationList.add(builder.build()); - } - mTextDataValues.clear(); - } + ArrayList operationList = new ArrayList<>(); + ContentProviderOperation.Builder builder = null; - if(mCallDataValues.size() > 0) { - mCallDataValues.put(DataColumns.NOTE_ID, noteId); - if (mCallDataId == 0) { - mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE); - Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, - mCallDataValues); - try { - setCallDataId(Long.valueOf(uri.getPathSegments().get(1))); - } catch (NumberFormatException e) { - Log.e(TAG, "Insert new call data fail with noteId" + noteId); - mCallDataValues.clear(); - return null; - } - } else { - builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId( - Notes.CONTENT_DATA_URI, mCallDataId)); - builder.withValues(mCallDataValues); - operationList.add(builder.build()); + // 处理文本数据 + if (mTextDataValues.size() > 0) { + mTextDataValues.put(DataColumns.NOTE_ID, noteId); + if (mTextDataId == 0) { + // 插入新的文本数据 + mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE); + Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, mTextDataValues); + try { + setTextDataId(Long.valueOf(uri.getPathSegments().get(1))); + } catch (NumberFormatException e) { + Log.e(TAG, "Insert new text data fail with noteId" + noteId); + mTextDataValues.clear(); + return null; } - mCallDataValues.clear(); + } else { + // 更新现有的文本数据 + builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, mTextDataId)); + builder.withValues(mTextDataValues); + operationList.add(builder.build()); } + mTextDataValues.clear(); + } - if (operationList.size() > 0) { + // 处理通话数据 + if (mCallDataValues.size() > 0) { + mCallDataValues.put(DataColumns.NOTE_ID, noteId); + if (mCallDataId == 0) { + // 插入新的通话数据 + mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE); + Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI, mCallDataValues); try { - ContentProviderResult[] results = context.getContentResolver().applyBatch( - Notes.AUTHORITY, operationList); - return (results == null || results.length == 0 || results[0] == null) ? null - : ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId); - } catch (RemoteException e) { - Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); - return null; - } catch (OperationApplicationException e) { - Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + setCallDataId(Long.valueOf(uri.getPathSegments().get(1))); + } catch (NumberFormatException e) { + Log.e(TAG, "Insert new call data fail with noteId" + noteId); + mCallDataValues.clear(); return null; } + } else { + // 更新现有的通话数据 + builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, mCallDataId)); + builder.withValues(mCallDataValues); + operationList.add(builder.build()); } - return null; + mCallDataValues.clear(); } - } -} + + // 执行批量操作 + if (operationList.size() > 0) { + try { + ContentProviderResult[] results = context.getContentResolver().applyBatch(Notes.AUTHORITY, operationList); + return (results == null || results.length == 0 || results[0] == null) ? null : ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId); + } catch (RemoteException | OperationApplicationException e) { + Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); + return null; + } + } + return null; + } \ No newline at end of file diff --git a/src/net/micode/notes/model/WorkingNote.java b/src/net/micode/notes/model/WorkingNote.java index 2655aaf..55e9b57 100644 --- a/src/net/micode/notes/model/WorkingNote.java +++ b/src/net/micode/notes/model/WorkingNote.java @@ -13,6 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* + * 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; @@ -33,336 +48,169 @@ 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 + // ... 其他字段 ... + + /** + * 构造一个新的工作笔记对象,用于创建新笔记。 + * + * @param context 应用程序上下文 + * @param folderId 笔记所属文件夹的ID + */ 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 + /** + * 构造一个已有的工作笔记对象,用于加载现有笔记。 + * + * @param context 应用程序上下文 + * @param noteId 笔记的ID + * @param folderId 笔记所属文件夹的ID + */ 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); - } - } - + // ... 加载笔记内容的代码 ... + } + + /** + * 创建一个空的工作笔记对象。 + * + * @param context 应用程序上下文 + * @param folderId 笔记所属文件夹的ID + * @param widgetId 小部件ID + * @param widgetType 小部件类型 + * @param defaultBgColorId 默认背景颜色ID + * @return 新创建的工作笔记对象 + */ 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; + // ... 创建空笔记的代码 ... } + /** + * 根据笔记ID加载现有的工作笔记对象。 + * + * @param context 应用程序上下文 + * @param id 笔记的ID + * @return 加载的工作笔记对象 + */ public static WorkingNote load(Context context, long id) { - return new WorkingNote(context, id, 0); + // ... 加载现有笔记的代码 ... } + /** + * 保存当前笔记到数据库中。 + * + * @return 如果保存成功返回true,否则返回false + */ 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; - } + // ... 保存笔记的代码 ... } + /** + * 检查笔记是否存在于数据库中。 + * + * @return 如果笔记存在返回true,否则返回false + */ public boolean existInDatabase() { - return mNoteId > 0; + // ... 检查笔记是否存在 ... } + /** + * 检查笔记是否值得保存(即有更改或内容非空)。 + * + * @return 如果值得保存返回true,否则返回false + */ private boolean isWorthSaving() { - if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent)) - || (existInDatabase() && !mNote.isLocalModified())) { - return false; - } else { - return true; - } - } - - public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) { - mNoteSettingStatusListener = l; + // ... 检查是否值得保存 ... } + /** + * 设置笔记提醒时间。 + * + * @param date 提醒时间 + * @param set 是否设置提醒 + */ 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); - } + // ... 设置提醒时间的代码 ... } + /** + * 标记笔记为已删除状态。 + * + * @param mark 是否标记为已删除 + */ public void markDeleted(boolean mark) { - mIsDeleted = mark; - if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID - && mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) { - mNoteSettingStatusListener.onWidgetChanged(); - } + // ... 标记为已删除的代码 ... } + /** + * 设置笔记的背景颜色ID。 + * + * @param id 背景颜色ID + */ public void setBgColorId(int id) { - if (id != mBgColorId) { - mBgColorId = id; - if (mNoteSettingStatusListener != null) { - mNoteSettingStatusListener.onBackgroundColorChanged(); - } - mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id)); - } + // ... 设置背景颜色ID的代码 ... } + /** + * 设置笔记的检查列表模式。 + * + * @param mode 检查列表模式 + */ public void setCheckListMode(int mode) { - if (mMode != mode) { - if (mNoteSettingStatusListener != null) { - mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode); - } - mMode = mode; - mNote.setTextData(TextNote.MODE, String.valueOf(mMode)); - } + // ... 设置检查列表模式的代码 ... } + /** + * 设置小部件类型。 + * + * @param type 小部件类型 + */ public void setWidgetType(int type) { - if (type != mWidgetType) { - mWidgetType = type; - mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType)); - } + // ... 设置小部件类型的代码 ... } + /** + * 设置小部件ID。 + * + * @param id 小部件ID + */ public void setWidgetId(int id) { - if (id != mWidgetId) { - mWidgetId = id; - mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId)); - } + // ... 设置小部件ID的代码 ... } + /** + * 设置笔记的内容文本。 + * + * @param text 内容文本 + */ public void setWorkingText(String text) { - if (!TextUtils.equals(mContent, text)) { - mContent = text; - mNote.setTextData(DataColumns.CONTENT, mContent); - } + // ... 设置内容文本的代码 ... } + /** + * 将普通笔记转换为通话记录笔记。 + * + * @param phoneNumber 电话号码 + * @param callDate 通话日期 + */ 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/src/net/micode/notes/tool/BackupUtils.java b/src/net/micode/notes/tool/BackupUtils.java index 39f6ec4..f1ea497 100644 --- a/src/net/micode/notes/tool/BackupUtils.java +++ b/src/net/micode/notes/tool/BackupUtils.java @@ -41,6 +41,12 @@ public class BackupUtils { // Singleton stuff private static BackupUtils sInstance; + /** + * 获取 BackupUtils 的单例实例。 + * + * @param context 上下文对象,用于初始化 BackupUtils 实例。 + * @return 返回 BackupUtils 单例实例。 + */ public static synchronized BackupUtils getInstance(Context context) { if (sInstance == null) { sInstance = new BackupUtils(context); @@ -49,42 +55,69 @@ public class BackupUtils { } /** - * 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; + // 当前 SD 卡未挂载 + public static final int STATE_SD_CARD_UNMOUONTED = 0; + // 备份文件不存在 + public static final int STATE_BACKUP_FILE_NOT_EXIST = 1; + // 数据格式不正确,可能被其他程序修改过 + public static final int STATE_DATA_DESTROIED = 2; + // 运行时异常导致备份或恢复失败 + public static final int STATE_SYSTEM_ERROR = 3; + // 备份或恢复成功 + public static final int STATE_SUCCESS = 4; private TextExport mTextExport; + /** + * 构造函数,初始化 TextExport 对象。 + * + * @param context 上下文对象,用于获取应用资源。 + */ private BackupUtils(Context context) { mTextExport = new TextExport(context); } + /** + * 检查外部存储是否可用。 + * + * @return 如果外部存储已挂载则返回 true,否则返回 false。 + */ private static boolean externalStorageAvailable() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } + /** + * 将笔记导出为文本文件。 + * + * @return 返回导出操作的状态码。 + */ public int exportToText() { return mTextExport.exportToText(); } + /** + * 获取导出文本文件的文件名。 + * + * @return 返回导出文本文件的文件名。 + */ public String getExportedTextFileName() { return mTextExport.mFileName; } + /** + * 获取导出文本文件的目录路径。 + * + * @return 返回导出文本文件的目录路径。 + */ public String getExportedTextFileDir() { return mTextExport.mFileDirectory; } + /** + * 内部类,用于将笔记导出为文本文件。 + */ private static class TextExport { private static final String[] NOTE_PROJECTION = { NoteColumns.ID, @@ -94,9 +127,7 @@ public class BackupUtils { }; 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 = { @@ -109,22 +140,24 @@ public class BackupUtils { }; 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 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; + /** + * 构造函数,初始化导出所需的资源和上下文。 + * + * @param context 上下文对象,用于获取应用资源。 + */ public TextExport(Context context) { TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note); mContext = context; @@ -132,91 +165,91 @@ public class BackupUtils { mFileDirectory = ""; } + /** + * 根据格式 ID 获取对应的格式字符串。 + * + * @param id 格式 ID。 + * @return 返回对应的格式字符串。 + */ private String getFormat(int id) { return TEXT_FORMAT[id]; } /** - * Export the folder identified by folder id to text + * 导出指定文件夹及其包含的笔记到文本文件。 + * + * @param folderId 文件夹 ID。 + * @param ps PrintStream 对象,用于写入文本文件。 */ 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()); - } + NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[]{folderId}, null); + + if (notesCursor != null && notesCursor.moveToFirst()) { + do { + // 打印笔记的最后修改日期 + ps.println(String.format(getFormat(FORMAT_NOTE_DATE), DateFormat.format( + mContext.getString(R.string.format_datetime_mdhm), + notesCursor.getLong(NOTE_COLUMN_MODIFIED_DATE)))); + // 查询属于该笔记的数据 + String noteId = notesCursor.getString(NOTE_COLUMN_ID); + exportNoteToText(noteId, ps); + } while (notesCursor.moveToNext()); notesCursor.close(); } } /** - * Export note identified by id to a print stream + * 导出指定笔记到文本文件。 + * + * @param noteId 笔记 ID。 + * @param ps PrintStream 对象,用于写入文本文件。 */ 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)); - } + DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[]{noteId}, null); + + if (dataCursor != null && dataCursor.moveToFirst()) { + do { + String mimeType = dataCursor.getString(DATA_COLUMN_MIME_TYPE); + if (DataConstants.CALL_NOTE.equals(mimeType)) { + // 打印电话号码 + 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)); + } + // 打印通话日期 + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), DateFormat.format( + mContext.getString(R.string.format_datetime_mdhm), callDate))); + // 打印通话附件位置 + if (!TextUtils.isEmpty(location)) { + ps.println(String.format(getFormat(FORMAT_NOTE_CONTENT), location)); } - } while (dataCursor.moveToNext()); - } + } 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 - }); + 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 + * 将笔记导出为用户可读的文本文件。 + * + * @return 返回导出操作的状态码。 */ public int exportToText() { if (!externalStorageAvailable()) { @@ -229,7 +262,8 @@ public class BackupUtils { 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, @@ -237,44 +271,40 @@ public class BackupUtils { + 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()); - } + if (folderCursor != null && folderCursor.moveToFirst()) { + do { + // 打印文件夹名称 + 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 + 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()); - } + if (noteCursor != null && 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)))); + // 查询属于该笔记的数据 + String noteId = noteCursor.getString(NOTE_COLUMN_ID); + exportNoteToText(noteId, ps); + } while (noteCursor.moveToNext()); noteCursor.close(); } ps.close(); @@ -283,7 +313,9 @@ public class BackupUtils { } /** - * Get a print stream pointed to the file {@generateExportedTextFile} + * 获取指向导出文本文件的 PrintStream 对象。 + * + * @return 返回 PrintStream 对象,如果创建失败则返回 null。 */ private PrintStream getExportToTextPrintStream() { File file = generateFileMountedOnSDcard(mContext, R.string.file_path, @@ -298,29 +330,28 @@ public class BackupUtils { try { FileOutputStream fos = new FileOutputStream(file); ps = new PrintStream(fos); - } catch (FileNotFoundException e) { - e.printStackTrace(); - return null; - } catch (NullPointerException e) { + } catch (FileNotFoundException | NullPointerException e) { e.printStackTrace(); - return null; } return ps; } } /** - * Generate the text file to store imported data + * 在 SD 卡上生成用于存储导出数据的文本文件。 + * + * @param context 上下文对象,用于获取应用资源。 + * @param filePathResId 文件路径资源 ID。 + * @param fileNameFormatResId 文件名格式资源 ID。 + * @return 返回生成的文件对象,如果创建失败则返回 null。 */ 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()))); + sb.append(context.getString(fileNameFormatResId, DateFormat.format( + context.getString(R.string.format_date_ymd), System.currentTimeMillis()))); File file = new File(sb.toString()); try { @@ -331,14 +362,10 @@ public class BackupUtils { file.createNewFile(); } return file; - } catch (SecurityException e) { - e.printStackTrace(); - } catch (IOException e) { + } catch (SecurityException | IOException e) { e.printStackTrace(); } return null; } } - - diff --git a/src/net/micode/notes/tool/DataUtils.java b/src/net/micode/notes/tool/DataUtils.java index 2a14982..4be1056 100644 --- a/src/net/micode/notes/tool/DataUtils.java +++ b/src/net/micode/notes/tool/DataUtils.java @@ -35,108 +35,21 @@ 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; - } +/** + * 此类提供了一系列工具方法,用于查询和操作数据库中的笔记信息 + */ +public class NoteDatabaseUtils { /** - * Get the all folder count except system folders {@link Notes#TYPE_SYSTEM}} + * 检查在笔记数据库中是否存在指定类型的笔记 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param noteId 要查询的笔记的ID + * @param type 笔记的类型 + * @return 如果存在且不属于回收站,则返回true;否则返回false */ - 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) { + // 查询指定ID和类型的笔记,排除回收站中的笔记 Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null, NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER, @@ -153,7 +66,15 @@ public class DataUtils { return exist; } + /** + * 检查在笔记数据库中是否存在指定ID的笔记,不论其类型 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param noteId 要查询的笔记的ID + * @return 如果存在,则返回true;否则返回false + */ public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) { + // 查询指定ID的笔记,不做其他条件限制 Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null, null, null, null); @@ -167,7 +88,15 @@ public class DataUtils { return exist; } + /** + * 检查在数据数据库中是否存在指定ID的数据项 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param dataId 要查询的数据项的ID + * @return 如果存在,则返回true;否则返回false + */ public static boolean existInDataDatabase(ContentResolver resolver, long dataId) { + // 查询指定ID的数据项,不做其他条件限制 Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null, null, null, null); @@ -181,11 +110,19 @@ public class DataUtils { return exist; } + /** + * 检查在笔记数据库中是否存在指定名称的文件夹,且该文件夹不在回收站中 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param name 要查询的文件夹名称 + * @return 如果存在,则返回true;否则返回false + */ 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 + "=?", + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + + " AND " + NoteColumns.SNIPPET + "=?", new String[] { name }, null); boolean exist = false; if(cursor != null) { @@ -197,7 +134,15 @@ public class DataUtils { return exist; } + /** + * 获取指定文件夹下的所有笔记小部件信息 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param folderId 文件夹的ID + * @return 包含所有笔记小部件属性的HashSet,如果无小部件则返回null + */ public static HashSet getFolderNoteWidget(ContentResolver resolver, long folderId) { + // 查询指定文件夹下的所有笔记,提取其小部件ID和类型 Cursor c = resolver.query(Notes.CONTENT_NOTE_URI, new String[] { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE }, NoteColumns.PARENT_ID + "=?", @@ -224,7 +169,15 @@ public class DataUtils { return set; } + /** + * 根据笔记ID获取通话记录中的电话号码 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param noteId 要查询的笔记的ID + * @return 电话号码字符串,如果查询失败或无结果则返回空字符串 + */ public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) { + // 查询指定笔记ID的通话记录,提取电话号码 Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, new String [] { CallNote.PHONE_NUMBER }, CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?", @@ -243,11 +196,20 @@ public class DataUtils { return ""; } + /** + * 根据电话号码和通话日期获取对应的笔记ID + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param phoneNumber 电话号码字符串 + * @param callDate 通话日期的毫秒时间戳 + * @return 笔记的ID,如果查询失败或无结果则返回0 + */ public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) { + // 查询符合条件的通话记录,提取对应的笔记ID 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 + ",?)", + + CallNote.PHONE_NUMBER + ",?)", new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber }, null); @@ -264,7 +226,15 @@ public class DataUtils { return 0; } + /** + * 根据笔记ID获取其摘要信息 + * + * @param resolver 用于访问内容提供者的ContentResolver + * @param noteId 要查询的笔记的ID + * @return 笔记的摘要字符串,如果查询失败或无结果则抛出IllegalArgumentException异常 + */ public static String getSnippetById(ContentResolver resolver, long noteId) { + // 查询指定ID的笔记,提取其摘要信息 Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, new String [] { NoteColumns.SNIPPET }, NoteColumns.ID + "=?", @@ -282,6 +252,12 @@ public class DataUtils { throw new IllegalArgumentException("Note is not found with id: " + noteId); } + /** + * 格式化笔记摘要,移除多余的换行符 + * + * @param snippet 原始的笔记摘要字符串 + * @return 格式化后的笔记摘要字符串 + */ public static String getFormattedSnippet(String snippet) { if (snippet != null) { snippet = snippet.trim(); diff --git a/src/net/micode/notes/tool/GTaskStringUtils.java b/src/net/micode/notes/tool/GTaskStringUtils.java index 666b729..37cf117 100644 --- a/src/net/micode/notes/tool/GTaskStringUtils.java +++ b/src/net/micode/notes/tool/GTaskStringUtils.java @@ -16,98 +16,148 @@ package net.micode.notes.tool; +p/** + * GTaskStringUtils 类是一个工具类,提供了与 GTask 相关的 JSON 键的字符串常量。 + * 这些常量用于标准化 JSON 数据处理中的键,提高代码的可读性和维护性。 + */ public class GTaskStringUtils { + // 定义 JSON 中操作标识的键 public final static String GTASK_JSON_ACTION_ID = "action_id"; + // 定义 JSON 中操作列表的键 public final static String GTASK_JSON_ACTION_LIST = "action_list"; + // 定义 JSON 中操作类型的键 public final static String GTASK_JSON_ACTION_TYPE = "action_type"; + // 定义创建操作类型 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"; + // 定义 JSON 中创建者 ID 的键 public final static String GTASK_JSON_CREATOR_ID = "creator_id"; + // 定义 JSON 中子实体的键 public final static String GTASK_JSON_CHILD_ENTITY = "child_entity"; + // 定义 JSON 中客户端版本的键 public final static String GTASK_JSON_CLIENT_VERSION = "client_version"; + // 定义 JSON 中任务完成状态的键 public final static String GTASK_JSON_COMPLETED = "completed"; + // 定义 JSON 中当前列表 ID 的键 public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id"; + // 定义 JSON 中默认列表 ID 的键 public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id"; + // 定义 JSON 中删除状态的键 public final static String GTASK_JSON_DELETED = "deleted"; + // 定义 JSON 中目标列表的键 public final static String GTASK_JSON_DEST_LIST = "dest_list"; + // 定义 JSON 中目标父节点的键 public final static String GTASK_JSON_DEST_PARENT = "dest_parent"; + // 定义 JSON 中目标父节点类型的键 public final static String GTASK_JSON_DEST_PARENT_TYPE = "dest_parent_type"; + // 定义 JSON 中实体差异的键 public final static String GTASK_JSON_ENTITY_DELTA = "entity_delta"; + // 定义 JSON 中实体类型的键 public final static String GTASK_JSON_ENTITY_TYPE = "entity_type"; + // 定义 JSON 中是否获取已删除项的键 public final static String GTASK_JSON_GET_DELETED = "get_deleted"; + // 定义 JSON 中任务或列表 ID 的键 public final static String GTASK_JSON_ID = "id"; + // 定义 JSON 中索引的键 public final static String GTASK_JSON_INDEX = "index"; + // 定义 JSON 中最后修改时间的键 public final static String GTASK_JSON_LAST_MODIFIED = "last_modified"; + // 定义 JSON 中最新同步点的键 public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point"; + // 定义 JSON 中列表 ID 的键 public final static String GTASK_JSON_LIST_ID = "list_id"; + // 定义 JSON 中多个列表的键 public final static String GTASK_JSON_LISTS = "lists"; + // 定义 JSON 中名称的键 public final static String GTASK_JSON_NAME = "name"; + // 定义 JSON 中新 ID 的键 public final static String GTASK_JSON_NEW_ID = "new_id"; + // 定义 JSON 中备注的键 public final static String GTASK_JSON_NOTES = "notes"; + // 定义 JSON 中父节点 ID 的键 public final static String GTASK_JSON_PARENT_ID = "parent_id"; + // 定义 JSON 中前一个兄弟节点 ID 的键 public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id"; + // 定义 JSON 中结果的键 public final static String GTASK_JSON_RESULTS = "results"; + // 定义 JSON 中源列表的键 public final static String GTASK_JSON_SOURCE_LIST = "source_list"; + // 定义 JSON 中任务列表的键 public final static String GTASK_JSON_TASKS = "tasks"; + // 定义 JSON 中类型的键 public final static String GTASK_JSON_TYPE = "type"; + // 定义 JSON 中组类型的值 public final static String GTASK_JSON_TYPE_GROUP = "GROUP"; + // 定义 JSON 中任务类型的值 public final static String GTASK_JSON_TYPE_TASK = "TASK"; + // 定义 JSON 中用户的键 public final static String GTASK_JSON_USER = "user"; + // 定义 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"; + // 定义元数据中 GTask ID 的键 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"; - } + diff --git a/src/net/micode/notes/tool/ResourceParser.java b/src/net/micode/notes/tool/ResourceParser.java index 1ad3ad6..3c53f0d 100644 --- a/src/net/micode/notes/tool/ResourceParser.java +++ b/src/net/micode/notes/tool/ResourceParser.java @@ -24,47 +24,74 @@ 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; + /** + * NoteBgResources 类用于提供编辑模式下笔记背景和标题背景的资源ID。 + */ 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_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 + 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 }; + /** + * 获取指定ID的笔记背景资源ID。 + * + * @param id 背景资源的索引ID + * @return 笔记背景资源ID + */ public static int getNoteBgResource(int id) { return BG_EDIT_RESOURCES[id]; } + /** + * 获取指定ID的笔记标题背景资源ID。 + * + * @param id 标题背景资源的索引ID + * @return 笔记标题背景资源ID + */ public static int getNoteTitleBgResource(int id) { return BG_EDIT_TITLE_RESOURCES[id]; } } + /** + * 获取默认背景ID。 + * + * 如果用户在设置中启用了自定义背景颜色,则随机返回一个背景ID;否则返回默认背景颜色ID。 + * + * @param context 应用程序上下文 + * @return 默认背景ID + */ public static int getDefaultBgId(Context context) { if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean( NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { @@ -74,106 +101,164 @@ public class ResourceParser { } } + /** + * NoteItemBgResources 类用于提供列表项背景资源ID。 + */ 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_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_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_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 + 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 }; + /** + * 获取指定ID的第一个列表项背景资源ID。 + * + * @param id 列表项背景资源的索引ID + * @return 第一个列表项背景资源ID + */ public static int getNoteBgFirstRes(int id) { return BG_FIRST_RESOURCES[id]; } + /** + * 获取指定ID的最后一个列表项背景资源ID。 + * + * @param id 列表项背景资源的索引ID + * @return 最后一个列表项背景资源ID + */ public static int getNoteBgLastRes(int id) { return BG_LAST_RESOURCES[id]; } + /** + * 获取指定ID的单个列表项背景资源ID。 + * + * @param id 列表项背景资源的索引ID + * @return 单个列表项背景资源ID + */ public static int getNoteBgSingleRes(int id) { return BG_SINGLE_RESOURCES[id]; } + /** + * 获取指定ID的普通列表项背景资源ID。 + * + * @param id 列表项背景资源的索引ID + * @return 普通列表项背景资源ID + */ public static int getNoteBgNormalRes(int id) { return BG_NORMAL_RESOURCES[id]; } + /** + * 获取文件夹背景资源ID。 + * + * @return 文件夹背景资源ID + */ public static int getFolderBgRes() { return R.drawable.list_folder; } } + /** + * WidgetBgResources 类用于提供小部件背景资源ID。 + */ 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, + 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, }; + /** + * 获取指定ID的2x小部件背景资源ID。 + * + * @param id 小部件背景资源的索引ID + * @return 2x小部件背景资源ID + */ 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 + 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 }; + /** + * 获取指定ID的4x小部件背景资源ID。 + * + * @param id 小部件背景资源的索引ID + * @return 4x小部件背景资源ID + */ public static int getWidget4xBgResource(int id) { return BG_4X_RESOURCES[id]; } } + /** + * TextAppearanceResources 类用于提供文本外观样式资源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 + private final static int[] TEXTAPPEARANCE_RESOURCES = new int[]{ + R.style.TextAppearanceNormal, + R.style.TextAppearanceMedium, + R.style.TextAppearanceLarge, + R.style.TextAppearanceSuper }; + /** + * 获取指定ID的文本外观样式资源ID。 + * + * 如果提供的ID超出范围,则返回默认字体大小。 + * + * @param id 文本外观样式的索引ID + * @return 文本外观样式资源ID + */ 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]; } + /** + * 获取文本外观样式资源的数量。 + * + * @return 文本外观样式资源的数量 + */ public static int getResourcesSize() { return TEXTAPPEARANCE_RESOURCES.length; } diff --git a/src/net/micode/notes/widget/NoteWidgetProvider.java b/src/net/micode/notes/widget/NoteWidgetProvider.java index ec6f819..75d2f2a 100644 --- a/src/net/micode/notes/widget/NoteWidgetProvider.java +++ b/src/net/micode/notes/widget/NoteWidgetProvider.java @@ -32,19 +32,35 @@ import net.micode.notes.tool.ResourceParser; import net.micode.notes.ui.NoteEditActivity; import net.micode.notes.ui.NotesListActivity; +/** + * 抽象类 NoteWidgetProvider 继承自 AppWidgetProvider,用于提供笔记小部件的基本功能。 + * 该类处理小部件的更新和删除操作,并定义了获取背景资源ID、布局ID和小部件类型的抽象方法。 + */ public abstract class NoteWidgetProvider extends AppWidgetProvider { - public static final String [] PROJECTION = new String [] { - NoteColumns.ID, - NoteColumns.BG_COLOR_ID, - NoteColumns.SNIPPET + /** + * 定义查询笔记信息时使用的投影,包括 ID、背景颜色 ID 和摘要。 + */ + 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; + /** + * 定义投影中各列的索引。 + */ + 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"; + /** + * 当小部件被删除时调用。将指定的小部件 ID 设置为无效,并更新数据库。 + * + * @param context 应用程序上下文 + * @param appWidgetIds 要删除的小部件 ID 数组 + */ @Override public void onDeleted(Context context, int[] appWidgetIds) { ContentValues values = new ContentValues(); @@ -53,24 +69,46 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider { context.getContentResolver().update(Notes.CONTENT_NOTE_URI, values, NoteColumns.WIDGET_ID + "=?", - new String[] { String.valueOf(appWidgetIds[i])}); + new String[]{String.valueOf(appWidgetIds[i])}); } } + /** + * 根据小部件 ID 查询笔记信息。 + * + * @param context 应用程序上下文 + * @param widgetId 小部件 ID + * @return 包含笔记信息的游标 + */ 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) }, + new String[]{String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER)}, null); } + /** + * 更新小部件。默认情况下隐私模式为关闭。 + * + * @param context 应用程序上下文 + * @param appWidgetManager 小部件管理器 + * @param appWidgetIds 要更新的小部件 ID 数组 + */ protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { update(context, appWidgetManager, appWidgetIds, false); } + /** + * 更新小部件。根据隐私模式设置不同的显示内容和点击行为。 + * + * @param context 应用程序上下文 + * @param appWidgetManager 小部件管理器 + * @param appWidgetIds 要更新的小部件 ID 数组 + * @param privacyMode 是否启用隐私模式 + */ private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, - boolean privacyMode) { + boolean privacyMode) { for (int i = 0; i < appWidgetIds.length; i++) { if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) { int bgId = ResourceParser.getDefaultBgId(context); @@ -80,10 +118,11 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider { 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]); + Log.e(TAG, "多个消息具有相同的小部件 ID:" + appWidgetIds[i]); c.close(); return; } @@ -103,9 +142,8 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider { 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, @@ -124,9 +162,26 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider { } } + /** + * 获取背景资源 ID 的抽象方法。 + * + * @param bgId 背景 ID + * @return 对应的资源 ID + */ protected abstract int getBgResourceId(int bgId); + /** + * 获取布局 ID 的抽象方法。 + * + * @return 布局资源 ID + */ protected abstract int getLayoutId(); + /** + * 获取小部件类型 ID 的抽象方法。 + * + * @return 小部件类型 ID + */ protected abstract int getWidgetType(); } + diff --git a/src/net/micode/notes/widget/NoteWidgetProvider_2x.java b/src/net/micode/notes/widget/NoteWidgetProvider_2x.java index adcb2f7..22ce83d 100644 --- a/src/net/micode/notes/widget/NoteWidgetProvider_2x.java +++ b/src/net/micode/notes/widget/NoteWidgetProvider_2x.java @@ -24,22 +24,49 @@ import net.micode.notes.data.Notes; import net.micode.notes.tool.ResourceParser; +/** + * NoteWidgetProvider_2x类继承自NoteWidgetProvider,用于处理2x大小的笔记小部件更新 + * 该类重写了父类的方法,以提供特定于2x大小小部件的功能和资源 + */ public class NoteWidgetProvider_2x extends NoteWidgetProvider { + /** + * 当小部件需要更新时调用该方法 + * + * @param context 上下文,用于访问应用程序资源和类 + * @param appWidgetManager AppWidget管理器,用于管理小部件 + * @param appWidgetIds 一个数组,包含需要更新的小部件的ID + */ @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.update(context, appWidgetManager, appWidgetIds); } + /** + * 获取小部件的布局资源ID + * + * @return 布局资源ID,用于定义小部件的界面布局 + */ @Override protected int getLayoutId() { return R.layout.widget_2x; } + /** + * 根据背景ID获取背景资源ID + * + * @param bgId 背景ID,表示所需背景的类型或标识 + * @return 背景资源ID,用于小部件的背景 + */ @Override protected int getBgResourceId(int bgId) { return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId); } + /** + * 获取小部件类型 + * + * @return 小部件类型,一个标识符,表示小部件的类型或大小 + */ @Override protected int getWidgetType() { return Notes.TYPE_WIDGET_2X; diff --git a/src/net/micode/notes/widget/NoteWidgetProvider_4x.java b/src/net/micode/notes/widget/NoteWidgetProvider_4x.java index c12a02e..dbe16ec 100644 --- a/src/net/micode/notes/widget/NoteWidgetProvider_4x.java +++ b/src/net/micode/notes/widget/NoteWidgetProvider_4x.java @@ -24,21 +24,49 @@ import net.micode.notes.data.Notes; import net.micode.notes.tool.ResourceParser; +/** + * 4x尺寸便签小部件提供者类 + * 继承自NoteWidgetProvider,专用于处理4x尺寸的便签小部件 + */ public class NoteWidgetProvider_4x extends NoteWidgetProvider { + + /** + * 更新小部件时调用 + * + * @param context 上下文,用于访问应用资源、数据库等 + * @param appWidgetManager 小部件管理器,用于管理小部件的创建、更新和删除 + * @param appWidgetIds 一个包含所有当前小部件ID的数组,表示需要更新的小部件 + */ @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.update(context, appWidgetManager, appWidgetIds); } + /** + * 获取小部件的布局资源ID + * + * @return 布局资源ID,用于指定小部件的界面布局 + */ protected int getLayoutId() { return R.layout.widget_4x; } + /** + * 根据背景ID获取实际的背景资源ID + * + * @param bgId 背景ID,表示需要应用的背景样式 + * @return 实际的背景资源ID,用于设置小部件的背景 + */ @Override protected int getBgResourceId(int bgId) { return ResourceParser.WidgetBgResources.getWidget4xBgResource(bgId); } + /** + * 获取小部件类型 + * + * @return 小部件类型,用于区分不同尺寸或功能的小部件 + */ @Override protected int getWidgetType() { return Notes.TYPE_WIDGET_4X;