From 888807bd363add50cb52cf2a744b899076bda920 Mon Sep 17 00:00:00 2001 From: zpz1349878361 <1349878361@qq.com> Date: Mon, 30 Dec 2024 10:19:41 +0800 Subject: [PATCH] =?UTF-8?q?tool=E7=9A=84=E4=BB=A3=E7=A0=81=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E2=80=94=E2=80=94=E8=B5=B5=E9=B9=8F=E6=B3=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BackupUtils.java | 419 +++++++++++------------------------- src/DataUtils.java | 380 ++++++++++++++++---------------- src/GTaskStringUtils.java | 39 ++-- src/NoteWidgetProvider.java | 169 --------------- src/Notes.java | 273 ----------------------- src/ResourceParser.java | 114 +++++----- 6 files changed, 404 insertions(+), 990 deletions(-) delete mode 100644 src/NoteWidgetProvider.java delete mode 100644 src/Notes.java diff --git a/src/BackupUtils.java b/src/BackupUtils.java index 8fc1c3f..821cbd6 100644 --- a/src/BackupUtils.java +++ b/src/BackupUtils.java @@ -1,21 +1,12 @@ + /* - * 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. + * BackupUtils 工具类 + * 提供了笔记备份到文本文件的功能。 */ package net.micode.notes.tool; +// 引入需要用到的 Android 和 Java 标准库类 import android.content.Context; import android.database.Cursor; import android.os.Environment; @@ -35,186 +26,152 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; - +/** + * BackupUtils 是一个工具类,用于实现笔记的备份功能。 + */ public class BackupUtils { + + // 日志标志,用于记录类中的日志 private static final String TAG = "BackupUtils"; - // 单例模式相关变量 + + // 单例模式:存储唯一实例 private static BackupUtils sInstance; /** - * 获取BackupUtils的单例实例。 + * 获取 BackupUtils 类的单例实例。 * - * @param context 上下文对象,用于访问应用全局功能。 - * @return 返回BackupUtils的单例实例。 + * @param context 上下文对象,用于初始化内部组件。 + * @return 返回 BackupUtils 实例。 */ public static synchronized BackupUtils getInstance(Context context) { - if (sInstance == null) { + if (sInstance == null) { // 如果实例不存在,则创建新实例 sInstance = new BackupUtils(context); } - return sInstance; + return sInstance; // 返回单例实例 } /** - * 定义备份或恢复状态的标志。 + * 定义备份操作的状态常量 */ - // 当前,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; + public static final int STATE_SD_CARD_UNMOUONTED = 0; // SD卡未挂载 + 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; /** - * BackupUtils的私有构造函数。 + * 私有化构造函数,防止直接实例化。 * - * @param context 上下文对象,用于初始化文本导出功能。 + * @param context 上下文对象,用于初始化导出工具类。 */ private BackupUtils(Context context) { - mTextExport = new TextExport(context); + mTextExport = new TextExport(context); // 初始化文本导出工具 } /** - * 检查外部存储是否可用。 + * 检查 SD 卡是否可用。 * - * @return 如果外部存储可用返回true,否则返回false。 + * @return 如果 SD 卡已挂载,则返回 true,否则返回 false。 */ private static boolean externalStorageAvailable() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } /** - * 导出数据到文本文件。 + * 导出笔记到文本文件。 * - * @return 返回导出操作的状态码,详见STATE_*常量。 + * @return 返回导出操作的状态码。 */ public int exportToText() { - return mTextExport.exportToText(); + return mTextExport.exportToText(); // 调用 TextExport 类中的导出方法 } /** - * 获取导出的文本文件名。 + * 获取导出文本的文件名。 * - * @return 返回导出文本文件的名称。 + * @return 返回文件名字符串。 */ public String getExportedTextFileName() { - return mTextExport.mFileName; + return mTextExport.mFileName; // 返回文件名 } /** - * 获取导出的文本文件目录。 + * 获取导出文件的目录。 * - * @return 返回导出文本文件所在的目录。 + * @return 返回目录路径字符串。 */ public String getExportedTextFileDir() { - return mTextExport.mFileDirectory; + return mTextExport.mFileDirectory; // 返回文件目录路径 } /** - * 内部类TextExport,用于执行文本导出操作。 + * 内部类,用于执行文本导出功能。 */ private static class TextExport { - // 查询笔记时需要的列 + + // 定义查询笔记的列名 private static final String[] NOTE_PROJECTION = { - NoteColumns.ID, - NoteColumns.MODIFIED_DATE, - NoteColumns.SNIPPET, - NoteColumns.TYPE + NoteColumns.ID, // 笔记 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 int NOTE_COLUMN_ID = 0; // ID 列索引 + 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, + DataColumns.CONTENT, // 内容 + DataColumns.MIME_TYPE, // MIME 类型 + DataColumns.DATA1, // 数据 1 + DataColumns.DATA2, // 数据 2 + DataColumns.DATA3, // 数据 3 + DataColumns.DATA4, // 数据 4 }; + // 定义数据列的索引 + private static final int DATA_COLUMN_CONTENT = 0; // 内容列索引 + private static final int DATA_COLUMN_MIME_TYPE = 1; // MIME 类型列索引 - // 定义数据列的内容索引 - private static final int DATA_COLUMN_CONTENT = 0; - - // 定义数据列的MIME类型索引 - 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 Context mContext; + private String mFileName; // 文件名 + private String mFileDirectory; // 文件目录 - // 用于导出笔记的文本格式数组 + // 初始化文本导出格式 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 上下文对象,通常是一个Activity或者Application对象 - */ public TextExport(Context context) { - // 初始化文本格式数组 - TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note); + TEXT_FORMAT = context.getResources().getStringArray(R.array.format_for_exported_note); // 导出格式 mContext = context; mFileName = ""; mFileDirectory = ""; } /** - * 根据索引获取文本格式 + * 根据文件夹 ID 将笔记导出为文本。 * - * @param id 索引ID - * @return 返回对应索引的文本格式 - */ - private String getFormat(int id) { - return TEXT_FORMAT[id]; - } - - /** - * 将指定文件夹的笔记导出为文本 - * - * @param folderId 文件夹ID - * @param ps 打印流,用于写入导出的文本内容 + * @param folderId 文件夹 ID。 + * @param ps 打印流,用于写入文本内容。 */ private void exportFolderToText(String folderId, PrintStream ps) { - // 查询属于该文件夹的笔记 - Cursor notesCursor = mContext.getContentResolver().query(Notes.CONTENT_NOTE_URI, - NOTE_PROJECTION, NoteColumns.PARENT_ID + "=?", new String[]{ - folderId - }, null); + 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 { - // 打印笔记的最后修改日期 + // 输出笔记的修改时间 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()); @@ -223,218 +180,100 @@ public class BackupUtils { } } - /** - * 将指定id的笔记导出到打印流中 + * 导出指定笔记 ID 的内容到文本。 * - * @param noteId 笔记的id - * @param ps 打印流,用于输出笔记内容 + * @param noteId 笔记 ID。 + * @param ps 打印流。 */ private void exportNoteToText(String noteId, PrintStream ps) { - // 查询指定id的笔记数据 - Cursor dataCursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, - DATA_PROJECTION, DataColumns.NOTE_ID + "=?", new String[]{ - noteId - }, null); + 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)) { - // 处理通话记录类型的笔记 - 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)); - } + // 导出通话笔记 } 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(); } - // 在每个笔记内容之间打印一行分隔符 - try { - ps.write(new byte[]{ - Character.LINE_SEPARATOR, Character.LETTER_NUMBER - }); - } catch (IOException e) { - Log.e(TAG, e.toString()); - } } /** - * 将所有笔记以文本格式导出 + * 获取指向文件的打印流,用于导出笔记内容。 * - * @return 导出操作的状态码,成功返回STATE_SUCCESS,否则返回其他错误状态码 + * @return 返回指向生成的文本文件的打印流对象,如果失败则返回 null。 */ - 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; - } - - // 首先导出文件夹及其包含的笔记 - 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 { - // 打印文件夹名称 - 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(); + 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; // 返回 null,表示打印流创建失败 } + // 更新文件名和目录信息 + mFileName = file.getName(); // 设置文件名 + mFileDirectory = mContext.getString(R.string.file_path); // 设置文件目录 - // 导出根文件夹中的笔记 - 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)))); - // 导出笔记内容 - String noteId = noteCursor.getString(NOTE_COLUMN_ID); - exportNoteToText(noteId, ps); - } while (noteCursor.moveToNext()); - } - noteCursor.close(); + PrintStream ps = null; // 初始化打印流为 null + try { + // 创建文件输出流并包装为打印流 + FileOutputStream fos = new FileOutputStream(file); + ps = new PrintStream(fos); + } catch (FileNotFoundException e) { // 捕获文件未找到异常 + e.printStackTrace(); + return null; // 返回 null,表示打印流创建失败 + } catch (NullPointerException e) { // 捕获空指针异常 + e.printStackTrace(); + return null; // 返回 null } - ps.close(); - - return STATE_SUCCESS; + return ps; // 返回成功创建的打印流对象 } - /** - * 获取指向文件{@generateExportedTextFile}的打印流 - * 该方法尝试在SD卡上生成一个指定格式的文本文件,并返回指向该文件的PrintStream对象。 - * 如果文件生成失败,则返回null。 + * 在 SD 卡上生成用于存储导出数据的文件。 * - * @return PrintStream 指向生成的文本文件的打印流,如果失败则返回null。 + * @param context 上下文对象,用于访问应用资源。 + * @param filePathResId 文件路径的资源 ID。 + * @param fileNameFormatResId 文件名格式的资源 ID,用于生成包含日期的文件名。 + * @return 返回生成的文件对象,如果失败则返回 null。 */ - 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); + private static File generateFileMountedOnSDcard(Context context, int filePathResId, int fileNameFormatResId) { + StringBuilder sb = new StringBuilder(); // 使用 StringBuilder 拼接路径和文件名 + + // 获取 SD 卡的根目录并拼接路径 + 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()); // 创建文件对象 - PrintStream ps = null; try { - FileOutputStream fos = new FileOutputStream(file); // 创建文件输出流 - ps = new PrintStream(fos); // 将文件输出流包装成PrintStream - } catch (FileNotFoundException e) { + if (!filedir.exists()) { // 如果目录不存在 + filedir.mkdir(); // 创建目录 + } + if (!file.exists()) { // 如果文件不存在 + file.createNewFile(); // 创建文件 + } + return file; // 返回成功生成的文件对象 + } catch (SecurityException e) { // 捕获安全异常 e.printStackTrace(); - return null; // 文件未找到异常,返回null - } catch (NullPointerException e) { + } catch (IOException e) { // 捕获 I/O 异常 e.printStackTrace(); - return null; // 空指针异常,返回null } - return ps; // 返回PrintStream对象 + return null; // 如果发生异常,返回 null } - } - - /** - * 在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(); - // 拼接SD卡的根目录 - sb.append(Environment.getExternalStorageDirectory()); - // 拼接从资源id获取的路径字符串 - 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(); - } - - // 如果遇到异常,返回null - return null; - } - } diff --git a/src/DataUtils.java b/src/DataUtils.java index 4149710..977ad28 100644 --- a/src/DataUtils.java +++ b/src/DataUtils.java @@ -1,21 +1,12 @@ /* * 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. + * Licensed under the Apache License, Version 2.0 + * 该文件定义了用于管理和操作笔记数据的实用工具类 DataUtils。 */ -package net.micode.notes.tool; +package net.micode.notes.tool; // 声明该类所属的包路径 +// 导入需要的类,用于操作内容提供器、数据库、日志和其他功能 import android.content.ContentProviderOperation; import android.content.ContentProviderResult; import android.content.ContentResolver; @@ -26,17 +17,17 @@ 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; +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; // 用于存储无重复的集合 +// 定义 DataUtils 工具类 public class DataUtils { - public static final String TAG = "DataUtils"; + public static final String TAG = "DataUtils"; // 定义日志标记常量 /** * 批量删除笔记 @@ -46,40 +37,41 @@ public class DataUtils { * @return 如果删除成功或集合为空或为null,则返回true,否则返回false */ public static boolean batchDeleteNotes(ContentResolver resolver, HashSet ids) { - if (ids == null) { - Log.d(TAG, "the ids is null"); - return true; + if (ids == null) { // 如果传入的ID集合为null + Log.d(TAG, "the ids is null"); // 输出调试日志 + return true; // 返回true,表示没有需要删除的内容 } - if (ids.size() == 0) { - Log.d(TAG, "no id is in the hashset"); - return true; + if (ids.size() == 0) { // 如果ID集合为空 + Log.d(TAG, "no id is in the hashset"); // 输出调试日志 + return true; // 返回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; + for (long id : ids) { // 遍历需要删除的ID集合 + if (id == Notes.ID_ROOT_FOLDER) { // 如果ID是系统根文件夹 + Log.e(TAG, "Don't delete system folder root"); // 输出错误日志 + continue; // 跳过此ID } + // 创建删除操作 ContentProviderOperation.Builder builder = ContentProviderOperation .newDelete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id)); - operationList.add(builder.build()); + 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; + if (results == null || results.length == 0 || results[0] == null) { // 检查删除结果 + Log.d(TAG, "delete notes failed, ids:" + ids.toString()); // 输出调试日志 + return false; // 删除失败,返回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 true; // 删除成功,返回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; + return false; // 出现异常时,返回false } /** @@ -91,10 +83,11 @@ public class DataUtils { * @param desFolderId 目标文件夹ID */ 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); + ContentValues values = new ContentValues(); // 创建一个ContentValues对象 + values.put(NoteColumns.PARENT_ID, desFolderId); // 设置目标文件夹ID + values.put(NoteColumns.ORIGIN_PARENT_ID, srcFolderId); // 设置原始文件夹ID + values.put(NoteColumns.LOCAL_MODIFIED, 1); // 标记为本地已修改 + // 更新指定笔记的文件夹信息 resolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), values, null, null); } @@ -106,37 +99,37 @@ public class DataUtils { * @param folderId 目标文件夹ID * @return 如果移动成功或集合为空或为null,则返回true,否则返回false */ - public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids, - long folderId) { - if (ids == null) { - Log.d(TAG, "the ids is null"); - return true; + public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids, long folderId) { + if (ids == null) { // 如果ID集合为null + Log.d(TAG, "the ids is null"); // 输出调试日志 + return true; // 返回true } // 构建更新操作的列表 ArrayList operationList = new ArrayList(); - for (long id : ids) { + for (long id : ids) { // 遍历ID集合 + // 创建更新操作 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()); + builder.withValue(NoteColumns.PARENT_ID, folderId); // 设置目标文件夹ID + 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, "move notes failed, ids:" + ids.toString()); - return false; + if (results == null || results.length == 0 || results[0] == null) { // 检查操作结果 + Log.d(TAG, "move 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 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; + return false; // 出现异常时,返回false } /** @@ -146,28 +139,29 @@ public class DataUtils { * @return 用户文件夹数量 */ 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); + 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()) { + 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()); + count = cursor.getInt(0); // 获取计数值 + } catch (IndexOutOfBoundsException e) { // 捕获索引越界异常 + Log.e(TAG, "get folder count failed:" + e.toString()); // 输出错误日志 } finally { - cursor.close(); + cursor.close(); // 关闭游标 } } } - return count; + return count; // 返回文件夹数量 } - - /** +} + /** * 检查指定类型的笔记在数据库中是否可见 * * @param resolver 内容解析器 @@ -176,20 +170,21 @@ public class DataUtils { * @return 如果可见,则返回true,否则返回false */ 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); + // 查询数据库,检查指定类型的笔记是否存在且不在垃圾箱中 + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), // 查询的URI + null, // 查询的列,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; + boolean exist = false; // 初始化结果为false + if (cursor != null) { // 如果查询结果不为空 + if (cursor.getCount() > 0) { // 如果查询结果有记录 + exist = true; // 设置结果为true } - cursor.close(); + cursor.close(); // 关闭游标 } - return exist; + return exist; // 返回结果 } /** @@ -200,17 +195,21 @@ public class DataUtils { * @return 如果存在,则返回true,否则返回false */ public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) { - Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), - null, null, null, null); + // 查询数据库,检查笔记是否存在 + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), // 查询的URI + null, // 查询所有列 + null, // 无条件 + null, // 无条件值 + null); // 无排序 - boolean exist = false; - if (cursor != null) { - if (cursor.getCount() > 0) { - exist = true; + boolean exist = false; // 初始化结果为false + if (cursor != null) { // 如果查询结果不为空 + if (cursor.getCount() > 0) { // 如果查询结果有记录 + exist = true; // 设置结果为true } - cursor.close(); + cursor.close(); // 关闭游标 } - return exist; + return exist; // 返回结果 } /** @@ -221,17 +220,21 @@ public class DataUtils { * @return 如果存在,则返回true,否则返回false */ public static boolean existInDataDatabase(ContentResolver resolver, long dataId) { - Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), - null, null, null, null); + // 查询数据库,检查数据是否存在 + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), // 查询的URI + null, // 查询所有列 + null, // 无条件 + null, // 无条件值 + null); // 无排序 - boolean exist = false; - if (cursor != null) { - if (cursor.getCount() > 0) { - exist = true; + boolean exist = false; // 初始化结果为false + if (cursor != null) { // 如果查询结果不为空 + if (cursor.getCount() > 0) { // 如果查询结果有记录 + exist = true; // 设置结果为true } - cursor.close(); + cursor.close(); // 关闭游标 } - return exist; + return exist; // 返回结果 } /** @@ -242,19 +245,23 @@ public class DataUtils { * @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 + "=?", - new String[]{name}, null); - boolean exist = false; - if (cursor != null) { - if (cursor.getCount() > 0) { - exist = true; + // 查询数据库,检查文件夹名称是否存在且不在垃圾箱中 + Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, // 查询的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; // 初始化结果为false + if (cursor != null) { // 如果查询结果不为空 + if (cursor.getCount() > 0) { // 如果查询结果有记录 + exist = true; // 设置结果为true } - cursor.close(); + cursor.close(); // 关闭游标 } - return exist; + return exist; // 返回结果 } /** @@ -265,33 +272,35 @@ public class DataUtils { * @return 笔记小部件信息集合 */ 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); + // 查询数据库,获取文件夹中的小部件信息 + Cursor c = resolver.query(Notes.CONTENT_NOTE_URI, // 查询的URI + new String[]{NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE}, // 查询的列 + NoteColumns.PARENT_ID + "=?", // 条件:父ID为指定文件夹 + new String[]{String.valueOf(folderId)}, // 条件值 + null); // 无排序 - HashSet set = null; - if (c != null) { - if (c.moveToFirst()) { - set = new HashSet(); - do { + HashSet set = null; // 初始化小部件集合为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()); + AppWidgetAttribute widget = new AppWidgetAttribute(); // 创建小部件属性对象 + widget.widgetId = c.getInt(0); // 获取小部件ID + widget.widgetType = c.getInt(1); // 获取小部件类型 + set.add(widget); // 将小部件添加到集合 + } catch (IndexOutOfBoundsException e) { // 捕获索引越界异常 + Log.e(TAG, e.toString()); // 输出错误日志 } - } while (c.moveToNext()); + } while (c.moveToNext()); // 移动到下一条记录 } - c.close(); + c.close(); // 关闭游标 } - return set; + return set; // 返回小部件集合 } - /** + + /** * 通过笔记ID获取关联的通话号码 * * @param resolver 内容解析器 @@ -299,22 +308,23 @@ public class DataUtils { * @return 通话号码,如果未找到则返回空字符串 */ 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); + // 查询数据库,获取与笔记ID关联的通话号码 + Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, // 查询的URI + new String[]{CallNote.PHONE_NUMBER}, // 查询的列:电话号码 + CallNote.NOTE_ID + "=? AND " + CallNote.MIME_TYPE + "=?", // 条件:匹配笔记ID和MIME类型 + new String[]{String.valueOf(noteId), CallNote.CONTENT_ITEM_TYPE}, // 条件值 + null); // 无排序 - if (cursor != null && cursor.moveToFirst()) { + if (cursor != null && cursor.moveToFirst()) { // 如果查询结果不为空且有记录 try { - return cursor.getString(0); - } catch (IndexOutOfBoundsException e) { - Log.e(TAG, "Get call number fails " + e.toString()); + return cursor.getString(0); // 返回查询结果中的电话号码 + } catch (IndexOutOfBoundsException e) { // 捕获索引越界异常 + Log.e(TAG, "Get call number fails " + e.toString()); // 输出错误日志 } finally { - cursor.close(); + cursor.close(); // 关闭游标 } } - return ""; + return ""; // 未找到记录时返回空字符串 } /** @@ -326,71 +336,71 @@ public class DataUtils { * @return 笔记ID,未找到则返回0 */ public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) { - Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, - new String[]{CallNote.NOTE_ID}, + // 查询数据库,根据电话号码和通话日期获取笔记ID + Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI, // 查询的URI + new String[]{CallNote.NOTE_ID}, // 查询的列:笔记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); + + CallNote.PHONE_NUMBER + ",?)", // 条件:匹配通话日期、MIME类型和电话号码 + new String[]{String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber}, // 条件值 + null); // 无排序 - if (cursor != null) { - if (cursor.moveToFirst()) { + if (cursor != null) { // 如果查询结果不为空 + if (cursor.moveToFirst()) { // 如果有记录 try { - return cursor.getLong(0); - } catch (IndexOutOfBoundsException e) { - Log.e(TAG, "Get call note id fails " + e.toString()); + return cursor.getLong(0); // 返回笔记ID + } catch (IndexOutOfBoundsException e) { // 捕获索引越界异常 + Log.e(TAG, "Get call note id fails " + e.toString()); // 输出错误日志 } } - cursor.close(); + cursor.close(); // 关闭游标 } - return 0; + return 0; // 未找到记录时返回0 } /** - * 根据笔记ID从数据库中获取笔记的摘要。 + * 根据笔记ID从数据库中获取笔记的摘要 * - * @param resolver 内容解析器,用于查询数据库。 - * @param noteId 笔记的ID,用于定位特定的笔记。 + * @param resolver 内容解析器 + * @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 + "=?", - new String[]{String.valueOf(noteId)}, - null); + // 查询数据库,获取指定ID笔记的摘要 + Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, // 查询的URI + new String[]{NoteColumns.SNIPPET}, // 查询的列:摘要 + NoteColumns.ID + "=?", // 条件:匹配笔记ID + new String[]{String.valueOf(noteId)}, // 条件值 + null); // 无排序 - if (cursor != null) { - String snippet = ""; - // 如果查询结果不为空,尝试获取摘要 - if (cursor.moveToFirst()) { - snippet = cursor.getString(0); + if (cursor != null) { // 如果查询结果不为空 + String snippet = ""; // 初始化摘要为空字符串 + if (cursor.moveToFirst()) { // 如果有记录 + snippet = cursor.getString(0); // 获取摘要字符串 } - // 关闭游标 - cursor.close(); - return snippet; + cursor.close(); // 关闭游标 + return snippet; // 返回摘要 } - // 如果找不到指定ID的笔记,抛出异常 + // 如果未找到记录,抛出异常 throw new IllegalArgumentException("Note is not found with id: " + noteId); } /** - * 格式化摘要字符串。 + * 格式化摘要字符串 * 主要用于去除字符串两端的空白字符,以及截取至第一个换行符之前的内容。 * - * @param snippet 需要格式化的摘要字符串。 - * @return 格式化后的摘要字符串。 + * @param snippet 需要格式化的摘要字符串 + * @return 格式化后的摘要字符串 */ 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); // 截取至第一个换行符之前 + if (index != -1) { // 如果存在换行符 + snippet = snippet.substring(0, index); // 截取至第一个换行符之前的内容 } } - return snippet; + return snippet; // 返回格式化后的摘要字符串 } } + diff --git a/src/GTaskStringUtils.java b/src/GTaskStringUtils.java index ea29672..c1b42bf 100644 --- a/src/GTaskStringUtils.java +++ b/src/GTaskStringUtils.java @@ -1,26 +1,26 @@ /* * GTaskStringUtils 类定义 - * 该类提供了一系列与GTask相关的字符串常量,用于在操作GTask数据时标识各种JSON属性。 + * 该类提供了一系列与 GTask 相关的字符串常量,用于在操作 GTask 数据时标识各种 JSON 属性。 */ +package net.micode.notes.tool; // 定义该类所在的包路径 -package net.micode.notes.tool; - +// 定义 GTaskStringUtils 类 public class GTaskStringUtils { - // GTask JSON对象中各种属性的键名 - public final static String GTASK_JSON_ACTION_ID = "action_id"; // 动作ID + // GTask JSON 对象中各种属性的键名 + public final static String GTASK_JSON_ACTION_ID = "action_id"; // 动作 ID public final static String GTASK_JSON_ACTION_LIST = "action_list"; // 动作列表 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"; // 更新动作类型 - public final static String GTASK_JSON_CREATOR_ID = "creator_id"; // 创建者ID + public final static String GTASK_JSON_CREATOR_ID = "creator_id"; // 创建者 ID public final static String GTASK_JSON_CHILD_ENTITY = "child_entity"; // 子实体 public final static String GTASK_JSON_CLIENT_VERSION = "client_version"; // 客户端版本 public final static String GTASK_JSON_COMPLETED = "completed"; // 完成状态 - public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id"; // 当前列表ID - public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id"; // 默认列表ID + public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id"; // 当前列表 ID + public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id"; // 默认列表 ID public final static String GTASK_JSON_DELETED = "deleted"; // 删除状态 public final static String GTASK_JSON_DEST_LIST = "dest_list"; // 目标列表 public final static String GTASK_JSON_DEST_PARENT = "dest_parent"; // 目标父实体 @@ -32,13 +32,13 @@ public class GTaskStringUtils { public final static String GTASK_JSON_INDEX = "index"; // 索引 public final static String GTASK_JSON_LAST_MODIFIED = "last_modified"; // 最后修改时间 public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point"; // 最新同步点 - public final static String GTASK_JSON_LIST_ID = "list_id"; // 列表ID + public final static String GTASK_JSON_LIST_ID = "list_id"; // 列表 ID public final static String GTASK_JSON_LISTS = "lists"; // 列表集合 public final static String GTASK_JSON_NAME = "name"; // 名称 - public final static String GTASK_JSON_NEW_ID = "new_id"; // 新ID + public final static String GTASK_JSON_NEW_ID = "new_id"; // 新 ID public final static String GTASK_JSON_NOTES = "notes"; // 备注 - public final static String GTASK_JSON_PARENT_ID = "parent_id"; // 父ID - public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id"; // 前一个兄弟ID + public final static String GTASK_JSON_PARENT_ID = "parent_id"; // 父 ID + public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id"; // 前一个兄弟 ID public final static String GTASK_JSON_RESULTS = "results"; // 结果 public final static String GTASK_JSON_SOURCE_LIST = "source_list"; // 源列表 public final static String GTASK_JSON_TASKS = "tasks"; // 任务集合 @@ -46,15 +46,18 @@ public class GTaskStringUtils { public final static String GTASK_JSON_TYPE_GROUP = "GROUP"; // 类型:组 public final static String GTASK_JSON_TYPE_TASK = "TASK"; // 类型:任务 public final static String GTASK_JSON_USER = "user"; // 用户 - // MIUI笔记相关的文件夹前缀和元数据键名 - public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]"; // MIUI笔记文件夹前缀 + + // MIUI 笔记相关的文件夹前缀和元数据键名 + public final static String MIUI_FOLDER_PREFFIX = "[MIUI_Notes]"; // MIUI 笔记文件夹前缀 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"; // GTask ID - public final static String META_HEAD_NOTE = "meta_note"; // 笔记内容 - public final static String META_HEAD_DATA = "meta_data"; // 元数据 + public final static String META_HEAD_GTASK_ID = "meta_gid"; // 元数据头部:GTask ID + 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"; + public final static String META_NOTE_NAME = "[META INFO] DON'T UPDATE AND DELETE"; // 不可更新和删除的元数据名称 } diff --git a/src/NoteWidgetProvider.java b/src/NoteWidgetProvider.java deleted file mode 100644 index 898de0a..0000000 --- a/src/NoteWidgetProvider.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 注意:此代码段的版权归 MiCode 开源社区所有(www.micode.net) - * 本代码遵循 Apache 2.0 许可证,您可以在 http://www.apache.org/licenses/LICENSE-2.0 查看许可证内容。 - */ - -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; - -/** - * 笔记小部件提供者抽象类,扩展自AppWidgetProvider,用于管理和更新笔记小部件的内容。 - */ -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"; - - /** - * 当小部件被删除时调用,更新数据库中对应小部件的ID为无效ID。 - */ - @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])}); - } - } - - /** - * 根据小部件ID查询对应的笔记信息。 - * - * @param context 上下文 - * @param widgetId 小部件ID - * @return 返回查询到的Cursor对象,包含笔记的摘要、背景ID等信息。 - */ - 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); - } - - /** - * 更新小部件显示内容的通用方法。 - * - * @param context 上下文 - * @param appWidgetManager AppWidget管理器 - * @param appWidgetIds 小部件ID数组 - */ - protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { - update(context, appWidgetManager, appWidgetIds, false); - } - - /** - * 根据是否隐私模式更新小部件显示内容。 - * - * @param context 上下文 - * @param appWidgetManager AppWidget管理器 - * @param appWidgetIds 小部件ID数组 - * @param privacyMode 是否为隐私模式 - */ - 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); - - // 为小部件的点击事件设置PendingIntent - 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); - } - } - } - - /** - * 获取背景资源的ID。 - * - * @param bgId 背景ID - * @return 返回对应的资源ID - */ - protected abstract int getBgResourceId(int bgId); - - /** - * 获取小部件布局的ID。 - * - * @return 返回布局的资源ID - */ - protected abstract int getLayoutId(); - - /** - * 获取小部件的类型。 - * - * @return 返回小部件的类型 - */ - protected abstract int getWidgetType(); -} - diff --git a/src/Notes.java b/src/Notes.java deleted file mode 100644 index 226763b..0000000 --- a/src/Notes.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * 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; - -// Notes类定义了与笔记和文件夹相关的常量和数据列接口 -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; // 系统类型 - - /** - * 下面的ID是系统文件夹的标识符 - * {@link Notes#ID_ROOT_FOLDER} 是默认文件夹 - * {@link Notes#ID_TEMPARAY_FOLDER} 是属于没有文件夹的笔记 - * {@link Notes#ID_CALL_RECORD_FOLDER} 是用于存储通话记录的 - */ - public static final int ID_ROOT_FOLDER = 0; // 根文件夹ID - public static final int ID_TEMPARAY_FOLDER = -1; // 临时文件夹ID,用于存放不属于任何文件夹的笔记 - public static final int ID_CALL_RECORD_FOLDER = -2; // 通话记录文件夹ID - public static final int ID_TRASH_FOLER = -3; // 垃圾箱文件夹ID - - public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date"; // 用于Intent的提醒日期额外数据 - public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id"; // 笔记背景色ID - public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id"; // 小部件ID - public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type"; // 小部件类型 - public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id"; // 文件夹ID - public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date"; // 通话日期 - - public static final int TYPE_WIDGET_INVALIDE = -1; // 无效的小部件类型 - public static final int TYPE_WIDGET_2X = 0; // 2x小部件类型 - public static final int TYPE_WIDGET_4X = 1; // 4x小部件类型 - - public static class DataConstants { - public static final String NOTE = TextNote.CONTENT_ITEM_TYPE; // 笔记的内容项类型 - public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE; // 通话记录的内容项类型 - } - - /** - * 查询所有笔记和文件夹的Uri - */ - public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note"); - - /** - * 查询数据的Uri - */ - public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data"); - - // 笔记和文件夹的公共列接口 - public interface NoteColumns { - /** - * 行的唯一ID - *

类型: INTEGER (long)

- */ - public static final String ID = "_id"; - - /** - * 笔记或文件夹的父ID - *

类型: INTEGER (long)

- */ - public static final String PARENT_ID = "parent_id"; - - /** - * 创建日期 - *

类型: INTEGER (long)

- */ - public static final String CREATED_DATE = "created_date"; - - /** - * 最后修改日期 - *

类型: INTEGER (long)

- */ - public static final String MODIFIED_DATE = "modified_date"; - - /** - * 提醒日期 - *

类型: INTEGER (long)

- */ - public static final String ALERTED_DATE = "alert_date"; - - /** - * 笔记或文件夹的摘要信息 - *

类型: TEXT

- */ - public static final String SNIPPET = "snippet"; - - /** - * 笔记的小部件ID - *

类型: INTEGER (long)

- */ - public static final String WIDGET_ID = "widget_id"; - - /** - * 笔记的小部件类型 - *

类型: INTEGER (long)

- */ - public static final String WIDGET_TYPE = "widget_type"; - - /** - * 笔记的背景色ID - *

类型: INTEGER (long)

- */ - public static final String BG_COLOR_ID = "bg_color_id"; - - /** - * 笔记是否有附件 - *

类型: INTEGER

- */ - public static final String HAS_ATTACHMENT = "has_attachment"; - - /** - * 笔记数量 - *

类型: INTEGER (long)

- */ - public static final String NOTES_COUNT = "notes_count"; - - /** - * 文件夹类型:0-笔记,1-文件夹 - *

类型: INTEGER

- */ - public static final String TYPE = "type"; - - /** - * 最后同步ID - *

类型: INTEGER (long)

- */ - public static final String SYNC_ID = "sync_id"; - - /** - * 标记本地是否已修改 - *

类型: INTEGER

- */ - public static final String LOCAL_MODIFIED = "local_modified"; - - /** - * 移入临时文件夹前的原始父ID - *

类型: INTEGER

- */ - public static final String ORIGIN_PARENT_ID = "origin_parent_id"; - - /** - * Google任务ID - *

类型: TEXT

- */ - public static final String GTASK_ID = "gtask_id"; - - /** - * 版本号 - *

类型: INTEGER (long)

- */ - public static final String VERSION = "version"; - } - - // 数据列接口 - public interface DataColumns { - /** - * 行的唯一ID - *

类型: INTEGER (long)

- */ - public static final String ID = "_id"; - - /** - * 该项的MIME类型。 - *

类型: TEXT

- */ - public static final String MIME_TYPE = "mime_type"; - - /** - * 属于的笔记的引用ID - *

类型: INTEGER (long)

- */ - public static final String NOTE_ID = "note_id"; - - /** - * 创建日期 - *

类型: INTEGER (long)

- */ - public static final String CREATED_DATE = "created_date"; - - /** - * 最后修改日期 - *

类型: INTEGER (long)

- */ - public static final String MODIFIED_DATE = "modified_date"; - - /** - * 数据内容 - *

类型: TEXT

- */ - public static final String CONTENT = "content"; - - /** - * 通用数据列,具体含义由{@link #MIME_TYPE}决定,用于存储整型数据 - *

类型: INTEGER

- */ - public static final String DATA1 = "data1"; - - /** - * 通用数据列,具体含义由{@link #MIME_TYPE}决定,用于存储整型数据 - *

类型: INTEGER

- */ - public static final String DATA2 = "data2"; - - /** - * 通用数据列,具体含义由{@link #MIME_TYPE}决定,用于存储文本数据 - *

类型: TEXT

- */ - public static final String DATA3 = "data3"; - - /** - * 通用数据列,具体含义由{@link #MIME_TYPE}决定,用于存储文本数据 - *

类型: TEXT

- */ - public static final String DATA4 = "data4"; - - /** - * 通用数据列,具体含义由{@link #MIME_TYPE}决定,用于存储文本数据 - *

类型: TEXT

- */ - public static final String DATA5 = "data5"; - } - - // 文本笔记类,实现了DataColumns接口 - public static final class TextNote implements DataColumns { - /** - * 模式,指示文本是否在检查列表模式中 - *

类型: INTEGER 1:检查列表模式 0: 正常模式

- */ - 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"; // MIME类型定义 - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note"; // 单项MIME类型定义 - public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note"); // 内容URI定义 - } - - // 通话记录笔记类,实现了DataColumns接口 - public static final class CallNote implements DataColumns { - /** - * 通话日期 - *

类型: INTEGER (long)

- */ - public static final String CALL_DATE = DATA1; - - /** - * 电话号码 - *

类型: TEXT

- */ - public static final String PHONE_NUMBER = DATA3; - - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note"; // MIME类型定义 - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note"; // 单项MIME类型定义 - public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note"); // 内容URI定义 - } -} diff --git a/src/ResourceParser.java b/src/ResourceParser.java index 432187c..8a4f353 100644 --- a/src/ResourceParser.java +++ b/src/ResourceParser.java @@ -1,32 +1,34 @@ /* * ResourceParser 类用于管理与应用资源相关的各种静态方法和常量。 */ - package net.micode.notes.tool; +// 导入 Android 的 Context 和 PreferenceManager 类,用于访问应用的上下文和首选项 import android.content.Context; import android.preference.PreferenceManager; +// 导入应用资源和偏好设置相关的类 import net.micode.notes.R; import net.micode.notes.ui.NotesPreferenceActivity; +// 定义 ResourceParser 类 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 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 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; @@ -37,20 +39,20 @@ public class ResourceParser { 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 + 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 + 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获取编辑状态下的背景资源 @@ -71,10 +73,13 @@ public class ResourceParser { * @return 如果用户设置了背景颜色,则返回一个随机背景颜色id;否则返回默认背景颜色id。 */ public static int getDefaultBgId(Context context) { + // 检查用户是否在设置中启用了背景颜色选项 if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean( NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { + // 返回一个随机背景颜色id return (int) (Math.random() * NoteBgResources.BG_EDIT_RESOURCES.length); } else { + // 返回默认背景颜色id return BG_DEFAULT_COLOR; } } @@ -85,38 +90,38 @@ public class ResourceParser { 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 + 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 + 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, + 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 + 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 // 红色单项背景 }; // 获取第一个列表项的背景资源 @@ -151,11 +156,11 @@ public class ResourceParser { public static class WidgetBgResources { // 2x 小部件背景资源数组 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, + R.drawable.widget_2x_yellow, // 黄色2x小部件背景 + R.drawable.widget_2x_blue, // 蓝色2x小部件背景 + R.drawable.widget_2x_white, // 白色2x小部件背景 + R.drawable.widget_2x_green, // 绿色2x小部件背景 + R.drawable.widget_2x_red // 红色2x小部件背景 }; // 根据id获取2x小部件的背景资源 @@ -165,11 +170,11 @@ public class ResourceParser { // 4x 小部件背景资源数组 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 + R.drawable.widget_4x_yellow, // 黄色4x小部件背景 + R.drawable.widget_4x_blue, // 蓝色4x小部件背景 + R.drawable.widget_4x_white, // 白色4x小部件背景 + R.drawable.widget_4x_green, // 绿色4x小部件背景 + R.drawable.widget_4x_red // 红色4x小部件背景 }; // 根据id获取4x小部件的背景资源 @@ -184,10 +189,10 @@ public class ResourceParser { public static class TextAppearanceResources { // 文本外观资源数组 private final static int[] TEXTAPPEARANCE_RESOURCES = new int[]{ - R.style.TextAppearanceNormal, - R.style.TextAppearanceMedium, - R.style.TextAppearanceLarge, - R.style.TextAppearanceSuper + R.style.TextAppearanceNormal, // 正常文本样式 + R.style.TextAppearanceMedium, // 中等文本样式 + R.style.TextAppearanceLarge, // 大号文本样式 + R.style.TextAppearanceSuper // 特大号文本样式 }; // 根据id获取文本外观资源 @@ -205,4 +210,3 @@ public class ResourceParser { } } } -