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.
5._Open-source-software-rea.../src/Note.java

254 lines
10 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.

// 包声明和导入必要的Android框架包以及项目特定的数据类
public class Note {
// 私有成员变量,用来保存笔记的修改值和数据内容
private ContentValues mNoteDiffValues;
private NoteData mNoteData;
// 日志标签,方便在日志中识别输出信息来源于哪个类
private static final String TAG = "Note";
/**
* 获取一个新的笔记ID用于添加新的笔记到数据库。
* 该方法是静态同步的确保同一时间只有一个线程可以获取新ID以避免冲突。
*/
public static synchronized long getNewNoteId(Context context, long folderId) {
// 创建一个ContentValues实例用于存储要插入数据库的笔记信息
ContentValues values = new ContentValues();
// 设置创建时间和修改时间为当前时间戳
long createdTime = System.currentTimeMillis();
values.put(NoteColumns.CREATED_DATE, createdTime);
values.put(NoteColumns.MODIFIED_DATE, createdTime);
// 设置笔记类型为普通笔记
values.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
// 标记为本地修改
values.put(NoteColumns.LOCAL_MODIFIED, 1);
// 设置父级文件夹ID
values.put(NoteColumns.PARENT_ID, folderId);
// 插入笔记记录并获取返回的URI
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
// 解析URI路径片段以获得新插入笔记的ID
long noteId = 0;
try {
noteId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString());
noteId = 0;
}
if (noteId == -1) {
throw new IllegalStateException("Wrong note id:" + noteId);
}
return noteId; // 返回新创建的笔记ID
}
// 构造函数初始化成员变量
public Note() {
mNoteDiffValues = new ContentValues();
mNoteData = new NoteData();
}
// 设置笔记属性值的方法
public void setNoteValue(String key, String value) {
// 更新或设置指定键对应的值,并标记为本地修改
mNoteDiffValues.put(key, value);
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 设置文本数据的方法
public void setTextData(String key, String value) {
mNoteData.setTextData(key, value);
}
// 设置文本数据ID的方法
public void setTextDataId(long id) {
mNoteData.setTextDataId(id);
}
// 获取文本数据ID的方法
public long getTextDataId() {
return mNoteData.mTextDataId;
}
// 设置通话记录数据ID的方法
public void setCallDataId(long id) {
mNoteData.setCallDataId(id);
}
// 设置通话记录数据的方法
public void setCallData(String key, String value) {
mNoteData.setCallData(key, value);
}
// 检查是否有本地修改过的数据
public boolean isLocalModified() {
return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified();
}
/**
* 同步笔记到数据库的方法。
* 如果笔记ID无效则抛出异常如果没有本地修改则直接返回true。
* 尝试更新笔记记录,即使失败也会继续尝试更新数据部分。
*/
public boolean syncNote(Context context, long noteId) {
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
if (!isLocalModified()) {
return true;
}
// 更新笔记的基本信息
if (context.getContentResolver().update(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null,
null) == 0) {
Log.e(TAG, "Update note error, should not happen");
// 即使更新失败也继续执行后续操作
}
mNoteDiffValues.clear(); // 清除已经同步的内容
// 同步额外的数据(如文本或通话记录)
if (mNoteData.isLocalModified()
&& (mNoteData.pushIntoContentResolver(context, noteId) == null)) {
return false;
}
return true;
}
// 内部类NoteData用来处理与笔记关联的详细数据
private class NoteData {
// 成员变量包括文本数据ID、通话记录数据ID及其对应的值集合
private long mTextDataId;
private ContentValues mTextDataValues;
private long mCallDataId;
private ContentValues mCallDataValues;
// 日志标签
private static final String TAG = "NoteData";
// 构造函数初始化成员变量
public NoteData() {
mTextDataValues = new ContentValues();
mCallDataValues = new ContentValues();
mTextDataId = 0;
mCallDataId = 0;
}
// 检查是否有本地修改过的数据
boolean isLocalModified() {
return mTextDataValues.size() > 0 || mCallDataValues.size() > 0;
}
// 设置文本数据ID的方法
void setTextDataId(long id) {
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0");
}
mTextDataId = id;
}
// 设置通话记录数据ID的方法
void setCallDataId(long id) {
if (id <= 0) {
throw new IllegalArgumentException("Call data id should larger than 0");
}
mCallDataId = id;
}
// 设置通话记录数据的方法
void setCallData(String key, String value) {
mCallDataValues.put(key, value);
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 设置文本数据的方法
void setTextData(String key, String value) {
mTextDataValues.put(key, value);
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
/**
* 将数据推送到ContentResolver进行数据库更新或插入。
* 对于文本数据和通话记录数据分别根据是否已有ID来决定是更新还是插入新记录。
*/
Uri pushIntoContentResolver(Context context, long noteId) {
// 参数校验
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
ArrayList<ContentProviderOperation> operationList = new ArrayList<>();
ContentProviderOperation.Builder builder = null;
// 处理文本数据
if(mTextDataValues.size() > 0) {
mTextDataValues.put(DataColumns.NOTE_ID, noteId);
if (mTextDataId == 0) {
// 插入新的文本数据记录
mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE);
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mTextDataValues);
try {
setTextDataId(Long.valueOf(uri.getPathSegments().get(1)));
} catch (NumberFormatException e) {
Log.e(TAG, "Insert new text data fail with noteId" + noteId);
mTextDataValues.clear();
return null;
}
} else {
// 更新现有的文本数据记录
builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mTextDataId));
builder.withValues(mTextDataValues);
operationList.add(builder.build());
}
mTextDataValues.clear();
}
// 处理通话记录数据
if(mCallDataValues.size() > 0) {
mCallDataValues.put(DataColumns.NOTE_ID, noteId);
if (mCallDataId == 0) {
// 插入新的通话记录数据记录
mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE);
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mCallDataValues);
try {
setCallDataId(Long.valueOf(uri.getPathSegments().get(1)));
} catch (NumberFormatException e) {
Log.e(TAG, "Insert new call data fail with noteId" + noteId);
mCallDataValues.clear();
return null;
}
} else {
// 更新现有的通话记录数据记录
builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mCallDataId));
builder.withValues(mCallDataValues);
operationList.add(builder.build());
}
mCallDataValues.clear();
}
// 执行批量操作
if (operationList.size() > 0) {
try {
ContentProviderResult[] results = context.getContentResolver().applyBatch(
Notes.AUTHORITY, operationList);
return (results == null || results.length == 0 || results[0] == null) ? null
: ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId);
} catch (RemoteException | OperationApplicationException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
return null;
}
}
return null;
}
}
}