|
|
|
|
@ -0,0 +1,348 @@
|
|
|
|
|
|
|
|
|
|
package net.micode.notes.model;
|
|
|
|
|
|
|
|
|
|
import android.appwidget.AppWidgetManager;
|
|
|
|
|
import android.content.ContentUris;
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
import android.database.Cursor;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
|
|
import net.micode.notes.data.Notes;
|
|
|
|
|
import net.micode.notes.data.Notes.CallNote;
|
|
|
|
|
import net.micode.notes.data.Notes.DataColumns;
|
|
|
|
|
import net.micode.notes.data.Notes.DataConstants;
|
|
|
|
|
import net.micode.notes.data.Notes.NoteColumns;
|
|
|
|
|
import net.micode.notes.data.Notes.TextNote;
|
|
|
|
|
import net.micode.notes.tool.ResourceParser.NoteBgResources;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 当前活动便签的管理类,负责便签的创建、加载、属性设置和数据库同步
|
|
|
|
|
* 封装便签业务逻辑,并通过监听器实现与UI的交互
|
|
|
|
|
*/
|
|
|
|
|
public class WorkingNote {
|
|
|
|
|
// 核心数据对象
|
|
|
|
|
private Note mNote; // 便签数据模型
|
|
|
|
|
private long mNoteId; // 当前便签的数据库ID(0表示未持久化)
|
|
|
|
|
private String mContent; // 便签文本内容
|
|
|
|
|
private int mMode; // 模式(如普通模式/待办清单模式)
|
|
|
|
|
|
|
|
|
|
// 属性字段
|
|
|
|
|
private long mAlertDate; // 提醒时间(毫秒时间戳,0表示未设置)
|
|
|
|
|
private long mModifiedDate; // 最后修改时间
|
|
|
|
|
private int mBgColorId; // 背景颜色ID(对应资源索引)
|
|
|
|
|
private int mWidgetId; // 关联的小部件ID
|
|
|
|
|
private int mWidgetType; // 小部件类型(如2x、4x)
|
|
|
|
|
private long mFolderId; // 所属文件夹ID
|
|
|
|
|
|
|
|
|
|
// 上下文与状态
|
|
|
|
|
private Context mContext; // 上下文对象
|
|
|
|
|
private static final String TAG = "WorkingNote";
|
|
|
|
|
private boolean mIsDeleted; // 标记是否已删除
|
|
|
|
|
|
|
|
|
|
// 监听器接口
|
|
|
|
|
private NoteSettingChangedListener mNoteSettingStatusListener; // 属性变更监听器
|
|
|
|
|
|
|
|
|
|
// 数据库查询字段定义
|
|
|
|
|
/** 数据表(Data表)查询字段 */
|
|
|
|
|
public static final String[] DATA_PROJECTION = new String[] {
|
|
|
|
|
DataColumns.ID, // 数据项ID
|
|
|
|
|
DataColumns.CONTENT, // 内容(文本或通话记录)
|
|
|
|
|
DataColumns.MIME_TYPE, // MIME类型(区分文本/通话记录)
|
|
|
|
|
DataColumns.DATA1, // 扩展字段1(如模式)
|
|
|
|
|
DataColumns.DATA2, // 扩展字段2
|
|
|
|
|
DataColumns.DATA3, // 扩展字段3
|
|
|
|
|
DataColumns.DATA4, // 扩展字段4
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/** 便签表(Note表)查询字段 */
|
|
|
|
|
public static final String[] NOTE_PROJECTION = new String[] {
|
|
|
|
|
NoteColumns.PARENT_ID, // 父文件夹ID
|
|
|
|
|
NoteColumns.ALERTED_DATE, // 提醒时间
|
|
|
|
|
NoteColumns.BG_COLOR_ID, // 背景色ID
|
|
|
|
|
NoteColumns.WIDGET_ID, // 关联小部件ID
|
|
|
|
|
NoteColumns.WIDGET_TYPE, // 小部件类型
|
|
|
|
|
NoteColumns.MODIFIED_DATE // 修改时间
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 数据表字段索引常量 --------------------------------
|
|
|
|
|
private static final int DATA_ID_COLUMN = 0;
|
|
|
|
|
private static final int DATA_CONTENT_COLUMN = 1;
|
|
|
|
|
private static final int DATA_MIME_TYPE_COLUMN = 2;
|
|
|
|
|
private static final int DATA_MODE_COLUMN = 3;
|
|
|
|
|
|
|
|
|
|
// 便签表字段索引常量 --------------------------------
|
|
|
|
|
private static final int NOTE_PARENT_ID_COLUMN = 0;
|
|
|
|
|
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
|
|
|
|
|
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
|
|
|
|
|
private static final int NOTE_WIDGET_ID_COLUMN = 3;
|
|
|
|
|
private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
|
|
|
|
|
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
|
|
|
|
|
|
|
|
|
|
// 构造方法 ----------------------------------------
|
|
|
|
|
/**
|
|
|
|
|
* 新建便签的私有构造方法
|
|
|
|
|
* @param context 上下文
|
|
|
|
|
* @param folderId 所属文件夹ID
|
|
|
|
|
*/
|
|
|
|
|
private WorkingNote(Context context, long folderId) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
mAlertDate = 0; // 默认无提醒
|
|
|
|
|
mModifiedDate = System.currentTimeMillis();
|
|
|
|
|
mFolderId = folderId;
|
|
|
|
|
mNote = new Note(); // 初始化空Note对象
|
|
|
|
|
mNoteId = 0; // 新便签未持久化,ID为0
|
|
|
|
|
mIsDeleted = false;
|
|
|
|
|
mMode = 0; // 默认普通模式
|
|
|
|
|
mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 初始无小部件关联
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 加载现有便签的私有构造方法
|
|
|
|
|
* @param context 上下文
|
|
|
|
|
* @param noteId 目标便签ID
|
|
|
|
|
* @param folderId 所属文件夹ID(可传入0,后续从数据库加载)
|
|
|
|
|
*/
|
|
|
|
|
private WorkingNote(Context context, long noteId, long folderId) {
|
|
|
|
|
mContext = context;
|
|
|
|
|
mNoteId = noteId;
|
|
|
|
|
mFolderId = folderId;
|
|
|
|
|
mIsDeleted = false;
|
|
|
|
|
mNote = new Note();
|
|
|
|
|
loadNote(); // 从数据库加载数据
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 核心方法 ----------------------------------------
|
|
|
|
|
/**
|
|
|
|
|
* 从数据库加载便签基础属性(Note表)
|
|
|
|
|
*/
|
|
|
|
|
private void loadNote() {
|
|
|
|
|
// 查询便签表
|
|
|
|
|
Cursor cursor = mContext.getContentResolver().query(
|
|
|
|
|
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId),
|
|
|
|
|
NOTE_PROJECTION, null, null, null);
|
|
|
|
|
|
|
|
|
|
if (cursor != null) {
|
|
|
|
|
if (cursor.moveToFirst()) {
|
|
|
|
|
// 解析字段
|
|
|
|
|
mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);
|
|
|
|
|
mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);
|
|
|
|
|
mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);
|
|
|
|
|
mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);
|
|
|
|
|
mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);
|
|
|
|
|
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
|
|
|
|
|
}
|
|
|
|
|
cursor.close();
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "无法找到便签ID: " + mNoteId);
|
|
|
|
|
throw new IllegalArgumentException("无效的便签ID: " + mNoteId);
|
|
|
|
|
}
|
|
|
|
|
loadNoteData(); // 继续加载数据表内容
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 从数据库加载便签具体数据(Data表)
|
|
|
|
|
*/
|
|
|
|
|
private void loadNoteData() {
|
|
|
|
|
// 查询关联的数据表项
|
|
|
|
|
Cursor cursor = mContext.getContentResolver().query(
|
|
|
|
|
Notes.CONTENT_DATA_URI,
|
|
|
|
|
DATA_PROJECTION,
|
|
|
|
|
DataColumns.NOTE_ID + "=?",
|
|
|
|
|
new String[] { String.valueOf(mNoteId) },
|
|
|
|
|
null
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (cursor != null) {
|
|
|
|
|
if (cursor.moveToFirst()) {
|
|
|
|
|
do {
|
|
|
|
|
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
|
|
|
|
|
if (DataConstants.NOTE.equals(type)) {
|
|
|
|
|
// 加载文本数据
|
|
|
|
|
mContent = cursor.getString(DATA_CONTENT_COLUMN);
|
|
|
|
|
mMode = cursor.getInt(DATA_MODE_COLUMN);
|
|
|
|
|
mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN)); // 关联数据项ID
|
|
|
|
|
} else if (DataConstants.CALL_NOTE.equals(type)) {
|
|
|
|
|
// 加载通话记录数据
|
|
|
|
|
mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));
|
|
|
|
|
} else {
|
|
|
|
|
Log.d(TAG, "未知数据类型: " + type);
|
|
|
|
|
}
|
|
|
|
|
} while (cursor.moveToNext());
|
|
|
|
|
}
|
|
|
|
|
cursor.close();
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "无法找到便签数据,ID: " + mNoteId);
|
|
|
|
|
throw new IllegalArgumentException("无效的便签数据ID: " + mNoteId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建新的空便签(工厂方法)
|
|
|
|
|
* @param context 上下文
|
|
|
|
|
* @param folderId 文件夹ID
|
|
|
|
|
* @param widgetId 关联小部件ID
|
|
|
|
|
* @param widgetType 小部件类型
|
|
|
|
|
* @param defaultBgColorId 默认背景色ID
|
|
|
|
|
*/
|
|
|
|
|
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
|
|
|
|
|
int widgetType, int defaultBgColorId) {
|
|
|
|
|
WorkingNote note = new WorkingNote(context, folderId);
|
|
|
|
|
note.setBgColorId(defaultBgColorId); // 设置默认背景
|
|
|
|
|
note.setWidgetId(widgetId); // 绑定小部件
|
|
|
|
|
note.setWidgetType(widgetType);
|
|
|
|
|
return note;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 加载现有便签(工厂方法)
|
|
|
|
|
* @param context 上下文
|
|
|
|
|
* @param id 便签ID
|
|
|
|
|
*/
|
|
|
|
|
public static WorkingNote load(Context context, long id) {
|
|
|
|
|
return new WorkingNote(context, id, 0); // 文件夹ID后续从数据库加载
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 保存便签到数据库(核心方法)
|
|
|
|
|
* @return 是否保存成功
|
|
|
|
|
*/
|
|
|
|
|
public synchronized boolean saveNote() {
|
|
|
|
|
if (isWorthSaving()) { // 检查是否值得保存
|
|
|
|
|
// 若为新便签,生成数据库ID
|
|
|
|
|
if (!existInDatabase()) {
|
|
|
|
|
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
|
|
|
|
|
Log.e(TAG, "创建新便签失败,ID: " + mNoteId);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 同步数据到数据库
|
|
|
|
|
mNote.syncNote(mContext, mNoteId);
|
|
|
|
|
|
|
|
|
|
// 若关联小部件,通知UI更新
|
|
|
|
|
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
|
|
|
|
|
mWidgetType != Notes.TYPE_WIDGET_INVALIDE &&
|
|
|
|
|
mNoteSettingStatusListener != null) {
|
|
|
|
|
mNoteSettingStatusListener.onWidgetChanged();
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false; // 无需保存
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 辅助方法 ----------------------------------------
|
|
|
|
|
/**
|
|
|
|
|
* 检查便签是否已持久化到数据库
|
|
|
|
|
*/
|
|
|
|
|
public boolean existInDatabase() {
|
|
|
|
|
return mNoteId > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 判断便签是否值得保存(过滤无效操作)
|
|
|
|
|
* 规则:
|
|
|
|
|
* - 已标记删除
|
|
|
|
|
* - 新便签且内容为空
|
|
|
|
|
* - 已存在但无修改
|
|
|
|
|
*/
|
|
|
|
|
private boolean isWorthSaving() {
|
|
|
|
|
return !(mIsDeleted ||
|
|
|
|
|
(!existInDatabase() && TextUtils.isEmpty(mContent)) ||
|
|
|
|
|
(existInDatabase() && !mNote.isLocalModified()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 属性设置方法 ------------------------------------
|
|
|
|
|
/**
|
|
|
|
|
* 设置提醒时间
|
|
|
|
|
* @param date 时间戳
|
|
|
|
|
* @param set 是否启用提醒
|
|
|
|
|
*/
|
|
|
|
|
public void setAlertDate(long date, boolean set) {
|
|
|
|
|
if (date != mAlertDate) {
|
|
|
|
|
mAlertDate = date;
|
|
|
|
|
mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));
|
|
|
|
|
}
|
|
|
|
|
if (mNoteSettingStatusListener != null) {
|
|
|
|
|
mNoteSettingStatusListener.onClockAlertChanged(date, set); // 通知监听器
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 标记删除状态
|
|
|
|
|
* @param mark 是否标记为删除
|
|
|
|
|
*/
|
|
|
|
|
public void markDeleted(boolean mark) {
|
|
|
|
|
mIsDeleted = mark;
|
|
|
|
|
// 若关联小部件,通知更新
|
|
|
|
|
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID &&
|
|
|
|
|
mWidgetType != Notes.TYPE_WIDGET_INVALIDE &&
|
|
|
|
|
mNoteSettingStatusListener != null) {
|
|
|
|
|
mNoteSettingStatusListener.onWidgetChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 设置背景色ID
|
|
|
|
|
* @param id 颜色资源ID
|
|
|
|
|
*/
|
|
|
|
|
public void setBgColorId(int id) {
|
|
|
|
|
if (id != mBgColorId) {
|
|
|
|
|
mBgColorId = id;
|
|
|
|
|
if (mNoteSettingStatusListener != null) {
|
|
|
|
|
mNoteSettingStatusListener.onBackgroundColorChanged();
|
|
|
|
|
}
|
|
|
|
|
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 切换待办清单模式
|
|
|
|
|
* @param mode 目标模式
|
|
|
|
|
*/
|
|
|
|
|
public void setCheckListMode(int mode) {
|
|
|
|
|
if (mMode != mode) {
|
|
|
|
|
// 触发模式切换回调
|
|
|
|
|
if (mNoteSettingStatusListener != null) {
|
|
|
|
|
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
|
|
|
|
|
}
|
|
|
|
|
mMode = mode;
|
|
|
|
|
mNote.setTextData(TextNote.MODE, String.valueOf(mMode)); // 更新数据模型
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 其他属性设置方法(略,逻辑类似)-------------------
|
|
|
|
|
// ... setWidgetType(), setWidgetId(), setWorkingText(), convertToCallNote() ...
|
|
|
|
|
|
|
|
|
|
// 数据获取方法 ------------------------------------
|
|
|
|
|
public String getContent() {
|
|
|
|
|
return mContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public long getAlertDate() {
|
|
|
|
|
return mAlertDate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int getBgColorResId() {
|
|
|
|
|
return NoteBgResources.getNoteBgResource(mBgColorId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ... 其他getter方法 ...
|
|
|
|
|
|
|
|
|
|
// 监听器接口 --------------------------------------
|
|
|
|
|
/**
|
|
|
|
|
* 便签属性变更监听器接口
|
|
|
|
|
* 用于通知UI层更新(如小部件、背景色变化)
|
|
|
|
|
*/
|
|
|
|
|
public interface NoteSettingChangedListener {
|
|
|
|
|
/** 背景色变更 */
|
|
|
|
|
void onBackgroundColorChanged();
|
|
|
|
|
/** 提醒时间设置/取消 */
|
|
|
|
|
void onClockAlertChanged(long date, boolean set);
|
|
|
|
|
/** 小部件内容需更新 */
|
|
|
|
|
void onWidgetChanged();
|
|
|
|
|
/** 待办清单模式切换 */
|
|
|
|
|
void onCheckListModeChanged(int oldMode, int newMode);
|
|
|
|
|
}
|
|
|
|
|
}
|