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.
TEST1231/Note.java

335 lines
14 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.content.ContentProviderOperation; // 导入用于构建批量数据库操作的类
import android.content.ContentProviderResult; // 导入用于接收批量操作结果的类
import android.content.ContentUris; // 导入用于生成URI的类这些URI指向数据库中的特定行
import android.content.ContentValues; // 导入用于存储一组键值对的类,这些键值对将被插入到数据库表中
import android.content.Context; // 导入Android应用上下文类
import android.content.OperationApplicationException; // 导入表示操作应用异常的类
import android.net.Uri; // 导入表示统一资源标识符的类
import android.os.RemoteException; // 导入表示远程过程调用异常的类
import android.util.Log; // 导入用于打印日志的类
import net.micode.notes.data.Notes; // 导入应用自定义的Notes类可能是一个包含多个内部类的数据库模型
import net.micode.notes.data.Notes.CallNote; // 导入Notes类中的CallNote内部类可能代表电话笔记
import net.micode.notes.data.Notes.DataColumns; // 导入Notes类中的DataColumns内部类可能包含数据表的列定义
import net.micode.notes.data.Notes.NoteColumns; // 导入Notes类中的NoteColumns内部类可能包含笔记表的列定义
import net.micode.notes.data.Notes.TextNote; // 导入Notes类中的TextNote内部类可能代表文本笔记
*//1
import java.util.ArrayList; // 导入ArrayList类
public class Note { // 声明一个名为Note的公共类
// 类的成员变量定义(在此代码段中未展示)
private ContentValues mNoteDiffValues; // 用于存储笔记的差异数据,以便后续更新数据库
private NoteData mNoteData; // 可能用于存储笔记的详细数据
private static final String TAG = "Note"; // 用于日志记录的标签
/**
* 创建一个新的笔记ID用于向数据库添加新笔记
*/
public static synchronized long getNewNoteId(Context context, long folderId) {
// 声明一个ContentValues对象用于存储要插入数据库的新笔记的数据
ContentValues values = new ContentValues();
// 获取当前系统时间(毫秒为单位),作为笔记的创建和修改时间
long createdTime = System.currentTimeMillis();
// 向values中添加笔记的创建日期
values.put(NoteColumns.CREATED_DATE, createdTime);
// 向values中添加笔记的修改日期初始时与创建日期相同
values.put(NoteColumns.MODIFIED_DATE, createdTime);
// 向values中添加笔记的类型此处假设Notes.TYPE_NOTE是一个预定义的常量表示笔记类型
values.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
// 向values中添加一个标记表示笔记是否在本地被修改过初始化为1可能表示已修改
values.put(NoteColumns.LOCAL_MODIFIED, 1);
// 向values中添加笔记的父ID即它所属的文件夹ID
values.put(NoteColumns.PARENT_ID, folderId);
// 使用ContentResolver向数据库的Notes.CONTENT_NOTE_URI插入新笔记的数据并返回新插入笔记的URI
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
// 初始化noteId为0用于存储从URI解析出的新笔记ID
long noteId = 0;
try {
// 从返回的URI的路径段中获取第二个元素索引为1因为索引从0开始并将其转换为long类型作为新笔记的ID
noteId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
// 如果转换过程中发生数字格式异常则记录错误日志并将noteId保持为0
Log.e(TAG, "Get note id error :" + e.toString());
noteId = 0;
}
// 检查noteId是否为-1虽然在此处不太可能因为Long.valueOf不会返回-1
// 但为了代码的健壮性,还是进行了检查
if (noteId == -1) {
// 如果noteId为-1则抛出IllegalStateException异常表示获得了错误的笔记ID
throw new IllegalStateException("Wrong note id:" + noteId);
}
// 返回解析出的新笔记ID
return noteId;
}
}*//2
// Note类的构造方法
public Note() {
// 初始化mNoteDiffValues用于存储笔记的差异数据这些数据通常用于更新数据库中的笔记
mNoteDiffValues = new ContentValues();
// 初始化mNoteData可能用于存储笔记的详细数据如文本、语音等
mNoteData = new NoteData();
}
// 设置笔记的某个键值对数据
public void setNoteValue(String key, String value) {
// 将键值对存储到mNoteDiffValues中准备用于更新数据库
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方法将文本数据存储到mNoteData中
mNoteData.setTextData(key, value);
}
// 设置文本数据的ID
public void setTextDataId(long id) {
// 调用mNoteData的setTextDataId方法设置文本数据的ID
mNoteData.setTextDataId(id);
}
// 获取文本数据的ID
public long getTextDataId() {
// 返回mNoteData中存储的文本数据ID
return mNoteData.mTextDataId;
}
// 设置通话数据的ID
public void setCallDataId(long id) {
// 调用mNoteData的setCallDataId方法设置通话数据的ID
mNoteData.setCallDataId(id);
}
// 设置通话数据的某个键值对数据
public void setCallData(String key, String value) {
// 调用mNoteData的setCallData方法将通话数据存储到mNoteData中
mNoteData.setCallData(key, value);
}
// 检查笔记是否已本地修改
public boolean isLocalModified() {
// 如果mNoteDiffValues中有数据或者mNoteData标记为已修改则返回true
return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified();
}
// 同步笔记到服务器或数据库
public boolean syncNote(Context context, long noteId) {
// 检查传入的noteId是否有效如果小于等于0则抛出异常
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
// 如果笔记没有本地修改则不需要同步直接返回true
if (!isLocalModified()) {
return true;
}
*//3
/**
* In theory, once data changed, the note should be updated on {@link NoteColumns#LOCAL_MODIFIED} and
* {@link NoteColumns#MODIFIED_DATE}. For data safety, though update note fails, we also update the
* note data info
*/
if (context.getContentResolver().update(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null,
null) == 0) {
// 如果更新返回0表示没有更新任何行这通常不应该发生
Log.e(TAG, "Update note error, should not happen");
// 不要返回,继续执行后续代码
}
// 清除mNoteDiffValues中的数据因为已经尝试更新到数据库
mNoteDiffValues.clear();
// 检查mNoteData是否标记为已修改并尝试将其推送到ContentResolver
if (mNoteData.isLocalModified()
&& (mNoteData.pushIntoContentResolver(context, noteId) == null)) {
// 如果mNoteData标记为已修改但推送失败则返回false
return false;
}
// 如果所有操作都成功则返回true
return true;
}
// NoteData内部类定义开始
private class NoteData {
// 存储文本数据的ID
private long mTextDataId;
// 存储文本数据的ContentValues
private ContentValues mTextDataValues;
// 存储通话数据的ID
private long mCallDataId;
// 存储通话数据的ContentValues
private ContentValues mCallDataValues;
// 用于日志记录的TAG
private static final String TAG = "NoteData";
// NoteData的构造方法
public NoteData() {
// 初始化ContentValues对象
mTextDataValues = new ContentValues();
mCallDataValues = new ContentValues();
// 初始化数据ID为0表示还没有关联的数据
mTextDataId = 0;
mCallDataId = 0;
}
// 检查NoteData是否已修改
boolean isLocalModified() {
// 如果mTextDataValues或mCallDataValues中有数据则返回true
return mTextDataValues.size() > 0 || mCallDataValues.size() > 0;
}
// 设置文本数据的ID
void setTextDataId(long id) {
// 检查ID是否有效
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0");
}
mTextDataId = id;
}
// 设置通话数据的ID
void setCallDataId(long id) {
// 检查ID是否有效
if (id <= 0) {
throw new IllegalArgumentException("Call data id should larger than 0");
}
mCallDataId = id;
}
// 设置通话数据
void setCallData(String key, String value) {
// 将键值对存储到mCallDataValues中
mCallDataValues.put(key, value);
// 标记笔记为已本地修改,并更新修改日期
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 设置文本数据
void setTextData(String key, String value) {
// 将键值对存储到mTextDataValues中
mTextDataValues.put(key, value);
// 标记笔记为已本地修改,并更新修改日期
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
}
// 将NoteData推送到ContentResolver
Uri pushIntoContentResolver(Context context, long noteId) {
// 检查noteId是否有效
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
// 创建用于批量操作的内容提供者操作列表
ArrayList<ContentProviderOperation> operationList = new ArrayList<>();
ContentProviderOperation.Builder builder = null;
// 如果mTextDataValues中有数据
if(mTextDataValues.size() > 0) {
// 添加noteId到mTextDataValues中
mTextDataValues.put(DataColumns.NOTE_ID, noteId);
// 如果mTextDataId为0表示是新的文本数据
if (mTextDataId == 0) {
// 插入新的文本数据到ContentResolver
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mTextDataValues);
try {
// 从返回的Uri中提取新的文本数据ID
setTextDataId(Long.valueOf(uri.getPathSegments().get(1)));
} catch (NumberFormatException e) {
// 如果提取ID失败则记录错误并清除mTextDataValues
Log.e(TAG, "Insert new text data fail with noteId" + noteId);
mTextDataValues.clear();
return null;
}
} else {
// 如果mTextDataId不为0表示是更新现有的文本数据
builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mTextDataId));
builder.withValues(mTextDataValues);
operationList.add(builder.build());
}
// 清除mTextDataValues中的数据因为已经尝试更新或插入到数据库
mTextDataValues.clear();
}
// 如果mCallDataValues中有数据处理逻辑与mTextDataValues相同
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);
// 检查结果是否有效并返回相应的Uri或null
return (results == null || results.length == 0 || results[0] == null) ? null
: ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId);
} catch (RemoteException e) {
// 记录远程异常
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
return null;
} catch (OperationApplicationException e) {
// 记录操作应用异常
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage()));
return null;
}
}
// 如果没有任何操作要执行则返回null
return null;
}
}
// Note类定义结束
}