You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MiNote/src/WorkingNote.java

459 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.model;
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;
/**
* 工作笔记实体类,处理笔记的核心业务逻辑
* 主要功能包括:
* 1. 创建新笔记/加载已有笔记
* 2. 管理笔记元数据(颜色、提醒时间等)
* 3. 处理笔记内容(文本/清单模式)
* 4. 与小部件交互
* 5. 数据持久化操作
*/
public class WorkingNote {
// 核心笔记对象
private Note mNote;
// 笔记数据库ID0表示新笔记
private long mNoteId;
// 笔记文本内容
private String mContent;
// 笔记模式(普通模式/清单模式)
private int mMode;
// 提醒时间0表示未设置
private long mAlertDate;
// 最后修改时间
private long mModifiedDate;
// 背景颜色资源ID
private int mBgColorId;
// 关联小部件ID
private int mWidgetId;
// 小部件类型
private int mWidgetType;
// 所属文件夹ID
private long mFolderId;
// 上下文对象
private Context mContext;
// 日志标签
private static final String TAG = "WorkingNote";
// 删除标记
private boolean mIsDeleted;
// 设置变更监听器
private NoteSettingChangedListener mNoteSettingStatusListener;
// 数据表查询字段
public static final String[] DATA_PROJECTION = new String[] {
DataColumns.ID,
DataColumns.CONTENT,
DataColumns.MIME_TYPE,
DataColumns.DATA1,
DataColumns.DATA2,
DataColumns.DATA3,
DataColumns.DATA4,
};
// 笔记表查询字段
public static final String[] NOTE_PROJECTION = new String[] {
NoteColumns.PARENT_ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.MODIFIED_DATE
};
// 数据表字段索引
private static final int DATA_ID_COLUMN = 0;
private static final int DATA_CONTENT_COLUMN = 1;
private static final int DATA_MIME_TYPE_COLUMN = 2;
private static final int DATA_MODE_COLUMN = 3;
// 笔记表字段索引
private static final int NOTE_PARENT_ID_COLUMN = 0;
private static final int NOTE_ALERTED_DATE_COLUMN = 1;
private static final int NOTE_BG_COLOR_ID_COLUMN = 2;
private static final int NOTE_WIDGET_ID_COLUMN = 3;
private static final int NOTE_WIDGET_TYPE_COLUMN = 4;
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
/**
* 新建笔记构造函数
* @param context 上下文对象
* @param folderId 所属文件夹ID
*/
private WorkingNote(Context context, long folderId) {
mContext = context;
mAlertDate = 0; // 默认不设置提醒
mModifiedDate = System.currentTimeMillis();
mFolderId = folderId;
mNote = new Note();
mNoteId = 0; // 0表示新笔记
mIsDeleted = false;
mMode = 0; // 默认普通模式
mWidgetType = Notes.TYPE_WIDGET_INVALIDE; // 默认无小部件
}
/**
* 加载已有笔记构造函数
* @param context 上下文对象
* @param noteId 存在的笔记ID
* @param folderId 所属文件夹ID
*/
private WorkingNote(Context context, long noteId, long folderId) {
mContext = context;
mNoteId = noteId;
mFolderId = folderId;
mIsDeleted = false;
mNote = new Note();
loadNote(); // 从数据库加载笔记数据
}
/**
* 加载笔记元数据
* @throws IllegalArgumentException 当笔记不存在时抛出
*/
private void loadNote() {
// 构建笔记URI
Uri noteUri = ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId);
Cursor cursor = mContext.getContentResolver().query(noteUri, 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(); // 加载具体内容数据
}
/**
* 加载笔记内容数据
* @throws IllegalArgumentException 当数据不存在时抛出
*/
private void loadNoteData() {
// 查询数据表
Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
DataColumns.NOTE_ID + "=?", new String[] { String.valueOf(mNoteId) }, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String type = cursor.getString(DATA_MIME_TYPE_COLUMN);
if (DataConstants.NOTE.equals(type)) { // 普通笔记数据
mContent = cursor.getString(DATA_CONTENT_COLUMN);
mMode = cursor.getInt(DATA_MODE_COLUMN);
mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));
} else if (DataConstants.CALL_NOTE.equals(type)) { // 通话记录数据
mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));
} else {
Log.d(TAG, "未知笔记类型:" + 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
* @return 新创建的WorkingNote实例
*/
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
* @return 加载的WorkingNote实例
*/
public static WorkingNote load(Context context, long id) {
return new WorkingNote(context, id, 0);
}
/**
* 保存笔记(同步方法保证线程安全)
* @return 保存是否成功
*/
public synchronized boolean saveNote() {
if (isWorthSaving()) { // 检查是否需要保存
// 处理新笔记的情况
if (!existInDatabase()) {
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
Log.e(TAG, "创建新笔记失败ID" + mNoteId);
return false;
}
}
// 同步数据到数据库
mNote.syncNote(mContext, mNoteId);
// 如果有关联小部件,触发更新
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
&& mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onWidgetChanged();
}
return true;
}
return false;
}
/**
* 检查笔记是否已存在于数据库
* @return 存在返回true
*/
public boolean existInDatabase() {
return mNoteId > 0;
}
/**
* 判断是否需要保存
* 以下情况不需要保存:
* 1. 笔记已标记删除
* 2. 新笔记且内容为空
* 3. 已有笔记且无修改
*/
private boolean isWorthSaving() {
return !(mIsDeleted
|| (!existInDatabase() && TextUtils.isEmpty(mContent))
|| (existInDatabase() && !mNote.isLocalModified()));
}
/**
* 设置笔记设置变更监听器
*/
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
mNoteSettingStatusListener = l;
}
/**
* 设置提醒时间
* @param date 提醒时间戳(毫秒)
* @param set 是否设置提醒true表示设置
*/
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 true表示标记删除
*/
public void markDeleted(boolean mark) {
mIsDeleted = mark;
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
&& mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onWidgetChanged();
}
}
/**
* 设置背景颜色
* @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 模式标识见TextNote常量
*/
public void setCheckListMode(int mode) {
if (mMode != mode) {
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
}
mMode = mode;
mNote.setTextData(TextNote.MODE, String.valueOf(mMode));
}
}
/**
* 设置小部件类型
*/
public void setWidgetType(int type) {
if (type != mWidgetType) {
mWidgetType = type;
mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType));
}
}
/**
* 设置关联小部件ID
*/
public void setWidgetId(int id) {
if (id != mWidgetId) {
mWidgetId = id;
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
}
}
/**
* 更新笔记内容
* @param text 新的文本内容
*/
public void setWorkingText(String text) {
if (!TextUtils.equals(mContent, text)) {
mContent = text;
mNote.setTextData(DataColumns.CONTENT, mContent);
}
}
/**
* 转换为通话记录笔记
* @param phoneNumber 电话号码
* @param callDate 通话时间
*/
public void convertToCallNote(String phoneNumber, long callDate) {
mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));
mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);
// 移动到通话记录专用文件夹
mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER));
}
//============== 获取方法 ==============//
public boolean hasClockAlert() {
return mAlertDate > 0;
}
public String getContent() {
return mContent;
}
public long getAlertDate() {
return mAlertDate;
}
public long getModifiedDate() {
return mModifiedDate;
}
public int getBgColorResId() {
return NoteBgResources.getNoteBgResource(mBgColorId);
}
public int getBgColorId() {
return mBgColorId;
}
public int getTitleBgResId() {
return NoteBgResources.getNoteTitleBgResource(mBgColorId);
}
public int getCheckListMode() {
return mMode;
}
public long getNoteId() {
return mNoteId;
}
public long getFolderId() {
return mFolderId;
}
public int getWidgetId() {
return mWidgetId;
}
public int getWidgetType() {
return mWidgetType;
}
/**
* 笔记设置变更监听接口
*/
public interface NoteSettingChangedListener {
/**
* 背景颜色变更回调
*/
void onBackgroundColorChanged();
/**
* 提醒时间变更回调
* @param date 新的提醒时间
* @param set 是否设置提醒
*/
void onClockAlertChanged(long date, boolean set);
/**
* 小部件变更回调
*/
void onWidgetChanged();
/**
* 清单模式切换回调
* @param oldMode 原模式
* @param newMode 新模式
*/
void onCheckListModeChanged(int oldMode, int newMode);
}
}