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.
xiaomi/src/model/Note.java

377 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;
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
*/
// 创建新笔记ID用于向数据库添加新笔记
public static synchronized long getNewNoteId(Context context, long folderId) {
// 同步方法,确保线程安全
// Create a new note in the database
// 在数据库中创建新笔记
ContentValues values = new ContentValues();
// 创建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);
// 设置本地修改标志为1
values.put(NoteColumns.PARENT_ID, folderId);
// 设置父文件夹ID
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
// 插入数据库并获取URI
long noteId = 0;
// 笔记ID初始化为0
try {
noteId = Long.valueOf(uri.getPathSegments().get(1));
// 从URI中提取笔记ID第二个路径段
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString());
// 记录错误日志
noteId = 0;
}
if (noteId == -1) {
throw new IllegalStateException("Wrong note id:" + noteId);
// 如果笔记ID为-1抛出异常
}
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);
// 设置本地修改标志为1
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
// 设置修改时间为当前时间
}
public void setTextData(String key, String value) {
// 设置文本数据
mNoteData.setTextData(key, value);
// 调用NoteData的setTextData方法
}
public void setTextDataId(long id) {
// 设置文本数据ID
mNoteData.setTextDataId(id);
// 调用NoteData的setTextDataId方法
}
public long getTextDataId() {
// 获取文本数据ID
return mNoteData.mTextDataId;
// 返回NoteData中的文本数据ID
}
public void setCallDataId(long id) {
// 设置通话数据ID
mNoteData.setCallDataId(id);
// 调用NoteData的setCallDataId方法
}
public void setCallData(String key, String value) {
// 设置通话数据
mNoteData.setCallData(key, value);
// 调用NoteData的setCallData方法
}
public boolean isLocalModified() {
// 检查是否有本地修改
return mNoteDiffValues.size() > 0 || mNoteData.isLocalModified();
// 如果笔记差异值非空或NoteData有修改返回true
}
public boolean syncNote(Context context, long noteId) {
// 同步笔记到数据库
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
// 检查笔记ID是否有效
}
if (!isLocalModified()) {
return true;
// 如果没有本地修改,直接返回成功
}
/**
* 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
*/
// 理论上数据改变后应该更新LOCAL_MODIFIED和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");
// 记录错误日志(理论上不应该发生)
// Do not return, fall through
// 不返回,继续执行
}
mNoteDiffValues.clear();
// 清空笔记差异值
if (mNoteData.isLocalModified()
&& (mNoteData.pushIntoContentResolver(context, noteId) == null)) {
// 如果NoteData有修改且推送数据失败
return false;
// 返回失败
}
return true;
// 返回成功
}
private class NoteData {
// 内部类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初始为0
mCallDataId = 0;
// 通话数据ID初始为0
}
boolean isLocalModified() {
// 检查是否有本地修改
return mTextDataValues.size() > 0 || mCallDataValues.size() > 0;
// 如果文本或通话数据差异值非空返回true
}
void setTextDataId(long id) {
// 设置文本数据ID
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0");
// 检查ID是否大于0
}
mTextDataId = id;
// 设置文本数据ID
}
void setCallDataId(long id) {
// 设置通话数据ID
if (id <= 0) {
throw new IllegalArgumentException("Call data id should larger than 0");
// 检查ID是否大于0
}
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) {
// 将数据推送到内容解析器
/**
* Check for safety
*/
// 安全检查
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);
// 插入数据并获取URI
try {
setTextDataId(Long.valueOf(uri.getPathSegments().get(1)));
// 从URI中提取数据ID并设置
} catch (NumberFormatException e) {
Log.e(TAG, "Insert new text data fail with noteId" + noteId);
// 记录错误日志
mTextDataValues.clear();
// 清空文本数据差异值
return null;
// 返回null表示失败
}
} else {
// 如果文本数据ID已存在表示是更新操作
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);
// 插入数据并获取URI
try {
setCallDataId(Long.valueOf(uri.getPathSegments().get(1)));
// 从URI中提取数据ID并设置
} catch (NumberFormatException e) {
Log.e(TAG, "Insert new call data fail with noteId" + noteId);
// 记录错误日志
mCallDataValues.clear();
// 清空通话数据差异值
return null;
// 返回null表示失败
}
} else {
// 如果通话数据ID已存在表示是更新操作
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否则返回null
} 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;
}
}
return null;
// 如果操作列表为空返回null
}
}
}
```