目录

1、Note.java

2、WorkingNote.java


1、Note.java

package net.micode.notes.model;import android.content.ContentProviderOperation;//批量的更新、插入、删除数据。
import android.content.ContentProviderResult;//操作的结果
import android.content.ContentUris;//用于添加和获取Uri后面的ID
import android.content.ContentValues;//一种用来存储基本数据类型数据的存储机制
import android.content.Context;//需要用该类来弄清楚调用者的实例
import android.content.OperationApplicationException;//操作应用程序容错
import android.net.Uri;//表示待操作的数据
import android.os.RemoteException;//远程容错
import android.util.Log;//输出日志,比如说出错、警告等public class Note {//   private ContentValues mNoteDiffValues;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 databaseContentValues 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);//ContentResolver()主要是实现外部应用对ContentProvider中的数据//进行添加、删除、修改和查询操作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;}//try-catch异常处理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);}//设置文本数据的IDpublic long getTextDataId() {return mNoteData.mTextDataId;}//得到文本数据的IDpublic void setCallDataId(long id) {mNoteData.setCallDataId(id);}//设置电话号码数据的IDpublic void setCallData(String key, String value) {mNoteData.setCallData(key, value);}//得到电话号码数据的IDpublic 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的操作存储到数据库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();}//把文本数据存入DataColumnsif(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();}//把电话号码数据存入DataColumnsif (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;}}
}

2、WorkingNote.java

package net.micode.notes.model;public class WorkingNote {// Note for the working noteprivate Note mNote;// Note Idprivate long mNoteId;// Note contentprivate String mContent;// Note modeprivate int mMode;private long mAlertDate;private long mModifiedDate;private int mBgColorId;private int mWidgetId;private int mWidgetType;private long mFolderId;private Context mContext;private static final String TAG = "WorkingNote";private boolean mIsDeleted;private NoteSettingChangedListener mNoteSettingStatusListener;// 声明 DATA_PROJECTION字符串数组public static final String[] DATA_PROJECTION = new String[] {DataColumns.ID,DataColumns.CONTENT,DataColumns.MIME_TYPE,DataColumns.DATA1,DataColumns.DATA2,DataColumns.DATA3,DataColumns.DATA4,};// 声明 NOTE_PROJECTION字符串数组public static final String[] NOTE_PROJECTION = new String[] {NoteColumns.PARENT_ID,NoteColumns.ALERTED_DATE,NoteColumns.BG_COLOR_ID,NoteColumns.WIDGET_ID,NoteColumns.WIDGET_TYPE,NoteColumns.MODIFIED_DATE};private static final int DATA_ID_COLUMN = 0;private static final int DATA_CONTENT_COLUMN = 1;private static final int DATA_MIME_TYPE_COLUMN = 2;private static final int DATA_MODE_COLUMN = 3;private static final int NOTE_PARENT_ID_COLUMN = 0;private static final int NOTE_ALERTED_DATE_COLUMN = 1;private static final int NOTE_BG_COLOR_ID_COLUMN = 2;private static final int NOTE_WIDGET_ID_COLUMN = 3;private static final int NOTE_WIDGET_TYPE_COLUMN = 4;private static final int NOTE_MODIFIED_DATE_COLUMN = 5;// New note constructpublic WorkingNote(Context context, long folderId) {mContext = context;mAlertDate = 0;mModifiedDate = System.currentTimeMillis();mFolderId = folderId;mNote = new Note();mNoteId = 0;mIsDeleted = false;mMode = 0;mWidgetType = Notes.TYPE_WIDGET_INVALIDE;}// WorkingNote的构造函数// Existing note constructprivate WorkingNote(Context context, long noteId, long folderId) {mContext = context;mNoteId = noteId;mFolderId = folderId;mIsDeleted = false;mNote = new Note();loadNote();}// 加载Note// 通过数据库调用query函数找到第一个条目private void loadNote() {Cursor cursor = mContext.getContentResolver().query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,null, null);// 若存在,储存相应信息if (cursor != null) {if (cursor.moveToFirst()) {mFolderId = cursor.getLong(NOTE_PARENT_ID_COLUMN);mBgColorId = cursor.getInt(NOTE_BG_COLOR_ID_COLUMN);mWidgetId = cursor.getInt(NOTE_WIDGET_ID_COLUMN);mWidgetType = cursor.getInt(NOTE_WIDGET_TYPE_COLUMN);mAlertDate = cursor.getLong(NOTE_ALERTED_DATE_COLUMN);mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);}cursor.close();// 若不存在,报错} else {Log.e(TAG, "No note with id:" + mNoteId);throw new IllegalArgumentException("Unable to find note with id " + mNoteId);}loadNoteData();}// 加载NoteDataprivate void loadNoteData() {Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,DataColumns.NOTE_ID + "=?", new String[] {String.valueOf(mNoteId)}, null);if (cursor != null) {// 查到信息不为空if (cursor.moveToFirst()) { // 查看第一项是否存在 do {String type = cursor.getString(DATA_MIME_TYPE_COLUMN);if (DataConstants.NOTE.equals(type)) {mContent = cursor.getString(DATA_CONTENT_COLUMN);mMode = cursor.getInt(DATA_MODE_COLUMN);mNote.setTextDataId(cursor.getLong(DATA_ID_COLUMN));} else if (DataConstants.CALL_NOTE.equals(type)) {mNote.setCallDataId(cursor.getLong(DATA_ID_COLUMN));} else {Log.d(TAG, "Wrong note type with type:" + type);}} while (cursor.moveToNext());//查阅所有项,直到为空}cursor.close();} else {Log.e(TAG, "No data with id:" + mNoteId);throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);}}// 创建空的Note// 传参:context,文件夹id,widget,背景颜色public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,int widgetType, int defaultBgColorId) {WorkingNote note = new WorkingNote(context, folderId);// 设定相关属性note.setBgColorId(defaultBgColorId);note.setWidgetId(widgetId);note.setWidgetType(widgetType);return note;}public static WorkingNote load(Context context, long id) {return new WorkingNote(context, id, 0);}// 保存Notepublic synchronized boolean saveNote() {if (isWorthSaving()) { //是否值得保存if (!existInDatabase()) { // 是否存在数据库中if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {Log.e(TAG, "Create new note fail with id:" + mNoteId);return false;}}mNote.syncNote(mContext, mNoteId);/*** Update widget content if there exist any widget of this note*/if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE&& mNoteSettingStatusListener != null) {mNoteSettingStatusListener.onWidgetChanged();}return true;} else {return false;}}// 是否在数据库中存在public boolean existInDatabase() {return mNoteId > 0;}// 是否值得保存private boolean isWorthSaving() {// 被删除,或(不在数据库中 内容为空),或 本地已保存过if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))|| (existInDatabase() && !mNote.isLocalModified())) {return false;} else {return true;}}// 设置mNoteSettingStatusListenerpublic void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {mNoteSettingStatusListener = l;}// 设置AlertDate// 若 mAlertDate与data不同,则更改mAlertDate并设定NoteValuepublic void setAlertDate(long date, boolean set) {if (date != mAlertDate) {mAlertDate = date;mNote.setNoteValue(NoteColumns.ALERTED_DATE, String.valueOf(mAlertDate));}if (mNoteSettingStatusListener != null) {mNoteSettingStatusListener.onClockAlertChanged(date, set);}}// 设定删除标记public void markDeleted(boolean mark) {// 设定标记mIsDeleted = mark;if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {mNoteSettingStatusListener.onWidgetChanged();// 调用mNoteSettingStatusListener的 onWidgetChanged方法}}// 设定背景颜色public void setBgColorId(int id) {if (id != mBgColorId) { //设定条件 id != mBgColorIdmBgColorId = id;if (mNoteSettingStatusListener != null) {mNoteSettingStatusListener.onBackgroundColorChanged();}mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));}}// 设定检查列表模式// 参数:modepublic void setCheckListMode(int mode) {if (mMode != mode) { //设定条件 mMode != modeif (mNoteSettingStatusListener != null) {mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);}mMode = mode;mNote.setTextData(TextNote.MODE, String.valueOf(mMode));}}// 设定WidgetType// 参数:typepublic void setWidgetType(int type) {if (type != mWidgetType) {//设定条件 type != mWidgetTypemWidgetType = type;mNote.setNoteValue(NoteColumns.WIDGET_TYPE, String.valueOf(mWidgetType));// 调用Note的setNoteValue方法更改WidgetType}}// 设定WidgetId// 参数:idpublic void setWidgetId(int id) {if (id != mWidgetId) {//设定条件 id != mWidgetIdmWidgetId = id;mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));// 调用Note的setNoteValue方法更改WidgetId}}// 设定WorkingTex// 参数:更改的textpublic void setWorkingText(String text) {if (!TextUtils.equals(mContent, text)) {//设定条件 mContent, text内容不同mContent = text;mNote.setTextData(DataColumns.CONTENT, mContent);// 调用Note的setTextData方法更改WorkingText}}// 转变mNote的CallData及CallNote信息// 参数:String phoneNumber, long callDatepublic void convertToCallNote(String phoneNumber, long callDate) {mNote.setCallData(CallNote.CALL_DATE, String.valueOf(callDate));mNote.setCallData(CallNote.PHONE_NUMBER, phoneNumber);mNote.setNoteValue(NoteColumns.PARENT_ID, String.valueOf(Notes.ID_CALL_RECORD_FOLDER));}// 判断是否有时钟题型public boolean hasClockAlert() {return (mAlertDate > 0 ? true : false);}// 获取Contentpublic String getContent() {return mContent;}// 获取AlertDatepublic long getAlertDate() {return mAlertDate;}// 获取ModifiedDatepublic long getModifiedDate() {return mModifiedDate;}// 获取背景颜色来源idpublic int getBgColorResId() {return NoteBgResources.getNoteBgResource(mBgColorId);}// 获取背景颜色idpublic int getBgColorId() {return mBgColorId;}// 获取标题背景颜色idpublic int getTitleBgResId() {return NoteBgResources.getNoteTitleBgResource(mBgColorId);}// 获取CheckListModepublic int getCheckListMode() {return mMode;}// 获取便签idpublic long getNoteId() {return mNoteId;}// 获取文件夹idpublic long getFolderId() {return mFolderId;}// 获取WidgetIdpublic int getWidgetId() {return mWidgetId;}// 获取WidgetTypepublic int getWidgetType() {return mWidgetType;}// 创建接口 NoteSettingChangedListener,便签更新监视// 为NoteEditActivity提供接口// 提供函数有public interface NoteSettingChangedListener {  /*** Called when the background color of current note has just changed*/void onBackgroundColorChanged();/*** Called when user set clock*/void onClockAlertChanged(long date, boolean set);/*** Call when user create note from widget*/void onWidgetChanged();/*** Call when switch between check list mode and normal mode* @param oldMode is previous mode before change* @param newMode is new mode*/void onCheckListModeChanged(int oldMode, int newMode);}
}

小米便签源码分析——model包相关推荐

  1. 2022 iapp 云便签源码

    二次开发云便签加强版iapp源码,WPS云便签一款可以对接iapp源码的软件,实现"添加便签,查询便签,删除便签,修改便签"四个功能,不管软件内,软件外.内部直接自己改,外部可以依 ...

  2. php日常工作便签源码,php便签

    取回选项 访问方式 类型 说明 ObsClient::RestoreTierExpedited string 快速取回,取回耗时1~5分钟. ObsClient::RestoreTierStandar ...

  3. tcpdump源码分析——抓包原理

    本篇我们从总体看下tcpdump工具的抓包原理,通过学习了解并掌握其实现的机制,为后续进一步底层操作做准备. 1.1.1.1  如何实现 先来看看包传递过来的流程,如下图.包从网卡到内存,到内核态,最 ...

  4. 小米便签从0到1维护教程

    小米便签开源社区版从0到1维护教程 1.前置条件-------软件的安装: 开发工具:Android studio 下载Android studio 汉化教程 安装请自行解决 SDK版本以及相关文件 ...

  5. 微信支付生成签名和验签SDK源码分析

    目录 一.签名分析 1.1 流程分析 1.构造签名串 2.计算签名值 3.设置请求头 二.源码级别分析 二.获取平台证书分析 三.验签分析 3.1 验签使用场景: 3.2 验证流程: 1.获取微信平台 ...

  6. Django源码分析9:model.py表结构的初始化概述

    django源码分析 本文环境python3.5.2,django1.10.x系列 django源码分析-model概述 Django项目中提供了内置的orm框架,只需要在models.py文件中添加 ...

  7. client-go之listers包源码分析

    listers包源码分析 listers包 admissionregistration包 listers包 从cache.Indexer中获取原生k8s的对象/列表 admissionregistra ...

  8. 65、Spark Streaming:数据接收原理剖析与源码分析

    一.数据接收原理 二.源码分析 入口包org.apache.spark.streaming.receiver下ReceiverSupervisorImpl类的onStart()方法 ###overri ...

  9. heritrix源码分析(未完成。太长了!!)

    Heritrix源码分析(一) 包介绍  序号  包名                   说明 1 org.apache.commons.httpclient      封装了apache的http ...

  10. ZRender源码分析2:Storage(Model层)

    回顾 上一篇请移步:zrender源码分析1:总体结构 本篇进行ZRender的MVC结构中的M进行分析 总体理解 上篇说到,Storage负责MVC层中的Model,也就是模型,对于zrender来 ...

最新文章

  1. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)
  2. Android 编译报错:Could not get resource
  3. BitSet 数字排序
  4. C#可用的日出日落时间类
  5. 第四范式入选CB Insights首届中国金融科技榜单
  6. fedora 不在sudoers文件中_Spring AOP中还有你不知道的JVM Class文件字节码转换知识!...
  7. 数据表 高水位 mysql_Oracle中的高水位(HWM)
  8. File Cabinet Pro for Mac(菜单栏快捷文件管理软件)
  9. Unicode详解zz
  10. Linux串口属性设置
  11. 云南网络文化经营许可证办理,云南办理网络文化经营许可证多少钱?文网文是什么?怎么办理文网文?办理文网文需要什么材料?
  12. 如何将开发好的安卓应用程序发布到安卓市场或商店
  13. Android性能优化—— 黑白屏启动优化
  14. 华为、百度这些大公司都青睐哪些编程语言呢?
  15. pstack命令使用说明
  16. 廖雪峰官方网站python学习笔记:第一个Pyhon程序
  17. recyclerview嵌套recyclerview
  18. 浅谈NDS下GBA卡带烧录代码-1.基础的写入、读取代码
  19. 焊工考试多少分及格?焊工考试答题技巧分享
  20. proxmox关闭屏幕

热门文章

  1. MCTS人工智能围棋
  2. 浏览器UserAgent的趣味史
  3. CDlinux如何制作U盘启动(附带Minidwep-gtk工具)
  4. ubuntu安装aircrack-ng/reaver/minidwep-gtk用来跑pin
  5. Android 系统FaceDetector人脸识别检测,圆形相机预览框,截取图片中的人脸图片(宽高自定义),圆形图片显示。
  6. 基于有限元法的转子动力学建模---Timoshenko梁单元有限元建模
  7. Multisim14 - 运行10版本文件时数码管一直显示为0的问题
  8. 使用GSON解析JSON数据
  9. 【开源】Java身份证号码识别系统
  10. java 分布式系统架构_什么是分布式系统!以及分布式系统架构的优缺点