Compare commits

..

9 Commits

Author SHA1 Message Date
王润泽 fd203c4f0a 完结撒花
11 months ago
王润泽 5d66dc7cf7 除了泛读,全部最后
11 months ago
王润泽 f10635b720 除了泛读报告以外,全部为最后
11 months ago
王润泽 f7b3c00a10 添加了背景切换,欢迎界面
11 months ago
王润泽 1736f1f57a Merge branch 'wangrunze_branch' of https://bdgit.educoder.net/mth9uq3ve/xiaomi_mini
11 months ago
王润泽 96891ded29 完成了背景切换和欢迎界面
11 months ago
王润泽 a8223eb850 实现背景及切换
11 months ago
王润泽 3efc053b12 Merge branch 'develop' of https://bdgit.educoder.net/mth9uq3ve/xiaomi_mini
11 months ago
mth9uq3ve 6a75eafbfe 期中测评的报告以及代码上传
11 months ago

@ -22,7 +22,7 @@
<activity
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="Notes"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
android:uiOptions="splitActionBarWhenNarrow"
@ -43,15 +43,8 @@
android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/NoteTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.INSERT_OR_EDIT" />

@ -22,57 +22,42 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import java.util.HashMap;
// 该代码是一个名为Contact的类用于获取联系人信息。
//代码中定义了一个静态的HashMap变量sContactCache用于缓存联系人信息。sContactCache的键是电话号码值是联系人姓名。
//定义了一个字符串常量CALLER_ID_SELECTION用于查询联系人信息的条件。该条件是通过拼接字符串而得到的包含了查询电话号码相等、数据类型为电话号码、联系人ID在指定范围内等条件。
//代码中定义了一个静态方法getContact用于根据电话号码获取联系人姓名。
public class Contact {
private static HashMap<String, String> sContactCache; // 缓存联系人信息
private static final String TAG = "Contact";//标签
private static HashMap<String, String> sContactCache;
private static final String TAG = "Contact";
private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER
+ ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
+ " AND " + Data.RAW_CONTACT_ID + " IN "
+ "(SELECT raw_contact_id "
+ " FROM phone_lookup"
+ " WHERE min_match = '+')"; // 查询联系人信息的条件
+ " WHERE min_match = '+')";
/**
*
* @param context
* @param phoneNumber
* @return null
*/
// 该方法首先检查缓存中是否已有该电话号码对应的联系人姓名,如果有则返回缓存中的值。如果缓存中没有该电话号码对应的联系人姓名,则通过查询数据库来获取联系人姓名。
// 查询数据库的条件是根据电话号码生成的CALLER_ID_SELECTION。如果查询结果不为空且移动到第一条记录则从结果中提取联系人姓名并将其存入缓存中。如果查询结果为空则返回null。
public static String getContact(Context context, String phoneNumber) {
if (sContactCache == null) {
if(sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
// 查找HashMap中是否已有phoneNumber信息
if (sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);//直接根据键值(电话号码)找到姓名
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));//最小匹配原则查找电话号码
// 查找数据库中phoneNumber的信息
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String[] { Phone.DISPLAY_NAME },
new String [] { Phone.DISPLAY_NAME },
selection,
new String[] { phoneNumber },
null);
// 判定查询结果
if (cursor != null && cursor.moveToFirst()) {
try {
// 找到相关信息
String name = cursor.getString(0);
sContactCache.put(phoneNumber, name);//放入缓存块
sContactCache.put(phoneNumber, name);
return name;
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, " Cursor get string error " + e.toString());
@ -81,8 +66,7 @@ public class Contact {
cursor.close();
}
} else {
// 未找到相关信息
Log.d(TAG, "No contact matched with number:" + phoneNumber);//给出反馈信息
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}
}

@ -17,7 +17,7 @@
package net.micode.notes.data;
import android.net.Uri;
public class Notes {//定义Nodes类初始化参数都赋值成静态量
public class Notes {
public static final String AUTHORITY = "micode_notes";
public static final String TAG = "Notes";
public static final int TYPE_NOTE = 0;
@ -54,14 +54,14 @@ public class Notes {//定义Nodes类初始化参数都赋值成静态量
/**
* Uri to query all notes and folders
*/
public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");//指定笔记的路径
public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");
/**
* Uri to query data
*/
public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");//用于指定数据的路径,类似上面
public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");
public interface NoteColumns {//定义笔记集ID、父集ID、创建日期修改日期等等列名称以及类型做初始化
public interface NoteColumns {
/**
* The unique ID for a row
* <P> Type: INTEGER (long) </P>
@ -167,7 +167,7 @@ public class Notes {//定义Nodes类初始化参数都赋值成静态量
public static final String VERSION = "version";
}
public interface DataColumns {//定义接口给每行数据ID类型所属笔记集ID内容数据等等做定义
public interface DataColumns {
/**
* The unique ID for a row
* <P> Type: INTEGER (long) </P>
@ -241,20 +241,20 @@ public class Notes {//定义Nodes类初始化参数都赋值成静态量
public static final String DATA5 = "data5";
}
public static final class TextNote implements DataColumns {//实现DataColumn接口为数据库查询操作提供数据列名称
public static final class TextNote implements DataColumns {
/**
* Mode to indicate the text in check list mode or not
* <P> Type: Integer 1:check list mode 0: normal mode </P>
*/
public static final String MODE = DATA1;
public static final int MODE_CHECK_LIST = 1;//表示当前文本是否还处于检查列清单的模式
public static final int MODE_CHECK_LIST = 1;
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");//指定路径
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");
}
public static final class CallNote implements DataColumns {

@ -27,7 +27,7 @@ import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相关的名称以及标签
public class NotesDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "note.db";
private static final int DB_VERSION = 4;
@ -42,7 +42,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
private static NotesDatabaseHelper mInstance;
private static final String CREATE_NOTE_TABLE_SQL =//规范定义数据库存储信息的格式以及组成部分
private static final String CREATE_NOTE_TABLE_SQL =
"CREATE TABLE " + TABLE.NOTE + "(" +
NoteColumns.ID + " INTEGER PRIMARY KEY," +
NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
@ -85,7 +85,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
/**
* Increase folder's note count when move note to the folder
*/
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =//设置触发器在笔记集更新的时候增加数量1
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =
"CREATE TRIGGER increase_folder_count_on_update "+
" AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
" BEGIN " +
@ -97,7 +97,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
/**
* Decrease folder's note count when move note from folder
*/
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =//类似的设置触发器在笔记集更新的时候减少数量1
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER =
"CREATE TRIGGER decrease_folder_count_on_update " +
" AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
" BEGIN " +
@ -110,7 +110,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
/**
* Increase folder's note count when insert new note to the folder
*/
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER =//设置触发器在笔记集创建的时候增加数量1
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER =
"CREATE TRIGGER increase_folder_count_on_insert " +
" AFTER INSERT ON " + TABLE.NOTE +
" BEGIN " +
@ -122,7 +122,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
/**
* Decrease folder's note count when delete note from the folder
*/
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER =//设置触发器,在笔记集删除文件的时候-1
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER =
"CREATE TRIGGER decrease_folder_count_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN " +
@ -135,7 +135,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
/**
* Update note's content when insert data with type {@link DataConstants#NOTE}
*/
private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER =//设置触发器用于在笔记中数据更改时进行相应ID字段等的更新
private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER =
"CREATE TRIGGER update_note_content_on_insert " +
" AFTER INSERT ON " + TABLE.DATA +
" WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
@ -210,14 +210,14 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
super(context, DB_NAME, null, DB_VERSION);
}
public void createNoteTable(SQLiteDatabase db) {//创建并管理日志信息表
public void createNoteTable(SQLiteDatabase db) {
db.execSQL(CREATE_NOTE_TABLE_SQL);
reCreateNoteTableTriggers(db);
createSystemFolder(db);
Log.d(TAG, "note table has been created");
}
private void reCreateNoteTableTriggers(SQLiteDatabase db) {//重置触发器
private void reCreateNoteTableTriggers(SQLiteDatabase db) {
db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update");
db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update");
db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_delete");
@ -301,7 +301,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { //定义数据库相
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//用于检查并进行数据库版本的更新,保障版本控制
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
boolean reCreateTriggers = false;
boolean skipV2 = false;

@ -35,7 +35,7 @@ import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE;
public class NotesProvider extends ContentProvider {//定义URL以及匹配规则
public class NotesProvider extends ContentProvider {
private static final UriMatcher mMatcher;
private NotesDatabaseHelper mHelper;
@ -86,12 +86,12 @@ public class NotesProvider extends ContentProvider {//定义URL以及匹配规
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,//执行数据库查询操作
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
Cursor c = null;
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
switch (mMatcher.match(uri)) {//匹配数据库查询关键字
switch (mMatcher.match(uri)) {
case URI_NOTE:
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder);
@ -148,7 +148,7 @@ public class NotesProvider extends ContentProvider {//定义URL以及匹配规
}
@Override
public Uri insert(Uri uri, ContentValues values) {//insert向数据库中插入一条数据信息值
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = mHelper.getWritableDatabase();
long dataId = 0, noteId = 0, insertedId = 0;
switch (mMatcher.match(uri)) {
@ -182,8 +182,7 @@ public class NotesProvider extends ContentProvider {//定义URL以及匹配规
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {//实现删除操作
/*这两个参数通常在一起使用以定义一个特定的删除操作。selection 定义了哪些数据应该被删除,而 selectionArgs 为 selection 中的占位符提供了具体的值。*/
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();
@ -229,7 +228,7 @@ public class NotesProvider extends ContentProvider {//定义URL以及匹配规
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {//更新
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
SQLiteDatabase db = mHelper.getWritableDatabase();

@ -24,8 +24,8 @@ import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
//主要是定义用于处理元数据
public class MetaData extends Task {//继承task是task的子类
public class MetaData extends Task {
private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null;
@ -34,7 +34,7 @@ public class MetaData extends Task {//继承task是task的子类
try {
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
Log.e(TAG, "failed to put related gid");//记录错误日志
Log.e(TAG, "failed to put related gid");
}
setNotes(metaInfo.toString());
setName(GTaskStringUtils.META_NOTE_NAME);
@ -47,10 +47,10 @@ public class MetaData extends Task {//继承task是task的子类
@Override
public boolean isWorthSaving() {
return getNotes() != null;
}//用于判断数据是否值得保存
}
@Override
public void setContentByRemoteJSON(JSONObject js) {//用远程的json设置内容基础操作元
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
if (getNotes() != null) {
try {
@ -64,9 +64,9 @@ public class MetaData extends Task {//继承task是task的子类
}
@Override
public void setContentByLocalJSON(JSONObject js) {//这几个函数都是通过一部分已知的项推算其他未知的
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");//抛出了IllegalAccessError异常表明它不应该被直接调用
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
@Override

@ -20,7 +20,7 @@ import android.database.Cursor;
import org.json.JSONObject;
public abstract class Node {//主要定义一些获取属性值的方法
public abstract class Node {
public static final int SYNC_ACTION_NONE = 0;
public static final int SYNC_ACTION_ADD_REMOTE = 1;
@ -38,7 +38,6 @@ public abstract class Node {//主要定义一些获取属性值的方法
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
public static final int SYNC_ACTION_ERROR = 8;
//为不同的同步类型添加调用编号
private String mGid;
@ -46,7 +45,7 @@ public abstract class Node {//主要定义一些获取属性值的方法
private long mLastModified;
private boolean mDeleted;//设置基础值,定义获取参数的方法
private boolean mDeleted;
public Node() {
mGid = null;
@ -65,9 +64,9 @@ public abstract class Node {//主要定义一些获取属性值的方法
public abstract JSONObject getLocalJSONFromContent();
public abstract int getSyncAction(Cursor c);//根据当前指针刷新缓冲区
public abstract int getSyncAction(Cursor c);
public void setGid(String gid) {//定义各项简单查询操作的返回值
public void setGid(String gid) {
this.mGid = gid;
}
@ -83,7 +82,7 @@ public abstract class Node {//主要定义一些获取属性值的方法
this.mDeleted = deleted;
}
public String getGid() {//this保证指向的还是当前的对象
public String getGid() {
return this.mGid;
}

@ -71,9 +71,9 @@ public class SqlData {
private ContentValues mDiffDataValues;
public SqlData(Context context) {//初始化对象,用于存储数据
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;//一类型的变量为true
mIsCreate = true;
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
@ -82,14 +82,14 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
public SqlData(Context context, Cursor c) {//同样是存储数据另外定义支持冲cursor读入
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;//二类型的变量为false
mIsCreate = false;
loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
private void loadFromCursor(Cursor c) {//上面用到的从cursor读取的函数从存储的各个列获取数据
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
mDataContent = c.getString(DATA_CONTENT_COLUMN);
@ -97,9 +97,9 @@ public class SqlData {
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
public void setContent(@androidx.annotation.NonNull JSONObject js) throws JSONException {//获取json类型的参数并且根据它更新自定义的数据单元中的值
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;//如果有id直接赋值没有则需要在获取
if (mIsCreate || mDataId != dataId) {//初始未设置的数据单元通过它设置内容通过cursor产生的数据元可通过它完成更新
public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
}
mDataId = dataId;
@ -131,7 +131,7 @@ public class SqlData {
}
public JSONObject getContent() throws JSONException {
if (mIsCreate) {//同样的只有通过cursor产生的数据单元可通过这个函数获取数据
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
@ -144,7 +144,7 @@ public class SqlData {
return js;
}
public void commit(long noteId, boolean validateVersion, long version) {//提交数据,并且打上类似于标签的版本号以及验证值
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
@ -162,10 +162,10 @@ public class SqlData {
} else {
if (mDiffDataValues.size() > 0) {
int result = 0;
if (!validateVersion) { // 不验证版本的情况下直接使用ContentResolver更新指定ID的数据
if (!validateVersion) {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
} else { // 需要验证版本的情况下使用ContentResolver进行条件更新操作
} else {
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
" ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE

@ -122,7 +122,7 @@ public class SqlNote {
private ArrayList<SqlData> mDataList;
public SqlNote(Context context) {//定义数据单元存储数据
public SqlNote(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = true;
@ -135,7 +135,7 @@ public class SqlNote {
mParentId = 0;
mSnippet = "";
mType = Notes.TYPE_NOTE;
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;//直接从设置的属性中获取值
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
mOriginParent = 0;
mVersion = 0;
@ -147,14 +147,14 @@ public class SqlNote {
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(c);//从cursor中直接获取变量值
loadFromCursor(c);
mDataList = new ArrayList<SqlData>();
if (mType == Notes.TYPE_NOTE)
loadDataContent();
mDiffNoteValues = new ContentValues();
}
public SqlNote(Context context, long id) {//根据id初始化数据单元
public SqlNote(Context context, long id) {
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = false;
@ -175,7 +175,7 @@ public class SqlNote {
}, null);
if (c != null) {
c.moveToNext();
loadFromCursor(c);//通过调用减少重复代码编写
loadFromCursor(c);
} else {
Log.w(TAG, "loadFromCursor: cursor = null");
}
@ -185,7 +185,7 @@ public class SqlNote {
}
}
private void loadFromCursor(Cursor c) {//直接使用get获得变量值
private void loadFromCursor(Cursor c) {
mId = c.getLong(ID_COLUMN);
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);
@ -200,7 +200,7 @@ public class SqlNote {
mVersion = c.getLong(VERSION_COLUMN);
}
private void loadDataContent() {//这个函数判别查询的数据是否存在,并且读取到数据列表中存储
private void loadDataContent() {
Cursor c = null;
mDataList.clear();
try {
@ -210,12 +210,12 @@ public class SqlNote {
}, null);
if (c != null) {
if (c.getCount() == 0) {
Log.w(TAG, "it seems that the note has not data");//遇到文件为空抛出对应的异常
Log.w(TAG, "it seems that the note has not data");
return;
}
while (c.moveToNext()) {
SqlData data = new SqlData(mContext, c);
mDataList.add(data);//向Datalist中加入读取到的数据
mDataList.add(data);
}
} else {
Log.w(TAG, "loadDataContent: cursor = null");
@ -226,8 +226,7 @@ public class SqlNote {
}
}
public boolean setContent(JSONObject js) {//设置数据单元中变量的值
//如果所需的值存在,直接赋值使用,否则再先进行一步读取
public boolean setContent(JSONObject js) {
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
@ -360,7 +359,7 @@ public class SqlNote {
return true;
}
public JSONObject getContent() {//直接读取的方式将所需的数据读到对应变量
public JSONObject getContent() {
try {
JSONObject js = new JSONObject();
@ -413,7 +412,6 @@ public class SqlNote {
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
//定义一些简单的获取取值的方法
public void setGtaskId(String gid) {
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
@ -442,7 +440,7 @@ public class SqlNote {
return mType == Notes.TYPE_NOTE;
}
public void commit(boolean validateVersion) {//将数据做一定修改提交
public void commit(boolean validateVersion) {
if (mIsCreate) {
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
mDiffNoteValues.remove(NoteColumns.ID);

@ -32,7 +32,7 @@ import org.json.JSONException;
import org.json.JSONObject;
public class Task extends Node {//继承Node类的属性
public class Task extends Node {
private static final String TAG = Task.class.getSimpleName();
private boolean mCompleted;
@ -54,7 +54,7 @@ public class Task extends Node {//继承Node类的属性
mMetaInfo = null;
}
public JSONObject getCreateAction(int actionId) {//创建一个初始的任务对象,并对它赋初值
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject();
try {
@ -103,7 +103,7 @@ public class Task extends Node {//继承Node类的属性
return js;
}
public JSONObject getUpdateAction(int actionId) {//更新任务
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
try {
@ -120,7 +120,7 @@ public class Task extends Node {//继承Node类的属性
// entity_delta
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
if (getNotes() != null) {//如果笔记不为空,更新笔记
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
@ -135,11 +135,11 @@ public class Task extends Node {//继承Node类的属性
return js;
}
public void setContentByRemoteJSON(JSONObject js) {//通过远端的json设置内容的值
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {//如果值已经被json对象所具备则直接进行设置
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
@ -175,7 +175,7 @@ public class Task extends Node {//继承Node类的属性
}
}
public void setContentByLocalJSON(JSONObject js) {//通过本地的json文件来设置内容
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
@ -204,7 +204,7 @@ public class Task extends Node {//继承Node类的属性
}
}
public JSONObject getLocalJSONFromContent() {//通过本地的内容生成json文件
public JSONObject getLocalJSONFromContent() {
String name = getName();
try {
if (mMetaInfo == null) {
@ -216,7 +216,7 @@ public class Task extends Node {//继承Node类的属性
JSONObject js = new JSONObject();
JSONObject note = new JSONObject();
JSONArray dataArray = new JSONArray();//声明所有所要用到的变量
JSONArray dataArray = new JSONArray();
JSONObject data = new JSONObject();
data.put(DataColumns.CONTENT, name);
dataArray.put(data);
@ -227,7 +227,7 @@ public class Task extends Node {//继承Node类的属性
} else {
// synced task
JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);//提取出所有的信息
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
@ -258,11 +258,11 @@ public class Task extends Node {//继承Node类的属性
}
}
public int getSyncAction(Cursor c) {//同步缓存
public int getSyncAction(Cursor c) {
try {
JSONObject noteInfo = null;
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);//更新到最新的笔记信息
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
}
if (noteInfo == null) {
@ -311,14 +311,14 @@ public class Task extends Node {//继承Node类的属性
return SYNC_ACTION_ERROR;
}
public boolean isWorthSaving() {//只要有信息就认为是值得保存的返回true
public boolean isWorthSaving() {
return mMetaInfo != null || (getName() != null && getName().trim().length() > 0)
|| (getNotes() != null && getNotes().trim().length() > 0);
}
public void setCompleted(boolean completed) {
this.mCompleted = completed;
}//进行前面使用过的调用函数返回值的对应
}
public void setNotes(String notes) {
this.mNotes = notes;

@ -30,17 +30,17 @@ import org.json.JSONObject;
import java.util.ArrayList;
public class TaskList extends Node {//同Task一样继承了Node
public class TaskList extends Node {
private static final String TAG = TaskList.class.getSimpleName();
private int mIndex;
private ArrayList<Task> mChildren;//内部含有一个Task的列是任务的序列
private ArrayList<Task> mChildren;
public TaskList() {
super();
mChildren = new ArrayList<Task>();
mIndex = 1;//初始化
mIndex = 1;
}
public JSONObject getCreateAction(int actionId) {
@ -74,7 +74,7 @@ public class TaskList extends Node {//同Task一样继承了Node
return js;
}
public JSONObject getUpdateAction(int actionId) {//更新行动与Task中定义的基本一样
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
try {
@ -104,7 +104,7 @@ public class TaskList extends Node {//同Task一样继承了Node
}
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {//类似的通过远端更新内容
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
@ -129,7 +129,7 @@ public class TaskList extends Node {//同Task一样继承了Node
}
}
public void setContentByLocalJSON(JSONObject js) {//通过本地文件更新内容
public void setContentByLocalJSON(JSONObject js) {
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
@ -215,26 +215,26 @@ public class TaskList extends Node {//同Task一样继承了Node
return SYNC_ACTION_ERROR;
}
//以上都与task定义类似
public int getChildTaskCount() {
return mChildren.size();
}
public boolean addChildTask(Task task) {
boolean ret = false;
if (task != null && !mChildren.contains(task)) {//任务不为空,并且还不在列表中,则将其加入
if (task != null && !mChildren.contains(task)) {
ret = mChildren.add(task);
if (ret) {//成功加入以后继续设置关系
if (ret) {
// need to set prior sibling and parent
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);//设置任务的父子关系
task.setParent(this);
}
}
return ret;
}
public boolean addChildTask(Task task, int index) {//更进一步的实现在指定索引位置插入任务
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
return false;
@ -260,9 +260,9 @@ public class TaskList extends Node {//同Task一样继承了Node
return true;
}
public boolean removeChildTask(Task task) {//移除子任务
public boolean removeChildTask(Task task) {
boolean ret = false;
int index = mChildren.indexOf(task);//查找其索引
int index = mChildren.indexOf(task);
if (index != -1) {
ret = mChildren.remove(task);
@ -281,7 +281,7 @@ public class TaskList extends Node {//同Task一样继承了Node
return ret;
}
public boolean moveChildTask(Task task, int index) {//定向移除对应位置的任务
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
@ -299,7 +299,7 @@ public class TaskList extends Node {//同Task一样继承了Node
return (removeChildTask(task) && addChildTask(task, index));
}
public Task findChildTaskByGid(String gid) {//通过Gid查找任务
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
if (t.getGid().equals(gid)) {
@ -309,7 +309,7 @@ public class TaskList extends Node {//同Task一样继承了Node
return null;
}
public int getChildTaskIndex(Task task) {//获取任务对应的索引
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
@ -323,7 +323,7 @@ public class TaskList extends Node {//同Task一样继承了Node
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
if (task.getGid().equals(gid))//找到一个gid相符的即为所要的任务
if (task.getGid().equals(gid))
return task;
}
return null;

@ -15,26 +15,18 @@
*/
package net.micode.notes.gtask.exception;
/**
* @method: ActionFailureException
* @description:ActionFailureException RuntimeException
*
* serialVersionUID
* @date: 11:05
* @author: Xia Yanbo
*/
public class ActionFailureException extends RuntimeException {
private static final long serialVersionUID = 4425249765923293627L;//序列化,用于验证版本一致性
//构造方法
private static final long serialVersionUID = 4425249765923293627L;
public ActionFailureException() {
super();//用构造方法赋初值,调用父类无参数的构造方法
super();
}
//构造方法
public ActionFailureException(String paramString) {
super(paramString);//调用父类有参数的构造方法
super(paramString);
}
//构造方法
public ActionFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}

@ -14,32 +14,20 @@
* limitations under the License.
*/
package net.micode.notes.gtask.exception;//调用完成异常处理
/**
* @method: NetworkFailureException
* @description:NetworkFailureException Exception
*
* //定义了私有参数serialVersionUID是序列化用于验证版本一致性
* @date: 11:07
* @author: Xia Yanbo
* @param:
* @param:
* @param:
*/
package net.micode.notes.gtask.exception;
public class NetworkFailureException extends Exception {
private static final long serialVersionUID = 2107610287180234136L;//序列化,用于验证版本一致性
//构造方法
private static final long serialVersionUID = 2107610287180234136L;
public NetworkFailureException() {
super();//用构造方法赋初值,调用父类无参数的构造方法
super();
}
//构造方法
public NetworkFailureException(String paramString) {
super(paramString);//调用父类有参数的构造方法
super(paramString);
}
//构造方法
public NetworkFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}
}

@ -29,21 +29,10 @@ import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;
/**
* @method: GTaskASyncTask
* @description:GTaskASyncTask AsyncTask
*
* 4
* mcontext 访context
* mOnCompleteListener
* mNotifiManager mTaskManager
* @date: 9:01
* @author: Xia Yanbo
*/
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;//序列化,用于验证版本
//声明定义一个接口OnCompleteListener实现放在后面
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
public interface OnCompleteListener {
void onComplete();
}
@ -55,16 +44,7 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private GTaskManager mTaskManager;
private OnCompleteListener mOnCompleteListener;
/**
* @method: GTaskASyncTask
* @description:GTaskASyncTask
* @date: 16:11
* @author: Xia Yanbo
* @param: mcontext 访context
* @param: mOnCompleteListener
* @param: mNotifiManager
* @param: mTaskManager
*/
public GTaskASyncTask(Context context, OnCompleteListener listener) {
mContext = context;
mOnCompleteListener = listener;
@ -72,42 +52,22 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
.getSystemService(Context.NOTIFICATION_SERVICE);
mTaskManager = GTaskManager.getInstance();
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:32
* @author: Xia Yanbo
*/
public void cancelSync() {
mTaskManager.cancelSync();
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:33
* @author: Xia Yanbo
* @param: message
*/
public void publishProgess(String message) {
publishProgress(new String[] {
message
});
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:35
* @author: Xia Yanbo
* @param:tickerIdID
* @param:content
* @return:NULL
*/
private void showNotification(int tickerId, String content) {
Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS;
notification.flags = Notification.FLAG_AUTO_CANCEL;//打上标识,用于判断发送报错信息和通知操作等
notification.flags = Notification.FLAG_AUTO_CANCEL;
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
@ -119,43 +79,24 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
}
// notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
// pendingIntent);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);//直接调用父类的方法
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:46
* @author: Xia Yanbo
* @return:
*/
@Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext)));//获取用户的状态信息
.getSyncAccountName(mContext)));
return mTaskManager.sync(mContext, this);
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:50
* @author: Xia Yanbo
* @param:Progress
*/
@Override
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);//显示正在进行同步操作的通知
if (mContext instanceof GTaskSyncService) {//检查是否是GTaskSyncService的实例。
showNotification(R.string.ticker_syncing, progress[0]);
if (mContext instanceof GTaskSyncService) {
((GTaskSyncService) mContext).sendBroadcast(progress[0]);
// 如果是就调用该服务的sendBroadcast方法发送广播通知其他组件同步的进度。
}
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:57
* @author: Xia Yanbo
* @param:result
*/
@Override
protected void onPostExecute(Integer result) {
if (result == GTaskManager.STATE_SUCCESS) {
@ -170,7 +111,7 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
showNotification(R.string.ticker_cancel, mContext
.getString(R.string.error_sync_cancelled));
}
if (mOnCompleteListener != null) {//如果监听到了报文,创建一个新的线程来通知任务完成(减少主进程时间浪费)
if (mOnCompleteListener != null) {
new Thread(new Runnable() {
public void run() {

@ -33,102 +33,78 @@ import net.micode.notes.data.Notes.TextNote;
import java.util.ArrayList;
/**
* @classname: Note
* @description:便便
* 便
* @date: 2024/1/2 21:31
* @author: Xia Yanbo
*/
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
* @classname: Note
* @description:便
* @date: 2024/1/2 20:36
* @author: Xia Yanbo
* @param:context
* @param:folderId id
* @return:noteIDid
*/
public static synchronized long getNewNoteId(Context context, long folderId) {//控制类的所有实例的并发访问
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);//所属包的id
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);//插入新的便签记录(标记)
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));//获取新笔记纪录的id
} catch (NumberFormatException e) {//获取失败报错
noteId = Long.valueOf(uri.getPathSegments().get(1));
} catch (NumberFormatException e) {
Log.e(TAG, "Get note id error :" + e.toString());
noteId = 0;
}
//如果noteid为-1抛出id错误的信息
if (noteId == -1) {
throw new IllegalStateException("Wrong note id:" + noteId);
}
return noteId;
}
//初始化定义两个变量用来存储便签的数据,一个是存储便签属性、一个是存储便签内容
public Note() {
mNoteDiffValues = new ContentValues();//便签属性
mNoteData = new NoteData();//便签内容
mNoteDiffValues = new ContentValues();
mNoteData = new NoteData();
}
//设置便签的属性
public void setNoteValue(String key, String value) {
mNoteDiffValues.put(key, value);//键值id
mNoteDiffValues.put(NoteColumns.LOCAL_MODIFIED, 1);//本地编辑修改位
mNoteDiffValues.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());//修改日期
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
public long getTextDataId() {
return mNoteData.mTextDataId;
}
//设置通话数据的id
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();
}
/**
* @classname: Note
* @methodname syncNote
* @description:便
* @date: 2024/1/2 20:54
* @author: Xia Yanbo
* @param:context
* @param:noteid便id
* @return:boolean
*/
public boolean syncNote(Context context, long noteId) {
if (noteId <= 0) {
throw new IllegalArgumentException("Wrong note id:" + noteId);
}
//没有修改过则不需要更新
if (!isLocalModified()) {
return true;
}
@ -136,7 +112,7 @@ public class Note {
/**
* 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
* note data info
*/
if (context.getContentResolver().update(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), mNoteDiffValues, null,
@ -144,8 +120,8 @@ public class Note {
Log.e(TAG, "Update note error, should not happen");
// Do not return, fall through
}
mNoteDiffValues.clear();//清除属性
//如果笔记在本地被修改过并且推送至ContentResolver失败则返回false
mNoteDiffValues.clear();
if (mNoteData.isLocalModified()
&& (mNoteData.pushIntoContentResolver(context, noteId) == null)) {
return false;
@ -155,97 +131,86 @@ public class Note {
}
private class NoteData {
private long mTextDataId;//文本数据的id
private long mTextDataId;
private ContentValues mTextDataValues;
private ContentValues mTextDataValues;//存储文本数据的键值对
private long mCallDataId;
private long mCallDataId;//通话数据的id
private ContentValues mCallDataValues;
private ContentValues mCallDataValues;//存储通话数据
private static final String TAG = "NoteData";
private static final String TAG = "NoteData";//记录标签,为日志记录打上标签。
//给新来的见证便签的键值以及id
public NoteData() {
mTextDataValues = new ContentValues();
mCallDataValues = new ContentValues();
mTextDataId = 0;
mCallDataId = 0;
}
//比较文本大小,确定是否被修改过
boolean isLocalModified() {
return mTextDataValues.size() > 0 || mCallDataValues.size() > 0;
}
//设置文本数据的id
void setTextDataId(long id) {
if(id <= 0) {
throw new IllegalArgumentException("Text data id should larger than 0");
}
mTextDataId = id;
}
//设置通话数据的id
void setCallDataId(long id) {
if (id <= 0) {
throw new IllegalArgumentException("Call data id should larger than 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());
}
/**
* @classname: NoteData
* @methodname pushIntoContentResolver
* @description:
* @date: 2024/1/2 21:10
* @author: Xia Yanbo
* @param:noteId便id
* @param:context
* @return:uri
*/
Uri pushIntoContentResolver(Context context, long noteId) {
/**
* Check for safety
*/
//检查笔记的id是否正确
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);
// 如果文本数据ID为0说明是新插入的数据
if (mTextDataId == 0) {
mTextDataValues.put(DataColumns.MIME_TYPE, TextNote.CONTENT_ITEM_TYPE);
Uri uri = context.getContentResolver().insert(Notes.CONTENT_DATA_URI,
mTextDataValues);//设置对应的关键键值,插入新的文本数据
mTextDataValues);
try {
setTextDataId(Long.valueOf(uri.getPathSegments().get(1)));//获取数据的id
} catch (NumberFormatException e) {//获取失败打印错误信息
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 {//创建一个更新操作,并设置更新的数据和条件
} else {
builder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mTextDataId));
builder.withValues(mTextDataValues);
operationList.add(builder.build());//将更新操作添加到操作列表中
operationList.add(builder.build());
}
mTextDataValues.clear();
}
//同理如果通信数据不为空,进行更新操作
if(mCallDataValues.size() > 0) {
mCallDataValues.put(DataColumns.NOTE_ID, noteId);
if (mCallDataId == 0) {
@ -267,19 +232,19 @@ public class Note {
}
mCallDataValues.clear();
}
//行动列表非空
if (operationList.size() > 0) {
try { // 使用内容解析器ContentResolver的applyBatch方法来批量执行操作列表中的操作
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);//返回操作完成后的结果
: 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;
}
}
return null;

@ -31,43 +31,37 @@ import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.tool.ResourceParser.NoteBgResources;
/**
* @classname: WorkingNote
* @description:便便便
* 便
* @date: 2024/1/4 11:03
* @author: Xia Yanbo
*/
public class WorkingNote {
// Note for the working note
private Note mNote;//便签对象
private Note mNote;
// Note Id
private long mNoteId;//便签的id
private long mNoteId;
// Note content
private String mContent;//内容字符串
public String mContent;
// Note mode
private int mMode;//便签所处的模式(任务清单/普通)
private int mMode;
private long mAlertDate;
private long mAlertDate;//提醒时间
private long mModifiedDate;
private long mModifiedDate;//修改日期
private int mBgColorId;
private int mBgColorId;//背景颜色
private int mWidgetId;
private int mWidgetId;//小插件的id号
private int mWidgetType;
private int mWidgetType;//小插件的类型
private long mFolderId;
private long mFolderId;//所属便签包的id号
private Context mContext;
private Context mContext;//便签的上下文
private static final String TAG = "WorkingNote";
private static final String TAG = "WorkingNote";//用于接收日志的标签
private boolean mIsDeleted;
private boolean mIsDeleted;//表示是否已经被删除
private NoteSettingChangedListener mNoteSettingStatusListener;
private NoteSettingChangedListener mNoteSettingStatusListener;//设置一个监听器,监听便签设置的改变
//定义数据的字段
public static final String[] DATA_PROJECTION = new String[] {
DataColumns.ID,
DataColumns.CONTENT,
@ -77,7 +71,7 @@ public class WorkingNote {
DataColumns.DATA3,
DataColumns.DATA4,
};
//定义便签的字段
public static final String[] NOTE_PROJECTION = new String[] {
NoteColumns.PARENT_ID,
NoteColumns.ALERTED_DATE,
@ -86,7 +80,7 @@ public class WorkingNote {
NoteColumns.WIDGET_TYPE,
NoteColumns.MODIFIED_DATE
};
//数据相关的参数
private static final int DATA_ID_COLUMN = 0;
private static final int DATA_CONTENT_COLUMN = 1;
@ -94,7 +88,7 @@ public class WorkingNote {
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;
@ -108,38 +102,19 @@ public class WorkingNote {
private static final int NOTE_MODIFIED_DATE_COLUMN = 5;
// New note construct
/**
* @classname: WorkingNote
* @methodname WorkingNote
* @description:便
* @date: 2024/1/3 19:26
* @author: Xia Yanbo
* @param:context
* @param:folderIdid
*/
private WorkingNote(Context context, long folderId) {
mContext = context;
mAlertDate = 0;
mModifiedDate = System.currentTimeMillis();
mFolderId = folderId;
mNote = new Note();
mNoteId = 0;//初始化笔记id为0
mNoteId = 0;
mIsDeleted = false;
mMode = 0;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
}
// Existing note construct
/**
* @classname: WorkingNote
* @methodname WorkingNote
* @description:使
* @date: 2024/1/3 21:33
* @author: Xia Yanbo
* @param:context
* @param:noteIdid
* @param:folderIdid
*/
private WorkingNote(Context context, long noteId, long folderId) {
mContext = context;
mNoteId = noteId;
@ -148,23 +123,14 @@ public class WorkingNote {
mNote = new Note();
loadNote();
}
/**
* @classname: WorkingNote
* @methodname loadNote
* @description:/便
* @date: 2024/1/3 21:34
* @author: Xia Yanbo
*/
private void loadNote() {
//查询数据库获取与给定笔记id关联的笔记
Cursor cursor = mContext.getContentResolver().query(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mNoteId), NOTE_PROJECTION, null,
null, null);
if (cursor != null) {
//如果cursor不为空移动到结果集的第一行
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);
@ -173,43 +139,33 @@ public class WorkingNote {
mModifiedDate = cursor.getLong(NOTE_MODIFIED_DATE_COLUMN);
}
cursor.close();
} else {//如果找不到关联的笔记抛出异常
} else {
Log.e(TAG, "No note with id:" + mNoteId);
throw new IllegalArgumentException("Unable to find note with id " + mNoteId);
}
// 调用loadNoteData方法继续加载与笔记相关的其他数据标记
loadNoteData();
}
/**
* @classname: WorkingNote
* @methodname loadNoteData
* @description:便
* @date: 2024/1/3 21:48
* @author: Xia Yanbo
*/
private void loadNoteData() {
//查询数据库获取与给定笔记id关联的笔记
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);//获取当前笔记的类型
//如果笔记是普通的笔记获取笔记内容、模式、id等参数完成赋值
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)) {//如果数据是通话数据从数据行中直接获取数据id
} 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());//光标移动到下一行
} while (cursor.moveToNext());
}
cursor.close();
} else {
@ -217,7 +173,7 @@ public class WorkingNote {
throw new IllegalArgumentException("Unable to find note's data with id " + mNoteId);
}
}
//创建一个空的便签设置属性以及资源的id号等等信息
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
int widgetType, int defaultBgColorId) {
WorkingNote note = new WorkingNote(context, folderId);
@ -226,17 +182,15 @@ public class WorkingNote {
note.setWidgetType(widgetType);
return note;
}
//读取便签的内容
public static WorkingNote load(Context context, long id) {
return new WorkingNote(context, id, 0);
}
public synchronized boolean saveNote() {
//检查笔记是否有保存的价值
if (isWorthSaving()) {
if (!existInDatabase()) {
// 如果不在数据库里根据包的id和上下文获取一个新的笔记ID如果获取失败则返回false并记录日志
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {//获取失败返回的id是0
if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
Log.e(TAG, "Create new note fail with id:" + mNoteId);
return false;
}
@ -246,7 +200,6 @@ public class WorkingNote {
/**
* Update widget content if there exist any widget of this note
*
*/
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE
@ -258,13 +211,12 @@ public class WorkingNote {
return false;
}
}
//检查是否位于数据库中
public boolean existInDatabase() {
return mNoteId > 0;
}
//检查便签是否具有保存的价值
private boolean isWorthSaving() {
//如果在数据库中已经存在而本地没有修改,或者便签已被删除了,或者便签为空,不值得保存
if (mIsDeleted || (!existInDatabase() && TextUtils.isEmpty(mContent))
|| (existInDatabase() && !mNote.isLocalModified())) {
return false;
@ -272,11 +224,11 @@ public class WorkingNote {
return true;
}
}
//设置笔记设置状态的监听器为工作状态
public void setOnSettingStatusChangedListener(NoteSettingChangedListener l) {
mNoteSettingStatusListener = l;
}
//设置提醒的日期
public void setAlertDate(long date, boolean set) {
if (date != mAlertDate) {
mAlertDate = date;
@ -286,7 +238,7 @@ public class WorkingNote {
mNoteSettingStatusListener.onClockAlertChanged(date, set);
}
}
//删除标记值
public void markDeleted(boolean mark) {
mIsDeleted = mark;
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
@ -295,7 +247,6 @@ public class WorkingNote {
}
}
//设置背景的颜色id
public void setBgColorId(int id) {
if (id != mBgColorId) {
mBgColorId = id;
@ -305,10 +256,9 @@ public class WorkingNote {
mNote.setNoteValue(NoteColumns.BG_COLOR_ID, String.valueOf(id));
}
}
//设置任务清单模式
public void setCheckListMode(int mode) {
if (mMode != mode) {
//进行任务清单模式必要组件的的设置
if (mNoteSettingStatusListener != null) {
mNoteSettingStatusListener.onCheckListModeChanged(mMode, mode);
}
@ -316,7 +266,7 @@ public class WorkingNote {
mNote.setTextData(TextNote.MODE, String.valueOf(mMode));
}
}
//设定组件相关的类型id等信息
public void setWidgetType(int type) {
if (type != mWidgetType) {
mWidgetType = type;
@ -330,25 +280,24 @@ public class WorkingNote {
mNote.setNoteValue(NoteColumns.WIDGET_ID, String.valueOf(mWidgetId));
}
}
//设置当前工作便签的文本
public void setWorkingText(String text) {
if (!TextUtils.equals(mContent, text)) {
mContent = text;//文本不一样时更新内容
mContent = text;
mNote.setTextData(DataColumns.CONTENT, mContent);
}
}
//将便签转化为通话便签
public 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);
}
//根据需要,返回对应的参数值
public String getContent() {
return mContent;
}
@ -392,13 +341,7 @@ public class WorkingNote {
public int getWidgetType() {
return mWidgetType;
}
/**
* @classname: WorkingNote
* @description:便
*
* @date: 2024/1/4 9:22
* @author: Xia Yanbo
*/
public interface NoteSettingChangedListener {
/**
* Called when the background color of current note has just changed
@ -412,7 +355,6 @@ public class WorkingNote {
/**
* Call when user create note from widget
*
*/
void onWidgetChanged();

@ -43,6 +43,7 @@ import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
@ -97,7 +98,7 @@ import java.util.regex.Pattern;
* @author: Xia Yanbo
*/
public class NoteEditActivity extends Activity implements OnClickListener,
public class NoteEditActivity extends AppCompatActivity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
//定义视图组件的基本数据(后面出现在了操作菜可选项里)
private class HeadViewHolder {

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -36,23 +36,16 @@ import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
/**
* @classname: NoteEditText
* @description:NoteEditText EditText
*
*
* @date: 2023/12/24 9:22
* @author: Xia Yanbo
*/
public class NoteEditText extends EditText {
private static final String TAG = "NoteEditText";//标签,分类接收特定信息
private int mIndex;//声明文本的索引
private static final String TAG = "NoteEditText";
private int mIndex;
private int mSelectionStartBeforeDelete;
//声明字符串常量,标志电话、网址、邮件
private static final String SCHEME_TEL = "tel:" ;
private static final String SCHEME_HTTP = "http:" ;
private static final String SCHEME_EMAIL = "mailto:" ;
//设置映射,将文本内容拼接成完整的网址
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
static {
sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel);
@ -62,65 +55,53 @@ public class NoteEditText extends EditText {
/**
* Call by the {@link NoteEditActivity} to delete or add edit text
* NoteEditActivity
*/
public interface OnTextViewChangeListener {
/**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
* and the text is null
* delete
*/
void onEditTextDelete(int index, String text);
/**
* Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER}
* happen
* enter
*/
void onEditTextEnter(int index, String text);
/**
* Hide or show item option when text change
*
*/
void onTextChange(int index, boolean hasText);
}
//声明文本视图变化的监听器
private OnTextViewChangeListener mOnTextViewChangeListener;
//实例化NoteEditText对象
public NoteEditText(Context context) {
super(context, null);
mIndex = 0;
}
//为本本编辑设置一个索引
public void setIndex(int index) {
mIndex = index;
}
//直接调用父类,定义好文本视图变化的监听器
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener;
}
//NoteEditText的构造函数通过文本编辑风格的参数集实例化
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle);
}
//NoteEditText的构造函数通过文本编辑风格的参数集实例化支持用户自定义风格
public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);//允许自定义风格
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
/**
* @classname: NoteEditText
* @methodname onTouchEvent
* @description:
* @date: 2023/12/24 10:05
* @author: Xia Yanbo
* @param:event
* @return:boolean
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {//对动作事件进行分类的判别
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
@ -131,24 +112,15 @@ public class NoteEditText extends EditText {
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);//直接获取行数
int off = layout.getOffsetForHorizontal(line, x);//从边界起数获得偏移
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
Selection.setSelection(getText(), off);
break;
}
return super.onTouchEvent(event);//再调用父类的方法进行后续的处理
return super.onTouchEvent(event);
}
/**
* @classname: NoteEditText
* @methodname onKeyDown
* @description:
* @date: 2023/12/24 10:15
* @author: Xia Yanbo
* @param:keyCode
* @param:event
* @return:boolean
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
@ -165,16 +137,7 @@ public class NoteEditText extends EditText {
}
return super.onKeyDown(keyCode, event);
}
/**
* @classname: NoteEditText
* @methodname onKeyUp
* @description:
* @date: 2023/12/24 10:15
* @author: Xia Yanbo
* @param:keyCode
* @param:event
* @return:boolean
*/
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
@ -203,20 +166,11 @@ public class NoteEditText extends EditText {
}
return super.onKeyUp(keyCode, event);
}
/**
* @classname: NoteEditText
* @methodname onFocusChanged
* @description:
* @date: 2023/12/24 10:25
* @author: Xia Yanbo
* @param:focused
* @param:direction
* @param:reviouslyFocusedRect
*/
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (mOnTextViewChangeListener != null) {
if (!focused && TextUtils.isEmpty(getText())) {//当没有输入,关注的视图也发生改变,设置隐藏
if (!focused && TextUtils.isEmpty(getText())) {
mOnTextViewChangeListener.onTextChange(mIndex, false);
} else {
mOnTextViewChangeListener.onTextChange(mIndex, true);
@ -224,27 +178,19 @@ public class NoteEditText extends EditText {
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
/**
* @classname: NoteEditText
* @methodname onCreateContextMenu
* @description:
* @date: 2023/12/24 10:34
* @author: Xia Yanbo
* @param:contextMenu
*/
@Override
protected void onCreateContextMenu(ContextMenu menu) {
if (getText() instanceof Spanned) {//检查文本的类型 Spanned是一个接口
int selStart = getSelectionStart();//所选择文本的开始位置
int selEnd = getSelectionEnd();//所选择文本的结束位置
//确定选择开始的较小值和较大值,方便直接做差
if (getText() instanceof Spanned) {
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();
int min = Math.min(selStart, selEnd);
int max = Math.max(selStart, selEnd);
//获取选择的文本范围内获取所有的 URLSpan 对象。URLSpan 是用于表示文本中的链接的。
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);//获取范围
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);
if (urls.length == 1) {
int defaultResId = 0;
//根据URL获取资源
for(String schema: sSchemaActionResMap.keySet()) {
if(urls[0].getURL().indexOf(schema) >= 0) {
defaultResId = sSchemaActionResMap.get(schema);
@ -255,10 +201,9 @@ public class NoteEditText extends EditText {
if (defaultResId == 0) {
defaultResId = R.string.note_link_other;
}
//添加菜单项
menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener(
new OnMenuItemClickListener() {
//设置监听器,放菜单项被点击,触发链接
public boolean onMenuItemClick(MenuItem item) {
// goto a new intent
urls[0].onClick(NoteEditText.this);
@ -267,6 +212,6 @@ public class NoteEditText extends EditText {
});
}
}
super.onCreateContextMenu(menu);//调用父类方法
super.onCreateContextMenu(menu);
}
}

@ -31,6 +31,7 @@ import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@ -78,7 +79,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
public class NotesListActivity extends AppCompatActivity implements OnClickListener, OnItemLongClickListener {
//首页背景变换
private int mode = -1;
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
@ -126,6 +127,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
public static final int NOTES_LISTVIEW_SCROLL_RATE = 30;
private NoteItemData mFocusNoteDataItem;
//表示是否在私密模式
public static int secret_mode = 0;
private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?";
@ -415,11 +418,36 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
if(secret_mode == 0) {
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
else{
String str1 = "444";
String [] PROJECTION = new String [] { //定义一个新的PROJECTION数组只换掉SNIPPET
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE,
NoteColumns.HAS_ATTACHMENT,
NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT,
NoteColumns.PARENT_ID,
// NoteColumns.SNIPPET,
str1,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
};
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
}
private final class BackgroundQueryHandler extends AsyncQueryHandler {
public BackgroundQueryHandler(ContentResolver contentResolver) {
@ -775,7 +803,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
} else {
Log.e(TAG, "Wrong state:" + mState);
}
if(secret_mode == 1)
menu.findItem(R.id.menu_secret).setVisible(false);
else
menu.findItem(R.id.menu_quit_secret).setVisible(false);
if(mode==-1){//decade
menu.findItem(R.id.menu_decade).setVisible(false);
}
@ -823,6 +854,53 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
else if(item.getItemId()==R.id.menu_search) {
onSearchRequested();
}
else if(item.getItemId()==R.id.menu_secret)
{//进入私密模式
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认进入私密模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(NotesListActivity.this,"您已进入私密模式",Toast.LENGTH_SHORT).show();
secret_mode = 1;
startAsyncNotesListQuery();
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){}
});
dialog.show();
startAsyncNotesListQuery();
}
else if(item.getItemId()==R.id.menu_quit_secret)
{ //退出私密模式
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认退出私密模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
secret_mode = 0;
Toast.makeText(NotesListActivity.this,"您已退出私密模式",Toast.LENGTH_SHORT).show();
startAsyncNotesListQuery();
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){}
});
dialog.show();
}
return true;
}

@ -15,7 +15,7 @@
limitations under the License.
-->
<FrameLayout
<FrameLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/list_background"
@ -61,6 +61,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/bg_btn_set_color" />
</LinearLayout>
<LinearLayout
@ -395,8 +396,8 @@
android:layout_marginRight="6dip"
android:layout_marginBottom="-7dip"
android:src="@drawable/selected" />
</FrameLayout>
</LinearLayout>
<ImageButton
android:id="@+id/add_img_btn"
@ -405,5 +406,8 @@
android:layout_marginLeft="7dp"
android:layout_marginTop="600dp"
android:layout_marginBottom="7dp"
android:src="@android:drawable/ic_menu_gallery" />
android:background="@android:drawable/ic_menu_camera"
android:visibility="visible"
tools:visibility="visible" />
</FrameLayout>

@ -44,4 +44,12 @@
<item
android:id="@+id/menu_zio"
android:title="@string/menu_zio"/>
<item
android:id="@+id/menu_secret"
android:title="@string/menu_secret"/>
<item
android:id="@+id/menu_quit_secret"
android:title="@string/menu_quit_secret"/>
</menu>

@ -0,0 +1,7 @@
<resources>
<style name="ThemeOverlay.Notesmaster.FullscreenContainer" parent="">
<item name="fullscreenBackgroundColor">@color/light_blue_900</item>
<item name="fullscreenTextColor">@color/light_blue_A400</item>
</style>
</resources>

@ -71,8 +71,6 @@
<string name="alert_message_delete_note">确认要删除该条便签吗?</string>
<string name="alert_message_delete_folder">确认删除文件夹及所包含的便签吗?</string>
<string name="format_move_notes_to_folder">已将所选 %1$d 条便签移到 %2$s 文件夹</string>
<string name="menu_secret">私密模式</string>
<string name="menu_quit_secret">退出私密模式</string>
<!-- export text -->
<string name="error_sdcard_unmounted">SD卡被占用不能操作</string>
<string name="error_sdcard_export">导出文本时发生错误请检查SD卡</string>

@ -0,0 +1,6 @@
<resources>
<declare-styleable name="FullscreenAttrs">
<attr name="fullscreenBackgroundColor" format="color" />
<attr name="fullscreenTextColor" format="color" />
</declare-styleable>
</resources>

@ -17,4 +17,9 @@
<resources>
<color name="user_query_highlight">#335b5b5b</color>
<color name="light_blue_600">#FF039BE5</color>
<color name="light_blue_900">#FF01579B</color>
<color name="light_blue_A200">#FF40C4FF</color>
<color name="light_blue_A400">#FF00B0FF</color>
<color name="black_overlay">#66000000</color>
</resources>

@ -40,6 +40,8 @@
<!-- notes list string -->
<!--首页背景切换-->
<string name="menu_secret">secret model</string>
<string name="menu_quit_secret">quit secret model</string>
<string name="menu_decade">Background: decade</string>
<string name="menu_zio">Background: zio</string>

@ -16,18 +16,22 @@
-->
<resources>
<style name="TextAppearanceSuper">
<item name="android:textSize">@dimen/text_font_size_super</item>
<item name="android:textColorLink">#0000ff</item>
</style>
<style name="TextAppearanceLarge">
<item name="android:textSize">@dimen/text_font_size_large</item>
<item name="android:textColorLink">#0000ff</item>
</style>
<style name="TextAppearanceMedium">
<item name="android:textSize">@dimen/text_font_size_medium</item>
<item name="android:textColorLink">#0000ff</item>
</style>
<style name="TextAppearanceNormal">
<item name="android:textSize">@dimen/text_font_size_normal</item>
<item name="android:textColorLink">#0000ff</item>
@ -63,7 +67,16 @@
</style>
<style name="NoteActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid">
<item name="android:displayOptions" />
<!-- <item name="android:displayOptions" /> -->
<item name="android:visibility">visible</item>
</style>
<style name="Widget.Theme.Notesmaster.ActionBar.Fullscreen" parent="Widget.AppCompat.ActionBar">
<item name="android:background">@color/black_overlay</item>
</style>
<style name="Widget.Theme.Notesmaster.ButtonBar.Fullscreen" parent="">
<item name="android:background">@color/black_overlay</item>
<item name="android:buttonBarStyle">?android:attr/buttonBarStyle</item>
</style>
</resources>

@ -0,0 +1,16 @@
<resources>
<style name="Theme.Notesmaster" parent="Theme.AppCompat.Light" />
<style name="Theme.Notesmaster.Fullscreen" parent="Theme.Notesmaster">
<item name="android:actionBarStyle">@style/Widget.Theme.Notesmaster.ActionBar.Fullscreen
</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">@null</item>
</style>
<style name="ThemeOverlay.Notesmaster.FullscreenContainer" parent="">
<item name="fullscreenBackgroundColor">@color/light_blue_600</item>
<item name="fullscreenTextColor">@color/light_blue_A200</item>
</style>
</resources>
Loading…
Cancel
Save