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.

268 lines
12 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;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.net.Uri;
import android.os.RemoteException;
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.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import java.util.ArrayList;
public class Note {
private ContentValues mNoteDiffValues; // 存储笔记的差异值
private NoteData mNoteData; // 存储笔记数据
private static final String TAG = "Note"; // 用于日志记录的标签
/**
* Create a new note id for adding a new note to databases
*/
public static synchronized long getNewNoteId(Context context, long folderId) {
// 创建一个新的笔记并插入到数据库中
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); // 设置本地修改标志
values.put(NoteColumns.PARENT_ID, folderId); // 设置父ID为文件夹ID
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values); // 插入笔记
long noteId = 0; // 初始化笔记ID
try {
noteId = Long.valueOf(uri.getPathSegments().get(1)); // 获取新插入笔记的ID
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString()); // 记录错误
noteId = 0; // 设置ID为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
}
// 获取文本数据ID
public long getTextDataId() {
return mNoteData.mTextDataId; // 返回文本数据ID
}
// 设置通话数据ID
public void setCallDataId(long id) {
mNoteData.setCallDataId(id); // 设置通话数据ID
}
// 设置通话数据
public void setCallData(String key, String value) {
mNoteData.setCallData(key, value); // 设置通话数据
}
// 检查笔记是否被本地修改
public boolean isLocalModified() {
return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified(); // 如果有差异值或笔记数据被修改返回true
}
// 同步笔记到数据库
public boolean syncNote(Context context, long noteId) {
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId); // 验证笔记ID
}
if (!isLocalModified()) {
return true; // 如果没有本地修改返回true
}
/**
* 理论上,一旦数据发生变化,笔记应该在 {@link NoteColumns#LOCAL_MODIFIED} 和
* {@link NoteColumns#MODIFIED_DATE} 上更新。为了数据安全,尽管更新笔记失败,我们也更新
* 笔记数据的信息
*/
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; // 如果笔记数据有本地修改且推送失败返回false
}
return true; // 返回成功
}
// 内部类,用于存储笔记数据
private class NoteData {
private long mTextDataId; // 文本数据ID
private ContentValues mTextDataValues; // 存储文本数据的内容值
private long mCallDataId; // 通话数据ID
private ContentValues mCallDataValues; // 存储通话数据的内容值
private static final String TAG = "NoteData"; // 用于日志记录的标签
// 构造函数,初始化笔记数据
public NoteData() {
mTextDataValues = new ContentValues(); // 初始化文本数据内容值
mCallDataValues = new ContentValues(); // 初始化通话数据内容值
mTextDataId = 0; // 初始化文本数据ID
mCallDataId = 0; // 初始化通话数据ID
}
// 检查笔记数据是否被本地修改
boolean isLocalModified() {
return mTextDataValues.size() > 0 || mCallDataValues.size() > 0; // 如果文本数据或通话数据有内容返回true
}
// 设置文本数据ID
void setTextDataId(long id) {
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0"); // 验证文本数据ID
}
mTextDataId = id; // 设置文本数据ID
}
// 设置通话数据ID
void setCallDataId(long id) {
if (id <= 0) {
throw new IllegalArgumentException("Call data id should larger than 0"); // 验证通话数据ID
}
mCallDataId = id; // 设置通话数据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()); // 更新修改日期
}
// 推送数据到内容解析器
Uri pushIntoContentResolver(Context context, long noteId) {
/**
* 安全检查
*/
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId); // 验证笔记ID
}
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>(); // 操作列表
ContentProviderOperation.Builder builder = null; // 操作构建器
if(mTextDataValues.size() > 0) { // 如果有文本数据
mTextDataValues.put(DataColumns.NOTE_ID, noteId); // 设置笔记ID
if (mTextDataId == 0) { // 如果文本数据ID为0表示是新数据
mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE); // 设置MIME类型
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mTextDataValues); // 插入文本数据
try {
setTextDataId(Long.valueOf(uri.getPathSegments().get(1))); // 获取新插入文本数据的ID
} catch (NumberFormatException e) {
Log.e(TAG, "Insert new text data fail with noteId" + noteId); // 记录错误
mTextDataValues.clear(); // 清空文本数据内容值
return null; // 返回null
}
} else { // 如果文本数据ID不为0表示是更新操作
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); // 设置笔记ID
if (mCallDataId == 0) { // 如果通话数据ID为0表示是新数据
mCallDataValues.put(DataColumns.MIME_TYPE, CallNote.CONTENT_ITEM_TYPE); // 设置MIME类型
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mCallDataValues); // 插入通话数据
try {
setCallDataId(Long.valueOf(uri.getPathSegments().get(1))); // 获取新插入通话数据的ID
} catch (NumberFormatException e) {
Log.e(TAG, "Insert new call data fail with noteId" + noteId); // 记录错误
mCallDataValues.clear(); // 清空通话数据内容值
return null; // 返回null
}
} else { // 如果通话数据ID不为0表示是更新操作
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); // 返回笔记URI
} catch (RemoteException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); // 记录错误
return null; // 返回null
} catch (OperationApplicationException e) {
Log.e(TAG, String.format("%s: %s", e.toString(), e.getMessage())); // 记录错误
return null; // 返回null
}
}
return null; // 返回null
}
}
}