From dd9e7bf58e243eff94758c47bff81823b7ceaa8e Mon Sep 17 00:00:00 2001 From: Wangranran <3587345858@qq.com> Date: Wed, 25 Dec 2024 16:53:57 +0800 Subject: [PATCH 1/4] 1 --- AlarmAlertActivity.txt | 164 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 AlarmAlertActivity.txt diff --git a/AlarmAlertActivity.txt b/AlarmAlertActivity.txt new file mode 100644 index 0000000..4cd4959 --- /dev/null +++ b/AlarmAlertActivity.txt @@ -0,0 +1,164 @@ + +/** + * 闹钟提醒活动类,用于处理便签的闹钟提醒。 + */ +public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { + // 便签ID + private long mNoteId; + // 便签摘要 + private String mSnippet; + // 摘要预览的最大长度 + private static final int SNIPPET_PREW_MAX_LEN = 60; + // 媒体播放器,用于播放闹钟声音 + MediaPlayer mPlayer; + + /** + * 当活动创建时调用。 + * @param savedInstanceState 保存的实例状态 + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // 请求无标题窗口特性 + requestWindowFeature(Window.FEATURE_NO_TITLE); + + // 获取窗口对象 + final Window win = getWindow(); + // 设置窗口在锁屏时显示 + win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); + + // 检查屏幕是否开启,如果未开启则点亮屏幕并保持唤醒状态 + if (!isScreenOn()) { + win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON + | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); + } + + // 获取启动活动的Intent + Intent intent = getIntent(); + + try { + // 从Intent中获取便签ID + mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); + // 获取便签摘要 + mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); + // 如果摘要超过预览长度,则截断并添加提示 + mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, + SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) + : mSnippet; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + return; + } + + // 创建媒体播放器 + mPlayer = new MediaPlayer(); + // 如果便签可见,则显示操作对话框并播放闹钟声音 + if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { + showActionDialog(); + playAlarmSound(); + } else { + // 如果便签不可见,则结束活动 + finish(); + } + } + + /** + * 检查屏幕是否开启。 + * @return 如果屏幕开启返回true,否则返回false。 + */ + private boolean isScreenOn() { + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + return pm.isScreenOn(); + } + + /** + * 播放闹钟声音。 + */ + private void playAlarmSound() { + // 获取默认闹钟铃声的Uri + Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); + + // 获取静音模式影响的流类型 + int silentModeStreams = Settings.System.getInt(getContentResolver(), + Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); + + // 设置媒体播放器的音频流类型 + if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { + mPlayer.setAudioStreamType(silentModeStreams); + } else { + mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); + } + try { + // 设置数据源并准备播放 + mPlayer.setDataSource(this, url); + mPlayer.prepare(); + mPlayer.setLooping(true); + mPlayer.start(); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalStateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 显示操作对话框。 + */ + private void showActionDialog() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle(R.string.app_name); + dialog.setMessage(mSnippet); + dialog.setPositiveButton(R.string.notealert_ok, this); + // 如果屏幕开启,则添加“进入”按钮 + if (isScreenOn()) { + dialog.setNegativeButton(R.string.notealert_enter, this); + } + dialog.show().setOnDismissListener(this); + } + + /** + * 点击对话框按钮时调用。 + * @param dialog 对话框 + * @param which 按钮类型 + */ + public void onClick(DialogInterface dialog, int which) { + switch (which) { + case DialogInterface.BUTTON_NEGATIVE: + // 启动便签编辑活动 + Intent intent = new Intent(this, NoteEditActivity.class); + intent.setAction(Intent.ACTION_VIEW); + intent.putExtra(Intent.EXTRA_UID, mNoteId); + startActivity(intent); + break; + default: + break; + } + } + + /** + * 对话框消失时调用。 + * @param dialog 对话框 + */ + public void onDismiss(DialogInterface dialog) { + stopAlarmSound(); + finish(); + } + + /** + * 停止闹钟声音。 + */ + private void stopAlarmSound() { + if (mPlayer != null) { + mPlayer.stop(); + mPlayer.release(); + mPlayer = null; + } + } +} + From cfd03611989aec308bb74de99ac44233bd248f72 Mon Sep 17 00:00:00 2001 From: Wangranran <3587345858@qq.com> Date: Wed, 25 Dec 2024 16:54:38 +0800 Subject: [PATCH 2/4] 2 --- AlarmInitReceiver.txt | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 AlarmInitReceiver.txt diff --git a/AlarmInitReceiver.txt b/AlarmInitReceiver.txt new file mode 100644 index 0000000..6c05ad6 --- /dev/null +++ b/AlarmInitReceiver.txt @@ -0,0 +1,52 @@ + +/** + * 闹钟初始化接收器,用于设置便签的闹钟提醒。 + */ +public class AlarmInitReceiver extends BroadcastReceiver { + + // 查询字段 + private static final String [] PROJECTION = new String [] { + NoteColumns.ID, // 便签ID + NoteColumns.ALERTED_DATE // 便签的提醒日期 + }; + + // 查询字段对应的列索引 + private static final int COLUMN_ID = 0; + private static final int COLUMN_ALERTED_DATE = 1; + + /** + * 接收到广播时调用。 + * @param context 上下文对象 + * @param intent 广播时传递的Intent + */ + @Override + public void onReceive(Context context, Intent intent) { + // 获取当前日期 + long currentDate = System.currentTimeMillis(); + // 查询所有未提醒且类型为便签的便签项 + Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, + PROJECTION, + NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, + new String[] { String.valueOf(currentDate) }, + null); + + if (c != null) { + if (c.moveToFirst()) { + // 遍历查询结果,为每个便签设置闹钟 + do { + long alertDate = c.getLong(COLUMN_ALERTED_DATE); + Intent sender = new Intent(context, AlarmReceiver.class); + // 设置闹钟接收器的数据,以便知道是哪个便签需要提醒 + sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); + AlarmManager alermManager = (AlarmManager) context + .getSystemService(Context.ALARM_SERVICE); + // 设置闹钟,使用RTC_WAKEUP模式确保设备在提醒时间被唤醒 + alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); + } while (c.moveToNext()); + } + c.close(); + } + } +} + From d0950b34838c255a19db7cde783ed89aa4a9b9c8 Mon Sep 17 00:00:00 2001 From: Wangranran <3587345858@qq.com> Date: Wed, 25 Dec 2024 17:07:44 +0800 Subject: [PATCH 3/4] 1 --- AlarmReceiver.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 AlarmReceiver.txt diff --git a/AlarmReceiver.txt b/AlarmReceiver.txt new file mode 100644 index 0000000..49f89ad --- /dev/null +++ b/AlarmReceiver.txt @@ -0,0 +1,24 @@ + +/** + * 闹钟接收器,用于处理闹钟提醒的广播。 + */ +public class AlarmReceiver extends BroadcastReceiver { + + /** + * 接收到广播时调用。 + * @param context 上下文对象,提供了与应用程序交互的信息。 + * @param intent 包含广播信息的数据。 + */ + @Override + public void onReceive(Context context, Intent intent) { + // 将接收到的Intent的目标设置为AlarmAlertActivity类 + intent.setClass(context, AlarmAlertActivity.class); + + // 为Intent添加标记,表示需要创建一个新的任务栈 + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + // 启动AlarmAlertActivity活动,显示闹钟提醒 + context.startActivity(intent); + } +} + From 7d36bfb090becb467bf029baa937ba93552b7511 Mon Sep 17 00:00:00 2001 From: Wangranran <3587345858@qq.com> Date: Wed, 25 Dec 2024 17:12:30 +0800 Subject: [PATCH 4/4] 3 --- BackupUtils.txt | 200 ++++++++++++++++++++++++++++++ DataUtils.txt | 152 +++++++++++++++++++++++ DateTimePicker.txt | 98 +++++++++++++++ DateTimePickerDialog.txt | 92 ++++++++++++++ DropdownMenu.txt | 62 ++++++++++ FoldersListAdapter.txt | 87 +++++++++++++ GTaskStringUtils.txt | 145 ++++++++++++++++++++++ NoteEditActivity.txt | 77 ++++++++++++ NoteEditText.txt | 77 ++++++++++++ NoteItemData.txt | 98 +++++++++++++++ NoteWidgetProvider.txt | 80 ++++++++++++ NoteWidgetProvider_2x.txt | 48 ++++++++ NoteWidgetProvider_4x.txt | 47 +++++++ NotesListActivity.txt | 110 +++++++++++++++++ NotesListAdapter.txt | 219 +++++++++++++++++++++++++++++++++ NotesListItem.txt | 124 +++++++++++++++++++ NotesPreferenceActivity.txt | 238 ++++++++++++++++++++++++++++++++++++ ResourceParser.txt | 188 ++++++++++++++++++++++++++++ 18 files changed, 2142 insertions(+) create mode 100644 BackupUtils.txt create mode 100644 DataUtils.txt create mode 100644 DateTimePicker.txt create mode 100644 DateTimePickerDialog.txt create mode 100644 DropdownMenu.txt create mode 100644 FoldersListAdapter.txt create mode 100644 GTaskStringUtils.txt create mode 100644 NoteEditActivity.txt create mode 100644 NoteEditText.txt create mode 100644 NoteItemData.txt create mode 100644 NoteWidgetProvider.txt create mode 100644 NoteWidgetProvider_2x.txt create mode 100644 NoteWidgetProvider_4x.txt create mode 100644 NotesListActivity.txt create mode 100644 NotesListAdapter.txt create mode 100644 NotesListItem.txt create mode 100644 NotesPreferenceActivity.txt create mode 100644 ResourceParser.txt diff --git a/BackupUtils.txt b/BackupUtils.txt new file mode 100644 index 0000000..f516e81 --- /dev/null +++ b/BackupUtils.txt @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.tool; + +import android.content.Context; +import android.database.Cursor; +import android.os.Environment; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.util.Log; + +import net.micode.notes.R; +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; + +/** + * BackupUtils 类提供了将应用程序中的笔记数据备份到文本文件的功能。 + */ +public class BackupUtils { + private static final String TAG = "BackupUtils"; + // Singleton 实例 + private static BackupUtils sInstance; + + /** + * 获取 BackupUtils 类的单例对象。 + * + * @param context Android 上下文对象。 + * @return BackupUtils 的单例对象。 + */ + public static synchronized BackupUtils getInstance(Context context) { + if (sInstance == null) { + sInstance = new BackupUtils(context); + } + 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; + + private TextExport mTextExport; + + /** + * BackupUtils 类的构造函数。 + * + * @param context Android 上下文对象。 + */ + 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; + } + + /** + * TextExport 类负责将笔记数据导出到文本文件。 + */ + private static class TextExport { + // 省略了部分代码注释,因为它们已经在代码中以注释的形式给出。 + // 这些代码主要是定义了一些用于查询数据库的投影数组,以及用于格式化输出文本的字符串数组。 + + private Context mContext; + private String mFileName; + private String mFileDirectory; + + /** + * TextExport 类的构造函数。 + * + * @param context Android 上下文对象。 + */ + public TextExport(Context context) { + // 初始化格式化字符串数组和上下文对象。 + } + + /** + * 根据资源ID获取格式化字符串。 + * + * @param id 资源ID。 + * @return 格式化字符串。 + */ + private String getFormat(int id) { + return TEXT_FORMAT[id]; + } + + /** + * 将指定文件夹中的笔记导出到文本文件。 + * + * @param folderId 文件夹ID。 + * @param ps PrintStream 对象,用于写入文本文件。 + */ + private void exportFolderToText(String folderId, PrintStream ps) { + // 查询属于该文件夹的笔记,并导出。 + } + + /** + * 将指定笔记导出到文本文件。 + * + * @param noteId 笔记ID。 + * @param ps PrintStream 对象,用于写入文本文件。 + */ + private void exportNoteToText(String noteId, PrintStream ps) { + // 查询属于该笔记的数据,并导出。 + } + + /** + * 将笔记数据导出为用户可读的文本格式。 + * + * @return 一个表示操作结果的状态码。 + */ + public int exportToText() { + // 检查外部存储是否可用,然后导出笔记数据到文本文件。 + } + + /** + * 获取指向导出文本文件的 PrintStream 对象。 + * + * @return PrintStream 对象,或者在出错时返回 null。 + */ + private PrintStream getExportToTextPrintStream() { + // 创建或获取文件,并返回 PrintStream 对象。 + } + } + + /** + * 在 SD 卡上生成用于存储导入数据的文本文件。 + * + * @param context Android 上下文对象。 + * @param filePathResId 文件路径资源ID。 + * @param fileNameFormatResId 文件名格式资源ID。 + * @return 生成的文件对象,或者在出错时返回 null。 + */ + private static File generateFileMountedOnSDcard(Context context, int filePathResId, int fileNameFormatResId) { + // 根据资源ID生成文件路径和文件名,并创建文件。 + } +} \ No newline at end of file diff --git a/DataUtils.txt b/DataUtils.txt new file mode 100644 index 0000000..2b0d06b --- /dev/null +++ b/DataUtils.txt @@ -0,0 +1,152 @@ + +/** + * 工具类DataUtils,包含一系列用于操作便签数据的方法。 + */ +public class DataUtils { + public static final String TAG = "DataUtils"; + + /** + * 批量删除便签。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param ids 要删除的便签ID集合。 + * @return 如果删除成功返回true,否则返回false。 + */ + public static boolean batchDeleteNotes(ContentResolver resolver, HashSet ids) { + // 方法实现... + } + + /** + * 将单个便签移动到另一个文件夹。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param id 要移动的便签ID。 + * @param srcFolderId 当前文件夹ID。 + * @param desFolderId 目标文件夹ID。 + */ + public static void moveNoteToFoler(ContentResolver resolver, long id, long srcFolderId, long desFolderId) { + // 方法实现... + } + + /** + * 批量将便签移动到指定文件夹。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param ids 要移动的便签ID集合。 + * @param folderId 目标文件夹ID。 + * @return 如果移动成功返回true,否则返回false。 + */ + public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids, long folderId) { + // 方法实现... + } + + /** + * 获取除系统文件夹外的所有文件夹数量。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @return 文件夹数量。 + */ + public static int getUserFolderCount(ContentResolver resolver) { + // 方法实现... + } + + /** + * 检查便签在数据库中是否可见。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param noteId 便签ID。 + * @param type 便签类型。 + * @return 如果便签可见返回true,否则返回false。 + */ + public static boolean visibleInNoteDatabase(ContentResolver resolver, long noteId, int type) { + // 方法实现... + } + + /** + * 检查便签在数据库中是否存在。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param noteId 便签ID。 + * @return 如果便签存在返回true,否则返回false。 + */ + public static boolean existInNoteDatabase(ContentResolver resolver, long noteId) { + // 方法实现... + } + + /** + * 检查数据在数据库中是否存在。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param dataId 数据ID。 + * @return 如果数据存在返回true,否则返回false。 + */ + public static boolean existInDataDatabase(ContentResolver resolver, long dataId) { + // 方法实现... + } + + /** + * 检查指定名称的文件夹是否可见。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param name 文件夹名称。 + * @return 如果文件夹可见返回true,否则返回false。 + */ + public static boolean checkVisibleFolderName(ContentResolver resolver, String name) { + // 方法实现... + } + + /** + * 获取文件夹中便签的小部件属性集合。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param folderId 文件夹ID。 + * @return 小部件属性集合。 + */ + public static HashSet getFolderNoteWidget(ContentResolver resolver, long folderId) { + // 方法实现... + } + + /** + * 根据便签ID获取关联的电话号码。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param noteId 便签ID。 + * @return 电话号码字符串。 + */ + public static String getCallNumberByNoteId(ContentResolver resolver, long noteId) { + // 方法实现... + } + + /** + * 根据电话号码和通话日期获取便签ID。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param phoneNumber 电话号码。 + * @param callDate 通话日期。 + * @return 便签ID。 + */ + public static long getNoteIdByPhoneNumberAndCallDate(ContentResolver resolver, String phoneNumber, long callDate) { + // 方法实现... + } + + /** + * 根据ID获取便签的摘要。 + * + * @param resolver ContentResolver对象,用于访问内容提供者。 + * @param noteId 便签ID。 + * @return 便签摘要字符串。 + */ + public static String getSnippetById(ContentResolver resolver, long noteId) { + // 方法实现... + } + + /** + * 获取格式化后的便签摘要,去除换行符。 + * + * @param snippet 原始便签摘要。 + * @return 格式化后的便签摘要。 + */ + public static String getFormattedSnippet(String snippet) { + // 方法实现... + } +} diff --git a/DateTimePicker.txt b/DateTimePicker.txt new file mode 100644 index 0000000..b3bb76e --- /dev/null +++ b/DateTimePicker.txt @@ -0,0 +1,98 @@ + +/** + * 自定义日期时间选择器视图。 + */ +public class DateTimePicker extends FrameLayout { + // 类成员变量和常量定义 + private static final boolean DEFAULT_ENABLE_STATE = true; + private static final int HOURS_IN_HALF_DAY = 12; + // ... 其他常量定义 + + // 日期时间选择器的组件 + private final NumberPicker mDateSpinner; + private final NumberPicker mHourSpinner; + private final NumberPicker mMinuteSpinner; + private final NumberPicker mAmPmSpinner; + private Calendar mDate; + + // 日期显示值数组 + private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; + + // AM/PM标志 + private boolean mIsAm; + + // 是否为24小时视图 + private boolean mIs24HourView; + + // 启用状态 + private boolean mIsEnabled = DEFAULT_ENABLE_STATE; + + // 初始化标志 + private boolean mInitialising; + + // 日期时间改变监听器 + private OnDateTimeChangedListener mOnDateTimeChangedListener; + + // NumberPicker值改变监听器 + private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { + @Override + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + // 日期改变时的处理逻辑 + } + }; + // ... 其他监听器定义 + + /** + * 定义日期时间改变监听器接口。 + */ + public interface OnDateTimeChangedListener { + void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute); + } + + /** + * 构造函数。 + */ + public DateTimePicker(Context context) { + // ... 实现代码 + } + + /** + * 设置当前日期。 + * @param date 长整型日期值。 + */ + public void setCurrentDate(long date) { + // ... 实现代码 + } + + /** + * 获取当前年份。 + * @return 当前年份。 + */ + public int getCurrentYear() { + // ... 实现代码 + } + + // ... 其他日期时间组件的getter和setter方法 + + /** + * 设置是否为24小时视图。 + * @param is24HourView 是否为24小时视图。 + */ + public void set24HourView(boolean is24HourView) { + // ... 实现代码 + } + + /** + * 设置日期时间改变监听器。 + * @param callback 监听器回调。 + */ + public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { + // ... 实现代码 + } + + private void onDateTimeChanged() { + // 通知监听器日期时间改变 + } +} + diff --git a/DateTimePickerDialog.txt b/DateTimePickerDialog.txt new file mode 100644 index 0000000..713bb10 --- /dev/null +++ b/DateTimePickerDialog.txt @@ -0,0 +1,92 @@ +/** + * 日期时间选择器对话框,允许用户设置日期和时间。 + */ +public class DateTimePickerDialog extends AlertDialog implements OnClickListener { + // 当前日期时间 + private Calendar mDate = Calendar.getInstance(); + // 是否为24小时视图 + private boolean mIs24HourView; + // 日期时间设置监听器 + private OnDateTimeSetListener mOnDateTimeSetListener; + // 日期时间选择器组件 + private DateTimePicker mDateTimePicker; + + /** + * 日期时间设置监听器接口。 + */ + public interface OnDateTimeSetListener { + void OnDateTimeSet(AlertDialog dialog, long date); + } + + /** + * 构造函数。 + * @param context 上下文对象 + * @param date 初始日期时间 + */ + public DateTimePickerDialog(Context context, long date) { + super(context); + mDateTimePicker = new DateTimePicker(context); + setView(mDateTimePicker); + // 设置日期时间改变监听器 + mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { + public void onDateTimeChanged(DateTimePicker view, int year, int month, + int dayOfMonth, int hourOfDay, int minute) { + mDate.set(Calendar.YEAR, year); + mDate.set(Calendar.MONTH, month); + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); + mDate.set(Calendar.MINUTE, minute); + updateTitle(mDate.getTimeInMillis()); + } + }); + mDate.setTimeInMillis(date); + mDate.set(Calendar.SECOND, 0); + mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); + // 设置确认和取消按钮 + setButton(context.getString(R.string.datetime_dialog_ok), this); + setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); + // 设置24小时视图 + set24HourView(DateFormat.is24HourFormat(this.getContext())); + updateTitle(mDate.getTimeInMillis()); + } + + /** + * 设置是否为24小时视图。 + * @param is24HourView 是否为24小时视图 + */ + public void set24HourView(boolean is24HourView) { + mIs24HourView = is24HourView; + } + + /** + * 设置日期时间设置监听器。 + * @param callBack 监听器回调 + */ + public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { + mOnDateTimeSetListener = callBack; + } + + /** + * 更新对话框标题为当前日期时间。 + * @param date 长整型日期时间值 + */ + private void updateTitle(long date) { + int flag = + DateUtils.FORMAT_SHOW_YEAR | + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; + flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_12HOUR; + setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); + } + + /** + * 点击事件处理。 + * @param arg0 对话框接口 + * @param arg1 按钮索引 + */ + public void onClick(DialogInterface arg0, int arg1) { + if (mOnDateTimeSetListener != null) { + mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); + } + } +} \ No newline at end of file diff --git a/DropdownMenu.txt b/DropdownMenu.txt new file mode 100644 index 0000000..c3a2414 --- /dev/null +++ b/DropdownMenu.txt @@ -0,0 +1,62 @@ +/** + * 下拉菜单类,用于创建和管理弹出式菜单。 + */ +public class DropdownMenu { + // 下拉按钮 + private Button mButton; + // 弹出式菜单 + private PopupMenu mPopupMenu; + // 菜单项 + private Menu mMenu; + + /** + * 构造函数。 + * @param context 上下文对象,用于获取资源和创建菜单。 + * @param button 显示下拉菜单的按钮。 + * @param menuId 要加载的菜单资源ID。 + */ + public DropdownMenu(Context context, Button button, int menuId) { + mButton = button; + // 设置按钮的背景资源为下拉图标 + mButton.setBackgroundResource(R.drawable.dropdown_icon); + // 创建PopupMenu实例,关联到按钮 + mPopupMenu = new PopupMenu(context, mButton); + // 获取菜单实例 + mMenu = mPopupMenu.getMenu(); + // 从资源文件中加载菜单项 + mPopupMenu.getMenuInflater().inflate(menuId, mMenu); + // 设置按钮的点击事件监听器,点击时显示菜单 + mButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + mPopupMenu.show(); + } + }); + } + + /** + * 设置菜单项点击事件监听器。 + * @param listener 菜单项点击事件监听器。 + */ + public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { + if (mPopupMenu != null) { + mPopupMenu.setOnMenuItemClickListener(listener); + } + } + + /** + * 查找具有指定ID的菜单项。 + * @param id 菜单项ID。 + * @return 菜单项对象。 + */ + public MenuItem findItem(int id) { + return mMenu.findItem(id); + } + + /** + * 设置下拉按钮的标题。 + * @param title 标题文本。 + */ + public void setTitle(CharSequence title) { + mButton.setText(title); + } +} \ No newline at end of file diff --git a/FoldersListAdapter.txt b/FoldersListAdapter.txt new file mode 100644 index 0000000..737768c --- /dev/null +++ b/FoldersListAdapter.txt @@ -0,0 +1,87 @@ +/** + * 文件夹列表适配器,用于显示和管理文件夹列表项。 + */ +public class FoldersListAdapter extends CursorAdapter { + // 投影数组,用于查询数据库时指定需要哪些列 + public static final String [] PROJECTION = { + NoteColumns.ID, + NoteColumns.SNIPPET + }; + + // 列索引常量 + public static final int ID_COLUMN = 0; + public static final int NAME_COLUMN = 1; + + /** + * 构造函数。 + * @param context 上下文对象,提供应用环境信息。 + * @param c 数据库游标,包含文件夹数据。 + */ + public FoldersListAdapter(Context context, Cursor c) { + super(context, c); + } + + /** + * 创建新的列表项视图。 + * @param context 上下文对象。 + * @param cursor 数据库游标。 + * @param parent 父视图组。 + * @return 新的列表项视图。 + */ + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return new FolderListItem(context); + } + + /** + * 绑定数据到列表项视图。 + * @param view 列表项视图。 + * @param context 上下文对象。 + * @param cursor 数据库游标。 + */ + @Override + public void bindView(View view, Context context, Cursor cursor) { + if (view instanceof FolderListItem) { + String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context + .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); + ((FolderListItem) view).bind(folderName); + } + } + + /** + * 获取指定位置的文件夹名称。 + * @param context 上下文对象。 + * @param position 列表项位置。 + * @return 文件夹名称。 + */ + public String getFolderName(Context context, int position) { + Cursor cursor = (Cursor) getItem(position); + return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context + .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); + } + + /** + * 自定义文件夹列表项视图。 + */ + private class FolderListItem extends LinearLayout { + private TextView mName; + + /** + * 构造函数。 + * @param context 上下文对象。 + */ + public FolderListItem(Context context) { + super(context); + inflate(context, R.layout.folder_list_item, this); + mName = (TextView) findViewById(R.id.tv_folder_name); + } + + /** + * 绑定文件夹名称到视图。 + * @param name 文件夹名称。 + */ + public void bind(String name) { + mName.setText(name); + } + } +} \ No newline at end of file diff --git a/GTaskStringUtils.txt b/GTaskStringUtils.txt new file mode 100644 index 0000000..deeb898 --- /dev/null +++ b/GTaskStringUtils.txt @@ -0,0 +1,145 @@ + +/** + * 工具类GTaskStringUtils,包含处理Google Tasks(GTask)JSON数据时使用的常量字符串。 + */ +public class GTaskStringUtils { + + // GTask JSON中用于标识操作ID的键 + public final static String GTASK_JSON_ACTION_ID = "action_id"; + + // GTask JSON中用于标识操作列表的键 + public final static String GTASK_JSON_ACTION_LIST = "action_list"; + + // GTask JSON中用于标识操作类型的键 + public final static String GTASK_JSON_ACTION_TYPE = "action_type"; + + // GTask JSON中用于标识创建任务的操作类型 + public final static String GTASK_JSON_ACTION_TYPE_CREATE = "create"; + + // GTask JSON中用于标识获取所有任务的操作类型 + public final static String GTASK_JSON_ACTION_TYPE_GETALL = "get_all"; + + // GTask JSON中用于标识移动任务的操作类型 + public final static String GTASK_JSON_ACTION_TYPE_MOVE = "move"; + + // GTask JSON中用于标识更新任务的操作类型 + public final static String GTASK_JSON_ACTION_TYPE_UPDATE = "update"; + + // GTask JSON中用于标识创建者ID的键 + public final static String GTASK_JSON_CREATOR_ID = "creator_id"; + + // GTask JSON中用于标识子实体的键 + public final static String GTASK_JSON_CHILD_ENTITY = "child_entity"; + + // GTask JSON中用于标识客户端版本的键 + public final static String GTASK_JSON_CLIENT_VERSION = "client_version"; + + // GTask JSON中用于标识任务是否完成的键 + public final static String GTASK_JSON_COMPLETED = "completed"; + + // GTask JSON中用于标识当前列表ID的键 + public final static String GTASK_JSON_CURRENT_LIST_ID = "current_list_id"; + + // GTask JSON中用于标识默认列表ID的键 + public final static String GTASK_JSON_DEFAULT_LIST_ID = "default_list_id"; + + // GTask JSON中用于标识任务是否被删除的键 + public final static String GTASK_JSON_DELETED = "deleted"; + + // GTask JSON中用于标识目标列表的键 + public final static String GTASK_JSON_DEST_LIST = "dest_list"; + + // GTask JSON中用于标识目标父实体的键 + public final static String GTASK_JSON_DEST_PARENT = "dest_parent"; + + // GTask JSON中用于标识目标父实体类型的键 + public final static String GTASK_JSON_DEST_PARENT_TYPE = "dest_parent_type"; + + // GTask JSON中用于标识实体变化的键 + public final static String GTASK_JSON_ENTITY_DELTA = "entity_delta"; + + // GTask JSON中用于标识实体类型的键 + public final static String GTASK_JSON_ENTITY_TYPE = "entity_type"; + + // GTask JSON中用于标识获取已删除任务的键 + public final static String GTASK_JSON_GET_DELETED = "get_deleted"; + + // GTask JSON中用于标识ID的键 + public final static String GTASK_JSON_ID = "id"; + + // GTask JSON中用于标识索引的键 + public final static String GTASK_JSON_INDEX = "index"; + + // GTask JSON中用于标识最后修改时间的键 + public final static String GTASK_JSON_LAST_MODIFIED = "last_modified"; + + // GTask JSON中用于标识最新同步点的键 + public final static String GTASK_JSON_LATEST_SYNC_POINT = "latest_sync_point"; + + // GTask JSON中用于标识列表ID的键 + public final static String GTASK_JSON_LIST_ID = "list_id"; + + // GTask JSON中用于标识列表集合的键 + public final static String GTASK_JSON_LISTS = "lists"; + + // GTask JSON中用于标识名称的键 + public final static String GTASK_JSON_NAME = "name"; + + // GTask JSON中用于标识新ID的键 + public final static String GTASK_JSON_NEW_ID = "new_id"; + + // GTask JSON中用于标识备注的键 + public final static String GTASK_JSON_NOTES = "notes"; + + // GTask JSON中用于标识父ID的键 + public final static String GTASK_JSON_PARENT_ID = "parent_id"; + + // GTask JSON中用于标识前一个兄弟ID的键 + public final static String GTASK_JSON_PRIOR_SIBLING_ID = "prior_sibling_id"; + + // GTask JSON中用于标识结果的键 + public final static String GTASK_JSON_RESULTS = "results"; + + // GTask JSON中用于标识源列表的键 + public final static String GTASK_JSON_SOURCE_LIST = "source_list"; + + // GTask JSON中用于标识任务集合的键 + public final static String GTASK_JSON_TASKS = "tasks"; + + // GTask JSON中用于标识类型的键 + public final static String GTASK_JSON_TYPE = "type"; + + // GTask JSON中用于标识组类型的值 + public final static String GTASK_JSON_TYPE_GROUP = "GROUP"; + + // GTask JSON中用于标识任务类型的值 + public final static String GTASK_JSON_TYPE_TASK = "TASK"; + + // GTask 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/NoteEditActivity.txt b/NoteEditActivity.txt new file mode 100644 index 0000000..17cb2d8 --- /dev/null +++ b/NoteEditActivity.txt @@ -0,0 +1,77 @@ +/** + * 便签编辑活动,用于编辑和查看便签详情。 + */ +public class NoteEditActivity extends Activity implements OnClickListener, + NoteSettingChangedListener, OnTextViewChangeListener { + + // 内部类,用于持有头部视图的控件引用 + private class HeadViewHolder { + // 修改日期文本视图 + public TextView tvModified; + // 提醒图标 + public ImageView ivAlertIcon; + // 提醒日期文本视图 + public TextView tvAlertDate; + // 设置背景颜色图标 + public ImageView ibSetBgColor; + } + + // 静态映射,用于背景颜色选择器按钮和颜色ID之间的映射 + private static final Map sBgSelectorBtnsMap = new HashMap(); + // 静态映射,用于字体大小选择器按钮和大小ID之间的映射 + private static final Map sFontSizeBtnsMap = new HashMap(); + + // 类成员变量 + // 头部视图持有者,包含头部相关控件的引用 + private HeadViewHolder mNoteHeaderHolder; + // 头部视图面板 + private View mHeadViewPanel; + // 背景颜色选择器 + private View mNoteBgColorSelector; + // 字体大小选择器 + private View mFontSizeSelector; + // 便签编辑器 + private EditText mNoteEditor; + // 便签编辑器面板 + private View mNoteEditorPanel; + // 当前编辑的便签 + private WorkingNote mWorkingNote; + // 共享偏好设置 + private SharedPreferences mSharedPrefs; + // 当前字体大小ID + private int mFontSizeId; + + /** + * 活动创建时调用。 + * @param savedInstanceState 保存的实例状态 + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.note_edit); + // 初始化活动状态 + if (savedInstanceState == null && !initActivityState(getIntent())) { + finish(); + return; + } + initResources(); + } + + /** + * 初始化活动状态。 + * @param intent 启动活动的Intent + * @return 是否成功初始化 + */ + private boolean initActivityState(Intent intent) { + // 根据传入的Intent初始化活动状态,例如加载便签数据等 + } + + /** + * 初始化资源。 + */ + private void initResources() { + // 初始化头部视图持有者,设置监听器,绑定数据等 + } + + // 其他方法,包括处理点击事件、保存便签、设置提醒等... +} \ No newline at end of file diff --git a/NoteEditText.txt b/NoteEditText.txt new file mode 100644 index 0000000..17cb2d8 --- /dev/null +++ b/NoteEditText.txt @@ -0,0 +1,77 @@ +/** + * 便签编辑活动,用于编辑和查看便签详情。 + */ +public class NoteEditActivity extends Activity implements OnClickListener, + NoteSettingChangedListener, OnTextViewChangeListener { + + // 内部类,用于持有头部视图的控件引用 + private class HeadViewHolder { + // 修改日期文本视图 + public TextView tvModified; + // 提醒图标 + public ImageView ivAlertIcon; + // 提醒日期文本视图 + public TextView tvAlertDate; + // 设置背景颜色图标 + public ImageView ibSetBgColor; + } + + // 静态映射,用于背景颜色选择器按钮和颜色ID之间的映射 + private static final Map sBgSelectorBtnsMap = new HashMap(); + // 静态映射,用于字体大小选择器按钮和大小ID之间的映射 + private static final Map sFontSizeBtnsMap = new HashMap(); + + // 类成员变量 + // 头部视图持有者,包含头部相关控件的引用 + private HeadViewHolder mNoteHeaderHolder; + // 头部视图面板 + private View mHeadViewPanel; + // 背景颜色选择器 + private View mNoteBgColorSelector; + // 字体大小选择器 + private View mFontSizeSelector; + // 便签编辑器 + private EditText mNoteEditor; + // 便签编辑器面板 + private View mNoteEditorPanel; + // 当前编辑的便签 + private WorkingNote mWorkingNote; + // 共享偏好设置 + private SharedPreferences mSharedPrefs; + // 当前字体大小ID + private int mFontSizeId; + + /** + * 活动创建时调用。 + * @param savedInstanceState 保存的实例状态 + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.note_edit); + // 初始化活动状态 + if (savedInstanceState == null && !initActivityState(getIntent())) { + finish(); + return; + } + initResources(); + } + + /** + * 初始化活动状态。 + * @param intent 启动活动的Intent + * @return 是否成功初始化 + */ + private boolean initActivityState(Intent intent) { + // 根据传入的Intent初始化活动状态,例如加载便签数据等 + } + + /** + * 初始化资源。 + */ + private void initResources() { + // 初始化头部视图持有者,设置监听器,绑定数据等 + } + + // 其他方法,包括处理点击事件、保存便签、设置提醒等... +} \ No newline at end of file diff --git a/NoteItemData.txt b/NoteItemData.txt new file mode 100644 index 0000000..4e8a5fe --- /dev/null +++ b/NoteItemData.txt @@ -0,0 +1,98 @@ +/** + * 便签项数据类,封装单个便签项的相关信息。 + */ +public class NoteItemData { + // 数据库查询字段投影 + static final String [] PROJECTION = new String [] { + NoteColumns.ID, + NoteColumns.ALERTED_DATE, + // ... 其他字段 + }; + + // 列索引常量 + private static final int ID_COLUMN = 0; + private static final int ALERTED_DATE_COLUMN = 1; + // ... 其他列索引常量 + + // 便签项属性 + private long mId; + private long mAlertDate; + private int mBgColorId; + private long mCreatedDate; + private boolean mHasAttachment; + private long mModifiedDate; + private int mNotesCount; + private long mParentId; + private String mSnippet; + private int mType; + private int mWidgetId; + private int mWidgetType; + private String mName; + private String mPhoneNumber; + + // 位置相关标志 + private boolean mIsLastItem; + private boolean mIsFirstItem; + private boolean mIsOnlyOneItem; + private boolean mIsOneNoteFollowingFolder; + private boolean mIsMultiNotesFollowingFolder; + + /** + * 构造函数,从数据库游标中初始化便签项数据。 + * @param context 上下文对象,用于访问资源和数据。 + * @param cursor 数据库游标,包含便签项的数据。 + */ + public NoteItemData(Context context, Cursor cursor) { + // 从游标中获取数据并初始化成员变量 + // ... 初始化代码 + } + + /** + * 检查便签项在列表中的位置,设置位置相关标志。 + * @param cursor 数据库游标。 + */ + private void checkPostion(Cursor cursor) { + // 设置位置相关标志的逻辑 + // ... 实现代码 + } + + // 获取器方法,用于获取便签项的属性值 + public boolean isOneFollowingFolder() { + return mIsOneNoteFollowingFolder; + } + + public boolean isMultiFollowingFolder() { + return mIsMultiNotesFollowingFolder; + } + + public boolean isLast() { + return mIsLastItem; + } + + public String getCallName() { + return mName; + } + + public boolean isFirst() { + return mIsFirstItem; + } + + public boolean isSingle() { + return mIsOnlyOneItem; + } + + public long getId() { + return mId; + } + + // ... 其他获取器方法 + + /** + * 根据游标获取便签类型。 + * @param cursor 数据库游标。 + * @return 便签类型。 + */ + public static int getNoteType(Cursor cursor) { + return cursor.getInt(TYPE_COLUMN); + } +} \ No newline at end of file diff --git a/NoteWidgetProvider.txt b/NoteWidgetProvider.txt new file mode 100644 index 0000000..8a80601 --- /dev/null +++ b/NoteWidgetProvider.txt @@ -0,0 +1,80 @@ +/** + * 便签小部件提供者,用于管理便签小部件的数据和界面更新。 + */ +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"; + + /** + * 当小部件被删除时调用。 + * @param context 上下文对象 + * @param appWidgetIds 被删除的小部件ID数组 + */ + @Override + public void onDeleted(Context context, int[] appWidgetIds) { + // 更新数据库,将被删除小部件的WIDGET_ID设置为无效 + } + + /** + * 获取小部件相关的便签信息。 + * @param context 上下文对象 + * @param widgetId 小部件ID + * @return 便签信息游标 + */ + private Cursor getNoteWidgetInfo(Context context, int widgetId) { + // 查询数据库,获取与小部件ID相关的便签信息 + } + + /** + * 更新小部件界面。 + * @param context 上下文对象 + * @param appWidgetManager AppWidget管理器 + * @param appWidgetIds 小部件ID数组 + */ + protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // 默认不启用隐私模式,调用带隐私模式参数的update方法 + } + + /** + * 更新小部件界面,支持隐私模式。 + * @param context 上下文对象 + * @param appWidgetManager AppWidget管理器 + * @param appWidgetIds 小部件ID数组 + * @param privacyMode 是否启用隐私模式 + */ + private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds, + boolean privacyMode) { + // 遍历小部件ID数组,更新每个小部件的界面 + } + + /** + * 获取背景资源ID。 + * @param bgId 背景ID + * @return 背景资源ID + */ + protected abstract int getBgResourceId(int bgId); + + /** + * 获取小部件布局ID。 + * @return 布局ID + */ + protected abstract int getLayoutId(); + + /** + * 获取小部件类型。 + * @return 小部件类型 + */ + protected abstract int getWidgetType(); +} \ No newline at end of file diff --git a/NoteWidgetProvider_2x.txt b/NoteWidgetProvider_2x.txt new file mode 100644 index 0000000..ea496ce --- /dev/null +++ b/NoteWidgetProvider_2x.txt @@ -0,0 +1,48 @@ +/** + * 2x2网格大小的便签小部件提供者,继承自NoteWidgetProvider。 + */ +public class NoteWidgetProvider_2x extends NoteWidgetProvider { + + /** + * 当小部件需要更新时调用。 + * @param context 上下文对象,提供应用程序环境信息。 + * @param appWidgetManager AppWidget管理器,用于管理小部件。 + * @param appWidgetIds 需要更新的小部件ID数组。 + */ + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // 调用父类的update方法,更新小部件 + super.update(context, appWidgetManager, appWidgetIds); + } + + /** + * 获取小部件的布局资源ID。 + * @return 小部件布局资源ID。 + */ + @Override + protected int getLayoutId() { + // 返回2x2网格大小小部件的布局资源ID + return R.layout.widget_2x; + } + + /** + * 获取背景资源ID。 + * @param bgId 背景ID。 + * @return 对应背景资源ID的资源。 + */ + @Override + protected int getBgResourceId(int bgId) { + // 根据背景ID获取2x2网格大小小部件的背景资源ID + return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId); + } + + /** + * 获取小部件类型。 + * @return 小部件类型。 + */ + @Override + protected int getWidgetType() { + // 返回2x2网格大小小部件的类型 + return Notes.TYPE_WIDGET_2X; + } +} \ No newline at end of file diff --git a/NoteWidgetProvider_4x.txt b/NoteWidgetProvider_4x.txt new file mode 100644 index 0000000..268a82b --- /dev/null +++ b/NoteWidgetProvider_4x.txt @@ -0,0 +1,47 @@ +/** + * 4x4网格大小的便签小部件提供者,继承自NoteWidgetProvider。 + */ +public class NoteWidgetProvider_4x extends NoteWidgetProvider { + + /** + * 当小部件需要更新时调用。 + * @param context 上下文对象,提供应用程序环境信息。 + * @param appWidgetManager AppWidget管理器,用于管理小部件。 + * @param appWidgetIds 需要更新的小部件ID数组。 + */ + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // 调用父类的update方法,更新小部件 + super.update(context, appWidgetManager, appWidgetIds); + } + + /** + * 获取小部件的布局资源ID。 + * @return 小部件布局资源ID。 + */ + protected int getLayoutId() { + // 返回4x4网格大小小部件的布局资源ID + return R.layout.widget_4x; + } + + /** + * 获取背景资源ID。 + * @param bgId 背景ID。 + * @return 对应背景资源ID的资源。 + */ + @Override + protected int getBgResourceId(int bgId) { + // 根据背景ID获取4x4网格大小小部件的背景资源ID + return ResourceParser.WidgetBgResources.getWidget4xBgResource(bgId); + } + + /** + * 获取小部件类型。 + * @return 小部件类型。 + */ + @Override + protected int getWidgetType() { + // 返回4x4网格大小小部件的类型 + return Notes.TYPE_WIDGET_4X; + } +} \ No newline at end of file diff --git a/NotesListActivity.txt b/NotesListActivity.txt new file mode 100644 index 0000000..0e7b7a8 --- /dev/null +++ b/NotesListActivity.txt @@ -0,0 +1,110 @@ +/** + * 便签列表活动,用于展示和管理便签列表。 + */ +public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { + // 定义查询令牌 + private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; + private static final int FOLDER_LIST_QUERY_TOKEN = 1; + + // 定义菜单项ID + private static final int MENU_FOLDER_DELETE = 0; + private static final int MENU_FOLDER_VIEW = 1; + private static final int MENU_FOLDER_CHANGE_NAME = 2; + + // 定义偏好设置键 + private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; + + // 枚举,表示当前列表的编辑状态 + private enum ListEditState { + NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER + }; + + // 类成员变量 + private ListEditState mState; + private BackgroundQueryHandler mBackgroundQueryHandler; + private NotesListAdapter mNotesListAdapter; + private ListView mNotesListView; + private Button mAddNewNote; + private boolean mDispatch; + private int mOriginY; + private int mDispatchY; + private TextView mTitleBar; + private long mCurrentFolderId; + private ContentResolver mContentResolver; + private ModeCallback mModeCallBack; + private static final String TAG = "NotesListActivity"; + private NoteItemData mFocusNoteDataItem; + + // onCreate方法,活动创建时调用 + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.note_list); + initResources(); + setAppInfoFromRawRes(); + } + + // 初始化资源 + private void initResources() { + // 初始化代码... + } + + // 从raw资源文件中设置应用信息 + private void setAppInfoFromRawRes() { + // 读取介绍信息并显示 + } + + // onStart方法,活动启动时调用 + @Override + protected void onStart() { + super.onStart(); + startAsyncNotesListQuery(); + } + + // 启动异步查询便签列表 + private void startAsyncNotesListQuery() { + // 查询代码... + } + + // 异步查询处理器 + private final class BackgroundQueryHandler extends AsyncQueryHandler { + // 构造函数和onQueryComplete方法... + } + + // 显示文件夹列表菜单 + private void showFolderListMenu(Cursor cursor) { + // 显示文件夹列表菜单代码... + } + + // 创建新便签 + private void createNewNote() { + // 创建新便签代码... + } + + // 批量删除便签 + private void batchDelete() { + // 批量删除便签代码... + } + + // 删除文件夹 + private void deleteFolder(long folderId) { + // 删除文件夹代码... + } + + // 打开节点(便签或文件夹) + private void openNode(NoteItemData data) { + // 打开便签节点代码... + } + + // 打开文件夹 + private void openFolder(NoteItemData data) { + // 打开文件夹代码... + } + + // onClick方法,处理点击事件 + public void onClick(View v) { + // 处理点击事件代码... + } + + // 其他方法,包括处理选项菜单、上下文菜单、搜索请求等... +} \ No newline at end of file diff --git a/NotesListAdapter.txt b/NotesListAdapter.txt new file mode 100644 index 0000000..0de97fc --- /dev/null +++ b/NotesListAdapter.txt @@ -0,0 +1,219 @@ +/** + * 便签列表适配器,用于管理和显示便签列表的数据。 + */ +public class NotesListAdapter extends CursorAdapter { + // 日志标签 + private static final String TAG = "NotesListAdapter"; + // 类成员变量 + private Context mContext; // 上下文对象 + private HashMap mSelectedIndex; // 保存选中状态的索引 + private int mNotesCount; // 便签计数 + private boolean mChoiceMode; // 是否处于选择模式 + + /** + * 应用小部件属性类。 + */ + public static class AppWidgetAttribute { + public int widgetId; // 小部件ID + public int widgetType; // 小部件类型 + }; + + /** + * 构造函数。 + * @param context 上下文对象 + */ + public NotesListAdapter(Context context) { + super(context, null); + mSelectedIndex = new HashMap(); + mContext = context; + mNotesCount = 0; + } + + /** + * 创建新的列表项视图。 + * @param context 上下文对象 + * @param cursor 游标对象 + * @param parent 父视图组 + * @return 新的列表项视图 + */ + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return new NotesListItem(context); + } + + /** + * 绑定数据到列表项视图。 + * @param view 列表项视图 + * @param context 上下文对象 + * @param cursor 游标对象 + */ + @Override + public void bindView(View view, Context context, Cursor cursor) { + if (view instanceof NotesListItem) { + NoteItemData itemData = new NoteItemData(context, cursor); + ((NotesListItem) view).bind(context, itemData, mChoiceMode, isSelectedItem(cursor.getPosition())); + } + } + + /** + * 设置列表项的选中状态。 + * @param position 列表项位置 + * @param checked 是否选中 + */ + public void setCheckedItem(final int position, final boolean checked) { + mSelectedIndex.put(position, checked); + notifyDataSetChanged(); + } + + /** + * 获取是否处于选择模式。 + * @return 是否处于选择模式 + */ + public boolean isInChoiceMode() { + return mChoiceMode; + } + + /** + * 设置选择模式。 + * @param mode 是否开启选择模式 + */ + public void setChoiceMode(boolean mode) { + mSelectedIndex.clear(); + mChoiceMode = mode; + } + + /** + * 全选或全不选。 + * @param checked 是否选中 + */ + public void selectAll(boolean checked) { + Cursor cursor = getCursor(); + for (int i = 0; i < getCount(); i++) { + if (cursor.moveToPosition(i)) { + if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) { + setCheckedItem(i, checked); + } + } + } + } + + /** + * 获取选中的便签ID集合。 + * @return 选中的便签ID集合 + */ + public HashSet getSelectedItemIds() { + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Long id = getItemId(position); + if (id == Notes.ID_ROOT_FOLDER) { + Log.d(TAG, "Wrong item id, should not happen"); + } else { + itemSet.add(id); + } + } + } + return itemSet; + } + + /** + * 获取选中的小部件属性集合。 + * @return 选中的小部件属性集合 + */ + public HashSet getSelectedWidget() { + HashSet itemSet = new HashSet(); + for (Integer position : mSelectedIndex.keySet()) { + if (mSelectedIndex.get(position) == true) { + Cursor c = (Cursor) getItem(position); + if (c != null) { + AppWidgetAttribute widget = new AppWidgetAttribute(); + NoteItemData item = new NoteItemData(mContext, c); + widget.widgetId = item.getWidgetId(); + widget.widgetType = item.getWidgetType(); + itemSet.add(widget); + } else { + Log.e(TAG, "Invalid cursor"); + return null; + } + } + } + return itemSet; + } + + /** + * 获取选中数量。 + * @return 选中数量 + */ + public int getSelectedCount() { + Collection values = mSelectedIndex.values(); + if (null == values) { + return 0; + } + Iterator iter = values.iterator(); + int count = 0; + while (iter.hasNext()) { + if (true == iter.next()) { + count++; + } + } + return count; + } + + /** + * 判断是否全部选中。 + * @return 是否全部选中 + */ + public boolean isAllSelected() { + int checkedCount = getSelectedCount(); + return (checkedCount != 0 && checkedCount == mNotesCount); + } + + /** + * 判断指定位置的项是否选中。 + * @param position 项的位置 + * @return 是否选中 + */ + public boolean isSelectedItem(final int position) { + if (null == mSelectedIndex.get(position)) { + return false; + } + return mSelectedIndex.get(position); + } + + /** + * 当内容变化时调用。 + */ + @Override + protected void onContentChanged() { + super.onContentChanged(); + calcNotesCount(); + } + + /** + * 更改游标。 + * @param cursor 新的游标 + */ + @Override + public void changeCursor(Cursor cursor) { + super.changeCursor(cursor); + calcNotesCount(); + } + + /** + * 计算便签数量。 + */ + private void calcNotesCount() { + mNotesCount = 0; + for (int i = 0; i < getCount(); i++) { + Cursor c = (Cursor) getItem(i); + if (c != null) { + if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) { + mNotesCount++; + } + } else { + Log.e(TAG, "Invalid cursor"); + return; + } + } + } +} \ No newline at end of file diff --git a/NotesListItem.txt b/NotesListItem.txt new file mode 100644 index 0000000..cb7b5a1 --- /dev/null +++ b/NotesListItem.txt @@ -0,0 +1,124 @@ +/** + * 便签列表项视图,用于展示单个便签项的界面元素。 + */ +public class NotesListItem extends LinearLayout { + // 类成员变量 + private ImageView mAlert; // 提醒图标 + private TextView mTitle; // 便签标题 + private TextView mTime; // 便签修改时间 + private TextView mCallName; // 通话记录姓名 + private NoteItemData mItemData; // 便签项数据 + private CheckBox mCheckBox; // 选择框 + + /** + * 构造函数。 + * @param context 上下文对象 + */ + public NotesListItem(Context context) { + super(context); + // inflate the layout for this view + inflate(context, R.layout.note_item, this); + // 初始化视图组件 + mAlert = (ImageView) findViewById(R.id.iv_alert_icon); + mTitle = (TextView) findViewById(R.id.tv_title); + mTime = (TextView) findViewById(R.id.tv_time); + mCallName = (TextView) findViewById(R.id.tv_name); + mCheckBox = (CheckBox) findViewById(android.R.id.checkbox); + } + + /** + * 绑定数据到视图。 + * @param context 上下文对象 + * @param data 便签项数据 + * @param choiceMode 是否处于选择模式 + * @param checked 是否选中 + */ + public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) { + // 根据是否处于选择模式显示或隐藏选择框,并设置选中状态 + if (choiceMode && data.getType() == Notes.TYPE_NOTE) { + mCheckBox.setVisibility(View.VISIBLE); + mCheckBox.setChecked(checked); + } else { + mCheckBox.setVisibility(View.GONE); + } + + // 保存便签项数据 + mItemData = data; + // 根据便签项类型设置不同的视图显示 + if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { + // 通话记录文件夹特殊处理 + mCallName.setVisibility(View.GONE); + mAlert.setVisibility(View.VISIBLE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); + mTitle.setText(context.getString(R.string.call_record_folder_name) + + context.getString(R.string.format_folder_files_count, data.getNotesCount())); + mAlert.setImageResource(R.drawable.call_record); + } else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) { + // 通话记录项特殊处理 + mCallName.setVisibility(View.VISIBLE); + mCallName.setText(data.getCallName()); + mTitle.setTextAppearance(context, R.style.TextAppearanceSecondaryItem); + mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); + if (data.hasAlert()) { + mAlert.setImageResource(R.drawable.clock); + mAlert.setVisibility(View.VISIBLE); + } else { + mAlert.setVisibility(View.GONE); + } + } else { + // 普通便签项处理 + mCallName.setVisibility(View.GONE); + mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); + if (data.getType() == Notes.TYPE_FOLDER) { + // 文件夹项处理 + mTitle.setText(data.getSnippet() + + context.getString(R.string.format_folder_files_count, + data.getNotesCount())); + mAlert.setVisibility(View.GONE); + } else { + // 普通便签处理 + mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet())); + if (data.hasAlert()) { + mAlert.setImageResource(R.drawable.clock); + mAlert.setVisibility(View.VISIBLE); + } else { + mAlert.setVisibility(View.GONE); + } + } + } + // 设置时间显示 + mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate())); + // 设置背景 + setBackground(data); + } + + /** + * 设置背景资源。 + * @param data 便签项数据 + */ + private void setBackground(NoteItemData data) { + // 根据便签项类型和位置设置不同的背景资源 + int id = data.getBgColorId(); + if (data.getType() == Notes.TYPE_NOTE) { + if (data.isSingle() || data.isOneFollowingFolder()) { + setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id)); + } else if (data.isLast()) { + setBackgroundResource(NoteItemBgResources.getNoteBgLastRes(id)); + } else if (data.isFirst() || data.isMultiFollowingFolder()) { + setBackgroundResource(NoteItemBgResources.getNoteBgFirstRes(id)); + } else { + setBackgroundResource(NoteItemBgResources.getNoteBgNormalRes(id)); + } + } else { + setBackgroundResource(NoteItemBgResources.getFolderBgRes()); + } + } + + /** + * 获取便签项数据。 + * @return 便签项数据 + */ + public NoteItemData getItemData() { + return mItemData; + } +} \ No newline at end of file diff --git a/NotesPreferenceActivity.txt b/NotesPreferenceActivity.txt new file mode 100644 index 0000000..b466f3c --- /dev/null +++ b/NotesPreferenceActivity.txt @@ -0,0 +1,238 @@ +/** + * 便签应用的偏好设置活动,用于管理应用的设置。 + */ +public class NotesPreferenceActivity extends PreferenceActivity { + // 偏好设置文件名 + public static final String PREFERENCE_NAME = "notes_preferences"; + // 同步账户名称的键 + public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name"; + // 最后同步时间的键 + public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time"; + // 设置背景颜色的键 + public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear"; + // 同步账户的键 + private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key"; + // 权限过滤键 + private static final String AUTHORITIES_FILTER_KEY = "authorities"; + + // 类成员变量 + private PreferenceCategory mAccountCategory; // 账户类别 + private GTaskReceiver mReceiver; // 接收器 + private Account[] mOriAccounts; // 原始账户数组 + private boolean mHasAddedAccount; // 是否添加了账户 + + /** + * 活动创建时调用。 + * @param icicle 保存的实例状态 + */ + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + // 设置返回键 + getActionBar().setDisplayHomeAsUpEnabled(true); + // 加载偏好设置 + addPreferencesFromResource(R.xml.preferences); + // 初始化账户类别 + mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); + // 注册接收器 + mReceiver = new GTaskReceiver(); + IntentFilter filter = new IntentFilter(); + filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); + registerReceiver(mReceiver, filter); + // 初始化视图 + View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); + getListView().addHeaderView(header, null, true); + } + + /** + * 活动恢复时调用。 + */ + @Override + protected void onResume() { + super.onResume(); + // 自动设置同步账户 + if (mHasAddedAccount) { + Account[] accounts = getGoogleAccounts(); + if (mOriAccounts != null && accounts.length > mOriAccounts.length) { + for (Account accountNew : accounts) { + boolean found = false; + for (Account accountOld : mOriAccounts) { + if (TextUtils.equals(accountOld.name, accountNew.name)) { + found = true; + break; + } + } + if (!found) { + setSyncAccount(accountNew.name); + break; + } + } + } + } + // 刷新UI + refreshUI(); + } + + /** + * 活动销毁时调用。 + */ + @Override + protected void onDestroy() { + if (mReceiver != null) { + unregisterReceiver(mReceiver); + } + super.onDestroy(); + } + + /** + * 加载账户偏好设置。 + */ + private void loadAccountPreference() { + mAccountCategory.removeAll(); + // 创建账户偏好项 + Preference accountPref = new Preference(this); + final String defaultAccount = getSyncAccountName(this); + accountPref.setTitle(getString(R.string.preferences_account_title)); + accountPref.setSummary(getString(R.string.preferences_account_summary)); + accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + if (!GTaskSyncService.isSyncing()) { + if (TextUtils.isEmpty(defaultAccount)) { + showSelectAccountAlertDialog(); + } else { + showChangeAccountConfirmAlertDialog(); + } + } else { + Toast.makeText(NotesPreferenceActivity.this, + R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT) + .show(); + } + return true; + } + }); + mAccountCategory.addPreference(accountPref); + } + + /** + * 加载同步按钮。 + */ + private void loadSyncButton() { + Button syncButton = (Button) findViewById(R.id.preference_sync_button); + TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); + // 设置按钮状态 + if (GTaskSyncService.isSyncing()) { + syncButton.setText(getString(R.string.preferences_button_sync_cancel)); + syncButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + GTaskSyncService.cancelSync(NotesPreferenceActivity.this); + } + }); + } else { + syncButton.setText(getString(R.string.preferences_button_sync_immediately)); + syncButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + GTaskSyncService.startSync(NotesPreferenceActivity.this); + } + }); + } + syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this))); + // 设置最后同步时间 + if (GTaskSyncService.isSyncing()) { + lastSyncTimeView.setText(GTaskSyncService.getProgressString()); + lastSyncTimeView.setVisibility(View.VISIBLE); + } else { + long lastSyncTime = getLastSyncTime(this); + if (lastSyncTime != 0) { + lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time, + DateFormat.format(getString(R.string.preferences_last_sync_time_format), + lastSyncTime))); + lastSyncTimeView.setVisibility(View.VISIBLE); + } else { + lastSyncTimeView.setVisibility(View.GONE); + } + } + } + + /** + * 刷新UI。 + */ + private void refreshUI() { + loadAccountPreference(); + loadSyncButton(); + } + + /** + * 显示选择账户的对话框。 + */ + private void showSelectAccountAlertDialog() { + // 对话框代码... + } + + /** + * 显示更改账户的确认对话框。 + */ + private void showChangeAccountConfirmAlertDialog() { + // 对话框代码... + } + + /** + * 获取Google账户。 + * @return 账户数组 + */ + private Account[] getGoogleAccounts() { + AccountManager accountManager = AccountManager.get(this); + return accountManager.getAccountsByType("com.google"); + } + + /** + * 设置同步账户。 + * @param account 账户名 + */ + private void setSyncAccount(String account) { + // 设置同步账户代码... + } + + /** + * 移除同步账户。 + */ + private void removeSyncAccount() { + // 移除同步账户代码... + } + + /** + * 获取同步账户名。 + * @param context 上下文对象 + * @return 同步账户名 + */ + public static String getSyncAccountName(Context context) { + // 获取同步账户名代码... + } + + /** + * 设置最后同步时间。 + * @param context 上下文对象 + * @param time 最后同步时间 + */ + public static void setLastSyncTime(Context context, long time) { + // 设置最后同步时间代码... + } + + /** + * 获取最后同步时间。 + * @param context 上下文对象 + * @return 最后同步时间 + */ + public static long getLastSyncTime(Context context) { + // 获取最后同步时间代码... + } + + /** + * GTask接收器,用于接收同步服务的广播。 + */ + private class GTaskReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + refreshUI(); + if (intent.getBooleanExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_IS_SYNCING, false)) { + TextView syncStatus = (TextView) findViewById(R.id.prefenerece_sync_status_textview); + syncS \ No newline at end of file diff --git a/ResourceParser.txt b/ResourceParser.txt new file mode 100644 index 0000000..5f77c3e --- /dev/null +++ b/ResourceParser.txt @@ -0,0 +1,188 @@ + +/** + * 工具类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 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内部类,用于管理便签背景资源。 + */ + public static class NoteBgResources { + // 编辑状态下的背景资源数组 + private final static int [] BG_EDIT_RESOURCES = new int [] { + R.drawable.edit_yellow, + R.drawable.edit_blue, + R.drawable.edit_white, + R.drawable.edit_green, + R.drawable.edit_red + }; + + // 编辑状态下标题的背景资源数组 + private final static int [] BG_EDIT_TITLE_RESOURCES = new int [] { + R.drawable.edit_title_yellow, + R.drawable.edit_title_blue, + R.drawable.edit_title_white, + R.drawable.edit_title_green, + R.drawable.edit_title_red + }; + + // 获取便签背景资源 + public static int getNoteBgResource(int id) { + return BG_EDIT_RESOURCES[id]; + } + + // 获取便签标题背景资源 + public static int getNoteTitleBgResource(int id) { + return BG_EDIT_TITLE_RESOURCES[id]; + } + } + + /** + * 根据上下文获取默认背景ID。 + * @param context 上下文对象 + * @return 默认背景ID + */ + public static int getDefaultBgId(Context context) { + if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean( + NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { + return (int) (Math.random() * NoteBgResources.BG_EDIT_RESOURCES.length); + } else { + return BG_DEFAULT_COLOR; + } + } + + /** + * NoteItemBgResources内部类,用于管理便签项背景资源。 + */ + public static class NoteItemBgResources { + // 定义不同类型的背景资源数组 + private final static int [] BG_FIRST_RESOURCES = new int [] { + R.drawable.list_yellow_up, + R.drawable.list_blue_up, + R.drawable.list_white_up, + R.drawable.list_green_up, + R.drawable.list_red_up + }; + private final static int [] BG_NORMAL_RESOURCES = new int [] { + R.drawable.list_yellow_middle, + R.drawable.list_blue_middle, + R.drawable.list_white_middle, + R.drawable.list_green_middle, + R.drawable.list_red_middle + }; + private final static int [] BG_LAST_RESOURCES = new int [] { + R.drawable.list_yellow_down, + R.drawable.list_blue_down, + R.drawable.list_white_down, + R.drawable.list_green_down, + R.drawable.list_red_down, + }; + private final static int [] BG_SINGLE_RESOURCES = new int [] { + R.drawable.list_yellow_single, + R.drawable.list_blue_single, + R.drawable.list_white_single, + R.drawable.list_green_single, + R.drawable.list_red_single + }; + + // 获取不同类型的便签项背景资源 + public static int getNoteBgFirstRes(int id) { + return BG_FIRST_RESOURCES[id]; + } + + public static int getNoteBgLastRes(int id) { + return BG_LAST_RESOURCES[id]; + } + + public static int getNoteBgSingleRes(int id) { + return BG_SINGLE_RESOURCES[id]; + } + + public static int getNoteBgNormalRes(int id) { + return BG_NORMAL_RESOURCES[id]; + } + + // 获取文件夹背景资源 + public static int getFolderBgRes() { + return R.drawable.list_folder; + } + } + + /** + * WidgetBgResources内部类,用于管理小部件背景资源。 + */ + 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, + }; + + // 获取2x小部件背景资源 + public static int getWidget2xBgResource(int id) { + return BG_2X_RESOURCES[id]; + } + + // 定义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 + }; + + // 获取4x小部件背景资源 + public static int getWidget4xBgResource(int id) { + return BG_4X_RESOURCES[id]; + } + } + + /** + * TextAppearanceResources内部类,用于管理文本外观资源。 + */ + public static class TextAppearanceResources { + // 定义文本外观资源数组 + private final static int [] TEXTAPPEARANCE_RESOURCES = new int [] { + R.style.TextAppearanceNormal, + R.style.TextAppearanceMedium, + R.style.TextAppearanceLarge, + R.style.TextAppearanceSuper + }; + + // 获取文本外观资源 + public static int getTexAppearanceResource(int id) { + if (id >= TEXTAPPEARANCE_RESOURCES.length) { + return BG_DEFAULT_FONT_SIZE; + } + return TEXTAPPEARANCE_RESOURCES[id]; + } + + // 获取资源数组的大小 + public static int getResourcesSize() { + return TEXTAPPEARANCE_RESOURCES.length; + } + } +}