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.
123456/src/java/net/micode/notes/model/Note.java

309 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.
* 总体分析
这段 Java 代码定义了Note类其围绕笔记数据的创建、修改以及与内容提供器Content Provider交互进行同步等操作构建逻辑是笔记数据管理的核心类之一。类中不仅包含了用于创建新笔记并获取其ID的方法还定义了针对笔记不同类型数据文本数据、通话数据等的设置方法同时通过判断笔记是否有本地修改来决定是否执行同步操作将修改后的数据更新到对应的数据库中内部的NoteData私有内部类则进一步细化了对笔记附属数据文本、通话相关的管理与操作逻辑整体助力实现笔记数据在应用内准确、有效的维护与持久化存储。
函数分析
getNewNoteId方法
所属类Note
功能通过构建ContentValues对象设置新笔记的创建时间、修改时间、类型、本地修改标志以及所属文件夹ID等初始属性然后利用ContentResolver将这些数据插入到笔记数据库Notes.CONTENT_NOTE_URI接着尝试从返回的Uri中解析出笔记ID若解析出现异常或者获取到的ID为特定错误值如-1则进行相应错误处理最终返回新创建笔记的ID用于生成新笔记并获取其唯一标识符。
Note类构造函数
所属类Note
功能初始化mNoteDiffValues用于存储笔记主要属性变更值的ContentValues对象和mNoteData管理笔记附属数据的NoteData对象为后续对笔记数据的操作准备好相关的数据容器。
setNoteValue方法
所属类Note
功能将传入的键值对添加到mNoteDiffValues中并同时设置本地修改标志以及更新修改时间用于更新笔记的主要属性数据标记其已被修改。
setTextData方法
所属类Note
功能调用内部NoteData对象的setTextData方法传入键值对将文本相关的数据信息添加到对应的ContentValues对象中同时更新笔记的修改相关状态用于设置笔记的文本数据内容。
setTextDataId方法
所属类Note
功能调用内部NoteData对象的setTextDataId方法传入ID值用于设置笔记的文本数据的ID且会对传入ID进行合法性判断大于0不符合则抛出异常。
getTextDataId方法
所属类Note
功能返回内部NoteData对象中记录的文本数据的ID用于获取笔记关联的文本数据的标识符。
setCallDataId方法
所属类Note
功能调用内部NoteData对象的setCallDataId方法传入ID值用于设置笔记的通话数据的ID同样会对传入ID进行合法性判断大于0不符合则抛出异常。
setCallData方法
所属类Note
功能调用内部NoteData对象的setCallData方法传入键值对将通话相关的数据信息添加到对应的ContentValues对象中同时更新笔记的修改相关状态用于设置笔记的通话数据内容。
isLocalModified方法
所属类Note
功能通过判断mNoteDiffValues笔记主要属性变更值以及内部NoteData对象是否有数据变化通过其isLocalModified方法判断返回笔记整体是否有本地修改的布尔值用于确定笔记数据是否发生了本地变更进而决定是否需要执行同步等后续操作。
syncNote方法
所属类Note
功能首先对传入的笔记ID进行合法性判断若笔记无本地修改则直接返回true表示无需同步操作。若有本地修改先尝试通过ContentResolver更新笔记的主要属性利用mNoteDiffValues中的数据更新失败会记录错误日志但继续后续流程接着清空mNoteDiffValues再判断笔记附属数据通过内部NoteData对象判断是否有修改且能否成功推送更新到内容提供器中根据推送结果返回相应布尔值以此实现将本地修改的笔记数据同步到对应数据库的功能。
NoteData类相关函数
构造函数:
所属类Note.NoteDataNote的内部类
功能初始化用于存储文本数据和通话数据的ContentValues对象以及文本数据ID和通话数据ID为后续管理笔记附属数据准备好相关的数据结构和初始值。
isLocalModified方法
所属类Note.NoteDataNote的内部类
功能通过判断文本数据和通话数据对应的ContentValues对象中是否有数据即其size是否大于0返回笔记附属数据是否有本地修改的布尔值用于在外部判断笔记整体是否有变化时提供附属数据部分的修改情况判断依据。
setTextDataId方法
所属类Note.NoteDataNote的内部类
功能对传入的文本数据ID进行合法性判断要求大于0符合则设置到对应的成员变量中不符合则抛出异常用于设置笔记的文本数据的ID保证ID值的有效性。
setCallDataId方法
所属类Note.NoteDataNote的内部类
功能与setTextDataId类似对传入的通话数据ID进行合法性判断大于0符合则设置到对应的成员变量中不符合则抛出异常用于设置笔记的通话数据的ID确保ID值合法合规。
setCallData方法
所属类Note.NoteDataNote的内部类
功能将传入的通话数据相关键值对添加到通话数据对应的ContentValues对象中同时更新外部笔记的修改相关状态用于设置笔记的通话数据内容并标记笔记已被修改。
setTextData方法
所属类Note.NoteDataNote的内部类
功能将传入的文本数据相关键值对添加到文本数据对应的ContentValues对象中同时更新外部笔记的修改相关状态用于设置笔记的文本数据内容并标记笔记已被修改。
pushIntoContentResolver方法
所属类Note.NoteDataNote的内部类
功能先对传入的笔记ID进行合法性判断接着根据文本数据和通话数据对应的ContentValues对象是否有数据分情况进行操作。若有数据设置笔记ID关联若对应数据ID为0则插入新数据到数据库并获取新ID否则构建更新操作添加到操作列表最后若操作列表有元素则通过ContentResolver批量执行操作根据执行结果返回相应Uri或null以此实现将笔记附属数据更新到内容提供器对应的数据库中的功能。
*/
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) {
// Create a new note in the database
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);
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
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;
}
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);
}
public void setTextDataId(long id) {
mNoteData.setTextDataId(id);
}
public long getTextDataId() {
return mNoteData.mTextDataId;
}
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();
}
public boolean syncNote(Context context, long noteId) {
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
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
*/
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)) {
return false;
}
return true;
}
private class NoteData {
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;
}
void setTextDataId(long id) {
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0");
}
mTextDataId = 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());
}
Uri pushIntoContentResolver(Context context, long noteId) {
/**
* Check for safety
*/
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
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 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;
}
}
}