软件工程维护提交

master
sona155 2 years ago
parent 58af26070f
commit 422b03f9f5

@ -1,132 +0,0 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.widget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.util.Log;
import android.widget.RemoteViews;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.tool.ResourceParser;
import net.micode.notes.ui.NoteEditActivity;
import net.micode.notes.ui.NotesListActivity;
public abstract class NoteWidgetProvider extends AppWidgetProvider {
public static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
};
public static final int COLUMN_ID = 0;
public static final int COLUMN_BG_COLOR_ID = 1;
public static final int COLUMN_SNIPPET = 2;
private static final String TAG = "NoteWidgetProvider";
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
ContentValues values = new ContentValues();
values.put(NoteColumns.WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
for (int i = 0; i < appWidgetIds.length; i++) {
context.getContentResolver().update(Notes.CONTENT_NOTE_URI,
values,
NoteColumns.WIDGET_ID + "=?",
new String[] { String.valueOf(appWidgetIds[i])});
}
}
private Cursor getNoteWidgetInfo(Context context, int widgetId) {
return context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
PROJECTION,
NoteColumns.WIDGET_ID + "=? AND " + NoteColumns.PARENT_ID + "<>?",
new String[] { String.valueOf(widgetId), String.valueOf(Notes.ID_TRASH_FOLER) },
null);
}
protected void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
update(context, appWidgetManager, appWidgetIds, false);
}
private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds,
boolean privacyMode) {
for (int i = 0; i < appWidgetIds.length; i++) {
if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) {
int bgId = ResourceParser.getDefaultBgId(context);
String snippet = "";
Intent intent = new Intent(context, NoteEditActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_ID, appWidgetIds[i]);
intent.putExtra(Notes.INTENT_EXTRA_WIDGET_TYPE, getWidgetType());
Cursor c = getNoteWidgetInfo(context, appWidgetIds[i]);
if (c != null && c.moveToFirst()) {
if (c.getCount() > 1) {
Log.e(TAG, "Multiple message with same widget id:" + appWidgetIds[i]);
c.close();
return;
}
snippet = c.getString(COLUMN_SNIPPET);
bgId = c.getInt(COLUMN_BG_COLOR_ID);
intent.putExtra(Intent.EXTRA_UID, c.getLong(COLUMN_ID));
intent.setAction(Intent.ACTION_VIEW);
} else {
snippet = context.getResources().getString(R.string.widget_havenot_content);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
}
if (c != null) {
c.close();
}
RemoteViews rv = new RemoteViews(context.getPackageName(), getLayoutId());
rv.setImageViewResource(R.id.widget_bg_image, getBgResourceId(bgId));
intent.putExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, bgId);
/**
* Generate the pending intent to start host for the widget
*/
PendingIntent pendingIntent = null;
if (privacyMode) {
rv.setTextViewText(R.id.widget_text,
context.getString(R.string.widget_under_visit_mode));
pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], new Intent(
context, NotesListActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
} else {
rv.setTextViewText(R.id.widget_text, snippet);
pendingIntent = PendingIntent.getActivity(context, appWidgetIds[i], intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
rv.setOnClickPendingIntent(R.id.widget_text, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
}
}
protected abstract int getBgResourceId(int bgId);
protected abstract int getLayoutId();
protected abstract int getWidgetType();
}

@ -1,47 +0,0 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.widget;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.tool.ResourceParser;
public class NoteWidgetProvider_2x extends NoteWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.update(context, appWidgetManager, appWidgetIds);
}
@Override
protected int getLayoutId() {
return R.layout.widget_2x;
}
@Override
protected int getBgResourceId(int bgId) {
return ResourceParser.WidgetBgResources.getWidget2xBgResource(bgId);
}
@Override
protected int getWidgetType() {
return Notes.TYPE_WIDGET_2X;
}
}

@ -1,46 +0,0 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.widget;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.tool.ResourceParser;
public class NoteWidgetProvider_4x extends NoteWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.update(context, appWidgetManager, appWidgetIds);
}
protected int getLayoutId() {
return R.layout.widget_4x;
}
@Override
protected int getBgResourceId(int bgId) {
return ResourceParser.WidgetBgResources.getWidget4xBgResource(bgId);
}
@Override
protected int getWidgetType() {
return Notes.TYPE_WIDGET_4X;
}
}

Binary file not shown.

@ -25,7 +25,7 @@ import android.util.Log;
import java.util.HashMap;
public class Contact { //建立联系人类
public class Contact {
private static HashMap<String, String> sContactCache;
private static final String TAG = "Contact";
@ -34,40 +34,38 @@ public class Contact { //建立联系人类
+ " AND " + Data.RAW_CONTACT_ID + " IN "
+ "(SELECT raw_contact_id "
+ " FROM phone_lookup"
+ " WHERE min_match = '+')"; //定义CALLER_ID_SELECTION字符串
+ " WHERE min_match = '+')";
public static String getContact(Context context, String phoneNumber) {
if(sContactCache == null) {
sContactCache = new HashMap<String, String>();
} //获取联系人函数
}
//查找HashMap中是否已经有PhoneNumber的信息有则返回PhoneNumber的信息
if(sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);
}
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
//用游标查找数据库中的PhoneNumber信息
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String [] { Phone.DISPLAY_NAME },
selection,
new String[] { phoneNumber },
null);
//if判断上述cursor的查询结果
if (cursor != null && cursor.moveToFirst()) { //moveToFirst——返回第一条
try { //找到了相关的信息
if (cursor != null && cursor.moveToFirst()) {
try {
String name = cursor.getString(0);
sContactCache.put(phoneNumber, name);
return name;
} catch (IndexOutOfBoundsException e) { //发生异常用catch捕捉
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, " Cursor get string error " + e.toString());
return null;
} finally {
cursor.close();
}
} else { //未找到相关信息
} else {
Log.d(TAG, "No contact matched with number:" + phoneNumber);
return null;
}

@ -18,10 +18,8 @@ package net.micode.notes.data;
import android.net.Uri;
public class Notes {
//final是一个保留关键字用于声明成员变量方法以及本地的变量
public static final String AUTHORITY = "micode_notes";
public static final String TAG = "Notes";
//以下三个常量用于在对notecolumn.TYPE的值进行设置的时候并给它们先给上初始值
public static final int TYPE_NOTE = 0;
public static final int TYPE_FOLDER = 1;
public static final int TYPE_SYSTEM = 2;
@ -57,61 +55,61 @@ public class Notes {
* Uri to query all notes and folders
*/
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 interface NoteColumns {
//定义NoteColumns内的常量用于后续数据库表头的创建
/**
* The unique ID for a row
* <P> Type: INTEGER (long) </P>
*/
public static final String ID = "_id"; //姓名
public static final String ID = "_id";
/**
* The parent's id for note or folder
* <P> Type: INTEGER (long) </P>
*/
public static final String PARENT_ID = "parent_id"; //父母姓名
public static final String PARENT_ID = "parent_id";
/**
* Created data for note or folder
* <P> Type: INTEGER (long) </P>
*/
public static final String CREATED_DATE = "created_date"; //创建的日期
public static final String CREATED_DATE = "created_date";
/**
* Latest modified date
* <P> Type: INTEGER (long) </P>
*/
public static final String MODIFIED_DATE = "modified_date"; //改变后的日期
public static final String MODIFIED_DATE = "modified_date";
/**
* Alert date
* <P> Type: INTEGER (long) </P>
*/
public static final String ALERTED_DATE = "alert_date"; //发出警报的日期
public static final String ALERTED_DATE = "alert_date";
/**
* Folder's name or text content of note
* <P> Type: TEXT </P>
*/
public static final String SNIPPET = "snippet"; //网络、片段
public static final String SNIPPET = "snippet";
/**
* Note's widget id
* <P> Type: INTEGER (long) </P>
*/
public static final String WIDGET_ID = "widget_id"; //应用小插件名
public static final String WIDGET_ID = "widget_id";
/**
* Note's widget type
* <P> Type: INTEGER (long) </P>
*/
public static final String WIDGET_TYPE = "widget_type"; //应用小插件的类型
public static final String WIDGET_TYPE = "widget_type";
/**
* Note's background color's id
@ -124,13 +122,13 @@ public class Notes {
* note, it has at least one attachment
* <P> Type: INTEGER </P>
*/
public static final String HAS_ATTACHMENT = "has_attachment"; //联系
public static final String HAS_ATTACHMENT = "has_attachment";
/**
* Folder's count of notes
* <P> Type: INTEGER (long) </P>
*/
public static final String NOTES_COUNT = "notes_count"; //笔记计数
public static final String NOTES_COUNT = "notes_count";
/**
* The file type: folder or note
@ -142,7 +140,7 @@ public class Notes {
* The last sync id
* <P> Type: INTEGER (long) </P>
*/
public static final String SYNC_ID = "sync_id"; //同步的意思
public static final String SYNC_ID = "sync_id";
/**
* Sign to indicate local modified or not
@ -167,9 +165,9 @@ public class Notes {
* <P> Type : INTEGER (long) </P>
*/
public static final String VERSION = "version";
} //上述常量用于更好地定义便签的一些属性
}
public interface DataColumns { //定义DataColumns内的常量也是用于后续数据库表头的创建
public interface DataColumns {
/**
* The unique ID for a row
* <P> Type: INTEGER (long) </P>
@ -241,7 +239,7 @@ public class Notes {
* <P> Type: TEXT </P>
*/
public static final String DATA5 = "data5";
} //上述变量定义用来存储便签内容和数据
}
public static final class TextNote implements DataColumns {
/**
@ -257,7 +255,7 @@ public class Notes {
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 class CallNote implements DataColumns {
/**
@ -277,5 +275,5 @@ public class Notes {
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note");
} //同上,这里定义的是电话内容的数据结构
}
}

@ -25,30 +25,14 @@ import android.util.Log;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
/*
import android.content.ContentValues;
//用于保存一些数据string double float int ...)信息,这些信息可以被数据库操作时使用。
import android.content.Context;
//加载和访问资源(具体不明)
import android.database.sqlite.SQLiteDatabase;
//主要提供了数据库中对应于添加、删除、更新、查询的操作方法insert、delete、update和query。配合第一个import
import android.database.sqlite.SQLiteOpenHelper;
//用于管理数据的创建以及后续版本的更新帮助
import android.util.Log;
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
//用SQLOpenhelper对一些note和文件进行数据库的操作比如删除文件后将文件里的note也相应地删除
*/
public class NotesDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "note.db";
private static final int DB_VERSION = 4;
public interface TABLE { //interface(接口)分成了note和data被后面的程序使用
public interface TABLE {
public static final String NOTE = "note";
public static final String DATA = "data";
@ -78,7 +62,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," +
NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" +
")";
//都是一些数据库中需要存储的项目名称,加进去也就相当于数据库中创建的表格的表头了
private static final String CREATE_DATA_TABLE_SQL =
"CREATE TABLE " + TABLE.DATA + "(" +
DataColumns.ID + " INTEGER PRIMARY KEY," +
@ -93,11 +77,11 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" +
")";
//同样的,也是一些需要在数据库中存储的项目名称,但是存储的项目不同
private static final String CREATE_DATA_NOTE_ID_INDEX_SQL =
"CREATE INDEX IF NOT EXISTS note_id_index ON " +
TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
//note_id,即便签的编号,这里是创建了一个存储便签编号的表格
/**
* Increase folder's note count when move note to the folder
*/
@ -109,7 +93,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
" WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
" END";
//类似于数据库的Trigger即触发器操作这里表示文件夹中移入一个note之后表格中需要更改哪些数据
/**
* Decrease folder's note count when move note from folder
*/
@ -122,7 +106,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
" AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
" END";
//同样的跟上述一样但这里表示文件夹中移除一个note之后数据库表格需要更新哪些数据
/**
* Increase folder's note count when insert new note to the folder
*/
@ -134,7 +118,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
" WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
" END";
//看上面的注解有“insert”即表示插入一个note之后数据库表格需要更改哪些数据
/**
* Decrease folder's note count when delete note from the folder
*/
@ -147,7 +131,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
" AND " + NoteColumns.NOTES_COUNT + ">0;" +
" END";
//同样上述注解有“delete”即删除一个Note之后数据库表格需要更改哪些数据
/**
* Update note's content when insert data with type {@link DataConstants#NOTE}
*/
@ -160,7 +144,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
" WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
" END";
//在文件夹中对一个Note导入新的数据之后数据库表格需要更改哪些数据
/**
* Update note's content when data with {@link DataConstants#NOTE} type has changed
*/
@ -173,7 +157,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
" WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
" END";
//Note被修改之后changed数据库表格需要更改哪些数据
/**
* Update note's content when data with {@link DataConstants#NOTE} type has deleted
*/
@ -186,7 +170,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" SET " + NoteColumns.SNIPPET + "=''" +
" WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
" END";
//Note删除之后deleted数据库表格需要更改哪些数据
/**
* Delete datas belong to note which has been deleted
*/
@ -197,7 +181,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" DELETE FROM " + TABLE.DATA +
" WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
" END";
//同样,看上述英文注解望文生义--删除已删除的便签之中的数据后数据库表格中需要更改哪些数据
/**
* Delete notes belong to folder which has been deleted
*/
@ -208,7 +192,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" DELETE FROM " + TABLE.NOTE +
" WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
" END";
//删除已删除的文件夹中的便签数据后数据库表格中需要更改哪些数据
/**
* Move notes belong to folder which has been moved to trash folder
*/
@ -221,18 +205,18 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
" SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
" WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
" END";
//还原已经扔进垃圾桶中的便签后数据库表格应做哪些修改
public NotesDatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
//构造函数传入数据库的name and version即其名称和版本
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) {
db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update");
db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update");
@ -250,8 +234,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER);
db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER);
}
//execSQL是数据库操作的API程序之间的接口主要是更改行为的SQL语句。
//在此主要用来重新创建上述已经定义的表格,但需要先删除原有数据库的触发器再重新创建新的数据库
private void createSystemFolder(SQLiteDatabase db) {
ContentValues values = new ContentValues();
@ -286,14 +269,14 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
db.insert(TABLE.NOTE, null, values);
}
//分别创建几个系统文件夹(记录文件夹,根文件夹,临时文件夹,垃圾文件夹)
public void createDataTable(SQLiteDatabase db) {
db.execSQL(CREATE_DATA_TABLE_SQL);
reCreateDataTableTriggers(db);
db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL);
Log.d(TAG, "data table has been created");
}
//创建表格用于存储标签的Data(数据)
private void reCreateDataTableTriggers(SQLiteDatabase db) {
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert");
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update");
@ -303,21 +286,20 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER);
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER);
}
//同上的解释execSQL是数据库的API主要是更改行为的SQL语句但需要先删除原来数据库的触发器再创建新数据库
static synchronized NotesDatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new NotesDatabaseHelper(context);
}
return mInstance;
}
//为了解决同一时刻只能有一个线程执行。就像有时候一个类需要同时被多个类来使用,但又只能被实例化一次,所以就定义一次,让
//其他类使用同一个这个类的实例
@Override
public void onCreate(SQLiteDatabase db) {
createNoteTable(db);
createDataTable(db);
}
//实现上述创建的两个表格oncreate有表示执行实现的意思
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
boolean reCreateTriggers = false;
@ -350,14 +332,14 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
+ "fails");
}
}
//数据库版本的更新,即数据库内容的一些更改
private void upgradeToV2(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE);
db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA);
createNoteTable(db);
createDataTable(db);
}
//upgradeToV2--即更新到V2的版本
private void upgradeToV3(SQLiteDatabase db) {
// drop unused triggers
db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert");
@ -372,9 +354,9 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM);
db.insert(TABLE.NOTE, null, values);
}
//同样的更新到V3版本
private void upgradeToV4(SQLiteDatabase db) {
db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION
+ " INTEGER NOT NULL DEFAULT 0");
} //更新到V4的版本
}
}

@ -37,7 +37,7 @@ import net.micode.notes.data.NotesDatabaseHelper.TABLE;
public class NotesProvider extends ContentProvider {
private static final UriMatcher mMatcher;
//UriMatcher 用于匹配 Uri
private NotesDatabaseHelper mHelper;
private static final String TAG = "NotesProvider";
@ -51,9 +51,7 @@ public class NotesProvider extends ContentProvider {
private static final int URI_SEARCH_SUGGEST = 6;
static {
// 创建UriMatcher时调用UriMatcher(UriMatcher.NO_MATCH)来表示不匹配任何路径的返回码
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//把需要匹配的Uri路径先全部注册上
mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE);
mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM);
mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA);
@ -67,7 +65,6 @@ public class NotesProvider extends ContentProvider {
* x'0A' represents the '\n' character in sqlite. For title and content in the search result,
* we will trim '\n' and white space in order to show more information.
*/
//对 NOTES_SEARCH_PROJECTION 的声明
private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + ","
+ NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + ","
@ -76,8 +73,6 @@ public class NotesProvider extends ContentProvider {
+ "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
+ "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
// 对 NOTES_SNIPPET_SEARCH_QUERY 的声明
private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
+ " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
@ -85,22 +80,18 @@ public class NotesProvider extends ContentProvider {
+ " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
@Override
//Context仅在onCreate()函数中被初始化。 同时对mHelper进行初始化
public boolean onCreate() {
mHelper = NotesDatabaseHelper.getInstance(getContext());
return true;
}
@Override
//使用游标Cursor方法查询Uri在数据库中对应的具体位置
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)) {
//对于不同的Uri匹配值在数据库中查找其对应的条目
case URI_NOTE:
c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null,
sortOrder);
@ -122,7 +113,6 @@ public class NotesProvider extends ContentProvider {
case URI_SEARCH:
case URI_SEARCH_SUGGEST:
if (sortOrder != null || projection != null) {
//出现不合法的参数异常
throw new IllegalArgumentException(
"do not specify sortOrder, selection, selectionArgs, or projection" + "with this query");
}
@ -130,9 +120,7 @@ public class NotesProvider extends ContentProvider {
String searchString = null;
if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) {
if (uri.getPathSegments().size() > 1) {
// 使用getPathSegments()方法得到一个String的List
searchString = uri.getPathSegments().get(1);
// uri.getPathSegments().get(1)为第2个元素
}
} else {
searchString = uri.getQueryParameter("pattern");
@ -151,7 +139,6 @@ public class NotesProvider extends ContentProvider {
}
break;
default:
//throw 来抛出异常
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (c != null) {
@ -161,18 +148,14 @@ public class NotesProvider extends ContentProvider {
}
@Override
//insert即插入一个Uri
public Uri insert(Uri uri, ContentValues values) {
//获得一个可写的数据库WritableDatabase
SQLiteDatabase db = mHelper.getWritableDatabase();
long dataId = 0, noteId = 0, insertedId = 0;
switch (mMatcher.match(uri)) {
//新增一个条目
case URI_NOTE:
insertedId = noteId = db.insert(TABLE.NOTE, null, values);
break;
case URI_DATA:
// 如果存在查找NOTE_ID
if (values.containsKey(DataColumns.NOTE_ID)) {
noteId = values.getAsLong(DataColumns.NOTE_ID);
} else {
@ -184,7 +167,6 @@ public class NotesProvider extends ContentProvider {
throw new IllegalArgumentException("Unknown URI " + uri);
}
// Notify the note uri
//notifyChange来获得一个ContentResolver对象并且对里面的内容作更新
if (noteId > 0) {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null);
@ -195,17 +177,14 @@ public class NotesProvider extends ContentProvider {
getContext().getContentResolver().notifyChange(
ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null);
}
// 返回插入的uri的路径
return ContentUris.withAppendedId(uri, insertedId);
}
@Override
//以下是删除一个Uri
public int delete(Uri uri, String selection, String[] selectionArgs) {
//Uri代表要操作的数据安卓上的可用资源图像音频视频等资源都可以用Uri来表示
int count = 0;
String id = null;
//获得可写的数据库
SQLiteDatabase db = mHelper.getWritableDatabase();
boolean deleteData = false;
switch (mMatcher.match(uri)) {
@ -249,7 +228,6 @@ public class NotesProvider extends ContentProvider {
}
@Override
//更新一个Uri
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0;
String id = null;
@ -289,12 +267,10 @@ public class NotesProvider extends ContentProvider {
return count;
}
//将字符串String解析成规定的格式
private String parseSelection(String selection) {
return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
}
//增加一个便签笔记版本即noteVersion
private void increaseNoteVersion(long id, String selection, String[] selectionArgs) {
StringBuilder sql = new StringBuilder(120);
sql.append("UPDATE ");
@ -316,7 +292,7 @@ public class NotesProvider extends ContentProvider {
}
sql.append(selectString);
}
// execSQL()是数据库的操作函数可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句
mHelper.getWritableDatabase().execSQL(sql.toString());
}

@ -27,38 +27,29 @@ import org.json.JSONObject;
public class MetaData extends Task {
private final static String TAG = MetaData.class.getSimpleName();
//功能得到类的简写名称SimpleName存入字符串TAG中
//实现调用getSimpleName()函数来得到类简写名称结果
private String mRelatedGid = null;
//功能:设置数据,即生成一个初始的,也叫元数据库
//实现调用JSONObject库函数put()Task类中的setNotes ()和setName ()函数
public void setMeta(String gid, JSONObject metaInfo) {
//对函数模块进行注释
try {
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
//将这一对键值放入jsonobject的对象metaInfo中
} catch (JSONException e) {
Log.e(TAG, "failed to put related gid");
//输出错误信息
}
setNotes(metaInfo.toString());
setName(GTaskStringUtils.META_NOTE_NAME);
}
//功能获取相关联的Gid
public String getRelatedGid() {
return mRelatedGid;
}
@Override
//功能:判断当前数据是否为空,若为空则返回“真”,即就是值得保存的
public boolean isWorthSaving() {
return getNotes() != null;
}
@Override
//功能使用远程json数据对象设置元数据内容
//实现调用父类Task中的setContentByRemoteJSON ()函数
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
if (getNotes() != null) {
@ -67,18 +58,16 @@ public class MetaData extends Task {
mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
} catch (JSONException e) {
Log.w(TAG, "failed to get related gid");
//输出警告信息
mRelatedGid = null;
}
}
}
@Override
//功能使用本地json数据对象设置元数据内容一般不用到若用到的话则throw Error即则抛出异常
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
} //传递非法参数异常
}
@Override
public JSONObject getLocalJSONFromContent() {
@ -86,9 +75,8 @@ public class MetaData extends Task {
}
@Override
//功能获取同步动作状态也是一般用不到如果用到则throw抛出异常
public int getSyncAction(Cursor c) {
throw new IllegalAccessError("MetaData:getSyncAction should not be called");
} //传递非法参数异常
}
}

@ -21,32 +21,31 @@ import android.database.Cursor;
import org.json.JSONObject;
public abstract class Node {
//定义了各种关于表征同步状态的常量
public static final int SYNC_ACTION_NONE = 0; // 本地和云端都无可更新内容(即本地和云端内容一致)
public static final int SYNC_ACTION_NONE = 0;
public static final int SYNC_ACTION_ADD_REMOTE = 1; // 需要在远程云端增加内容
public static final int SYNC_ACTION_ADD_REMOTE = 1;
public static final int SYNC_ACTION_ADD_LOCAL = 2; // 需要在本地增加内容
public static final int SYNC_ACTION_ADD_LOCAL = 2;
public static final int SYNC_ACTION_DEL_REMOTE = 3; // 需要在远程云端删除内容
public static final int SYNC_ACTION_DEL_REMOTE = 3;
public static final int SYNC_ACTION_DEL_LOCAL = 4; // 需要在本地删除内容
public static final int SYNC_ACTION_DEL_LOCAL = 4;
public static final int SYNC_ACTION_UPDATE_REMOTE = 5; // 需要将本地内容更新到远程云端
public static final int SYNC_ACTION_UPDATE_REMOTE = 5;
public static final int SYNC_ACTION_UPDATE_LOCAL = 6; // 需要将远程云端内容更新到本地
public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; // 同步出现冲突
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
public static final int SYNC_ACTION_ERROR = 8;
public static final int SYNC_ACTION_ERROR = 8; // 同步出现错误
//上述序号标注的功能在data下的TaskList中有详细的实现过程这里只作粗略的定义详见TaskList
private String mGid;
private String mName;
private long mLastModified; //记录最后一次修改的时间
private long mLastModified;
private boolean mDeleted; //表达是否被删除了
private boolean mDeleted;
public Node() {
mGid = null;

@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*便sqlnotedatanote
SqlData*/
package net.micode.notes.gtask.data;
import android.content.ContentResolver;
@ -37,21 +36,15 @@ import org.json.JSONObject;
public class SqlData {
// 功能得到类的简写名称存入字符串TAG中
// 实现调用getSimpleName ()函数来获取类的简写名称
private static final String TAG = SqlData.class.getSimpleName();
private static final int INVALID_ID = -99999;
//给mDataId设置初始值为-99999
//来自Notes类中定义的DataColumn中的一些常量
// 集合了interface DataColumns中所有SF常量
public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
//下面五行的五个变量是作为SQL表中五列的编号
public static final int DATA_ID_COLUMN = 0;
public static final int DATA_MIME_TYPE_COLUMN = 1;
@ -64,8 +57,6 @@ public class SqlData {
private ContentResolver mContentResolver;
//判断是否直接用Content生成是的话则为true否则的话为false
private boolean mIsCreate;
private long mDataId;
@ -80,14 +71,10 @@ public class SqlData {
private ContentValues mDiffDataValues;
/*
mContentResolverContentProvider
mIsCreate */
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;
mDataId = INVALID_ID; //mDataId置为初始值-99999前面已经叙述过
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
mDataContentData1 = 0;
@ -95,9 +82,6 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
/*
mContentResolverContentProvider
mIsCreate */
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
@ -105,9 +89,6 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
/*
*/
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
@ -116,9 +97,7 @@ public class SqlData {
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
//功能:设置用于共享的数据,并提供异常抛出机制与处理机制
public void setContent(JSONObject js) throws JSONException {
//如果传入的JSONObject对象中有DataColumns.ID这一项则设置否则设为INVALID_ID使用格式
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
@ -151,13 +130,11 @@ public class SqlData {
mDataContentData3 = dataContentData3;
}
//获取共享的数据内容,并提供异常抛出与处理机制
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
//创建JSONObject对象将相关数据放入其中并返回。
JSONObject js = new JSONObject();
js.put(DataColumns.ID, mDataId);
js.put(DataColumns.MIME_TYPE, mDataMimeType);
@ -167,7 +144,6 @@ public class SqlData {
return js;
}
//功能commit函数用于把当前所做的修改保存到数据库
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
@ -206,7 +182,7 @@ public class SqlData {
mDiffDataValues.clear();
mIsCreate = false;
}
//获取当前Id
public long getId() {
return mDataId;
}

@ -37,16 +37,12 @@ import org.json.JSONObject;
import java.util.ArrayList;
/*Description便sqldatanotedata
SqlDataSqlNote */
public class SqlNote {
/* TAG
getSimpleName () */
private static final String TAG = SqlNote.class.getSimpleName();
private static final int INVALID_ID = -99999;
// 集合了interface NoteColumns中所有SF常量17个
public static final String[] PROJECTION_NOTE = new String[] {
NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE,
@ -56,7 +52,6 @@ public class SqlNote {
NoteColumns.VERSION
};
//以下设置17个列的编号
public static final int ID_COLUMN = 0;
public static final int ALERTED_DATE_COLUMN = 1;
@ -91,7 +86,6 @@ public class SqlNote {
public static final int VERSION_COLUMN = 16;
//一下定义了17个内部的变量其中12个可以由content中获得5个需要初始化为0或者new
private Context mContext;
private ContentResolver mContentResolver;
@ -128,10 +122,6 @@ public class SqlNote {
private ArrayList<SqlData> mDataList;
/*
mIsCreate
*/
//构造函数只有context对所有的变量进行初始化
public SqlNote(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
@ -139,9 +129,9 @@ public class SqlNote {
mId = INVALID_ID;
mAlertDate = 0;
mBgColorId = ResourceParser.getDefaultBgId(context);
mCreatedDate = System.currentTimeMillis(); //调用系统函数获得创建时间
mCreatedDate = System.currentTimeMillis();
mHasAttachment = 0;
mModifiedDate = System.currentTimeMillis(); //最后一次修改时间初始化为创建时间
mModifiedDate = System.currentTimeMillis();
mParentId = 0;
mSnippet = "";
mType = Notes.TYPE_NOTE;
@ -153,10 +143,6 @@ public class SqlNote {
mDataList = new ArrayList<SqlData>();
}
/*
mIsCreate */
//构造函数有context和一个数据库的cursor多数变量通过cursor指向的一条记录直接进行初始化
public SqlNote(Context context, Cursor c) {
mContext = context;
mContentResolver = context.getContentResolver();
@ -168,8 +154,6 @@ public class SqlNote {
mDiffNoteValues = new ContentValues();
}
/*
mIsCreate*/
public SqlNote(Context context, long id) {
mContext = context;
mContentResolver = context.getContentResolver();
@ -182,17 +166,16 @@ public class SqlNote {
}
//功能通过id从光标处加载数据
private void loadFromCursor(long id) {
Cursor c = null;
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)",
new String[] {
String.valueOf(id)
}, null); //通过id获得对应的ContentResolver中的cursor
}, null);
if (c != null) {
c.moveToNext();
loadFromCursor(c); //加载数据进行初始化
loadFromCursor(c);
} else {
Log.w(TAG, "loadFromCursor: cursor = null");
}
@ -202,9 +185,7 @@ public class SqlNote {
}
}
//功能:通过游标从光标处加载数据
private void loadFromCursor(Cursor c) {
//直接从一条记录中获得以下变量的初始值
mId = c.getLong(ID_COLUMN);
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);
@ -219,7 +200,6 @@ public class SqlNote {
mVersion = c.getLong(VERSION_COLUMN);
}
//功能通过content机制获取共享数据并加载到数据库当前游标处
private void loadDataContent() {
Cursor c = null;
mDataList.clear();
@ -246,7 +226,6 @@ public class SqlNote {
}
}
//功能设置通过content机制用于共享的数据信息
public boolean setContent(JSONObject js) {
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
@ -380,7 +359,6 @@ public class SqlNote {
return true;
}
//功能获取content机制提供的数据并加载到note中
public JSONObject getContent() {
try {
JSONObject js = new JSONObject();
@ -392,7 +370,6 @@ public class SqlNote {
JSONObject note = new JSONObject();
if (mType == Notes.TYPE_NOTE) {
//类型为note时
note.put(NoteColumns.ID, mId);
note.put(NoteColumns.ALERTED_DATE, mAlertDate);
note.put(NoteColumns.BG_COLOR_ID, mBgColorId);
@ -416,7 +393,6 @@ public class SqlNote {
}
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
} else if (mType == Notes.TYPE_FOLDER || mType == Notes.TYPE_SYSTEM) {
//类型为文件夹或者系统时
note.put(NoteColumns.ID, mId);
note.put(NoteColumns.TYPE, mType);
note.put(NoteColumns.SNIPPET, mSnippet);
@ -431,49 +407,39 @@ public class SqlNote {
return null;
}
//功能给当前id设置父id
public void setParentId(long id) {
mParentId = id;
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
//功能给当前id设置Gtaskid
public void setGtaskId(String gid) {
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
//功能给当前id设置同步id
public void setSyncId(long syncId) {
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
}
//功能:初始化本地修改,即撤销所有当前修改
public void resetLocalModified() {
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
}
//功能获得当前id
public long getId() {
return mId;
}
//功能获得当前的id的父id
public long getParentId() {
return mParentId;
}
//功能:获取小片段即用于显示的部分便签内容
public String getSnippet() {
return mSnippet;
}
//功能:判断是否为便签类型
public boolean isNoteType() {
return mType == Notes.TYPE_NOTE;
}
//功能commit函数用于把当前所做的修改保存到数据库
public void commit(boolean validateVersion) {
if (mIsCreate) {
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
@ -492,7 +458,7 @@ public class SqlNote {
}
if (mType == Notes.TYPE_NOTE) {
for (SqlData sqlData : mDataList) { //直接使用sqldata中的实现
for (SqlData sqlData : mDataList) {
sqlData.commit(mId, false, -1);
}
}
@ -504,7 +470,7 @@ public class SqlNote {
if (mDiffNoteValues.size() > 0) {
mVersion ++;
int result = 0;
if (!validateVersion) { //构造字符串
if (!validateVersion) {
result = mContentResolver.update(Notes.CONTENT_NOTE_URI, mDiffNoteValues, "("
+ NoteColumns.ID + "=?)", new String[] {
String.valueOf(mId)

@ -35,22 +35,22 @@ import org.json.JSONObject;
public class Task extends Node {
private static final String TAG = Task.class.getSimpleName();
private boolean mCompleted; //看是否完成
private boolean mCompleted;
private String mNotes;
private JSONObject mMetaInfo; //将要在实例中存储数据的类型
private JSONObject mMetaInfo;
private Task mPriorSibling; //对应的优先兄弟Task的指针但是仍有待完善
private Task mPriorSibling;
private TaskList mParent; //所在的任务列表的指针
private TaskList mParent;
public Task() {
super();
mCompleted = false;
mNotes = null;
mPriorSibling = null; //TaskList中当前Task前面的Task的指针
mParent = null; //当前Task所在的TaskList
mPriorSibling = null;
mParent = null;
mMetaInfo = null;
}

@ -30,23 +30,22 @@ import org.json.JSONObject;
import java.util.ArrayList;
public class TaskList extends Node { //对抽象类Node的拓展
public class TaskList extends Node {
private static final String TAG = TaskList.class.getSimpleName();
private int mIndex; //这是一个指针
private int mIndex;
private ArrayList<Task> mChildren; //定义数组变量mChildren存储Task类型系列数据
private ArrayList<Task> mChildren;
public TaskList() { //构造函数初始化
super(); //引用父类构造函数理解为Node()
public TaskList() {
super();
mChildren = new ArrayList<Task>();
mIndex = 1;
}
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject(); //生成JSONObject类型变量js
JSONObject js = new JSONObject();
//下面代码中string内容参照GTaskStringUtils中共同阅读
try {
// action_type
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
@ -95,7 +94,7 @@ public class TaskList extends Node { //对抽象类Node的拓展
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) { //指捕捉JSONException异常
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate tasklist-update jsonobject");
@ -218,7 +217,7 @@ public class TaskList extends Node { //对抽象类Node的拓展
}
public int getChildTaskCount() {
return mChildren.size(); //返回TaskList数组mChildren的大小
return mChildren.size();
}
public boolean addChildTask(Task task) {
@ -229,14 +228,13 @@ public class TaskList extends Node { //对抽象类Node的拓展
// need to set prior sibling and parent
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
//每一次数组变化时setPriorSibling都要紧跟更改
task.setParent(this);
}
}
return ret; //返回布尔值——是否成功添加任务
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;
@ -262,7 +260,7 @@ public class TaskList extends Node { //对抽象类Node的拓展
return true;
}
public boolean removeChildTask(Task task) { //删除TaskList数组中的成员
public boolean removeChildTask(Task task) {
boolean ret = false;
int index = mChildren.indexOf(task);
if (index != -1) {
@ -280,10 +278,10 @@ public class TaskList extends Node { //对抽象类Node的拓展
}
}
}
return ret; //布尔值——是否删除成功
return ret;
}
public boolean moveChildTask(Task task, int index) { //将TaskList中含有的某个成员移动至index位置
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
@ -299,10 +297,9 @@ public class TaskList extends Node { //对抽象类Node的拓展
if (pos == index)
return true;
return (removeChildTask(task) && addChildTask(task, index));
//在移除成员和添加成员均成功时返回真值
}
public Task findChildTaskByGid(String gid) { //按gid寻找Task
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
if (t.getGid().equals(gid)) {
@ -313,7 +310,7 @@ public class TaskList extends Node { //对抽象类Node的拓展
}
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task); //返回指定Task的index
return mChildren.indexOf(task);
}
public Task getChildTaskByIndex(int index) {
@ -321,13 +318,13 @@ public class TaskList extends Node { //对抽象类Node的拓展
Log.e(TAG, "getTaskByIndex: invalid index");
return null;
}
return mChildren.get(index); //返回指定index的Task
return mChildren.get(index);
}
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
if (task.getGid().equals(gid))
return task; //返回指定gid的Task
return task;
}
return null;
}

@ -18,18 +18,16 @@ package net.micode.notes.gtask.exception;
public class ActionFailureException extends RuntimeException {
private static final long serialVersionUID = 4425249765923293627L;
/*JVM serialVersionUID
InvalidClassException */
public ActionFailureException() {
super(); //直接调用父类构造函数即理解为Exception()
super();
}
public ActionFailureException(String paramString) {
super(paramString); //理解为Exception(paramString)
super(paramString);
}
public ActionFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable); //理解为Exception(paramString, paramThrowable)
super(paramString, paramThrowable);
}
}

@ -18,18 +18,16 @@ package net.micode.notes.gtask.exception;
public class NetworkFailureException extends Exception {
private static final long serialVersionUID = 2107610287180234136L;
/*JVM serialVersionUID
InvalidClassException */
public NetworkFailureException() {
super(); //直接调用父类构造函数即理解为Exception()
super();
}
public NetworkFailureException(String paramString) {
super(paramString); //理解为Exception(paramString)
super(paramString);
}
public NetworkFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable); //理解为Exception(paramString, paramThrowable)
super(paramString, paramThrowable);
}
}

@ -57,13 +57,17 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
mTaskManager.cancelSync();
}
public void publishProgess(String message) { //发布进度
public void publishProgess(String message) {
publishProgress(new String[] {
message
});
}
private void showNotification(int tickerId, String content) { //提示当前同步状态
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;
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
@ -73,30 +77,20 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), 0);
}
Notification.Builder builder = new Notification.Builder(mContext)
.setAutoCancel(true)
.setContentTitle(mContext.getString(R.string.app_name))
.setContentText(content)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setOngoing(true);
Notification notification=builder.getNotification();
notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
pendingIntent);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
@Override
protected Integer doInBackground(Void... unused) { //该任务于后台执行
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext)));
return mTaskManager.sync(mContext, this);
}
@Override
protected void onProgressUpdate(String... progress) { //显示进度条
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);
if (mContext instanceof GTaskSyncService) {
((GTaskSyncService) mContext).sendBroadcast(progress[0]);

@ -106,15 +106,15 @@ public class GTaskClient {
if (mInstance == null) {
mInstance = new GTaskClient();
}
return mInstance; //返回实例化对象,若未定义则创建对象
return mInstance;
}
public boolean login(Activity activity) { //登录操作
public boolean login(Activity activity) {
// we suppose that the cookie would expire after 5 minutes
// then we need to re-login
final long interval = 1000 * 60 * 5;
if (mLastLoginTime + interval < System.currentTimeMillis()) {
mLoggedin = false; //超过5分钟则重新登录
mLoggedin = false;
}
// need to re-login after account switch
@ -129,14 +129,14 @@ public class GTaskClient {
return true;
}
mLastLoginTime = System.currentTimeMillis(); //更新最后登录时间
String authToken = loginGoogleAccount(activity, false); //是否登录到谷歌账户
mLastLoginTime = System.currentTimeMillis();
String authToken = loginGoogleAccount(activity, false);
if (authToken == null) {
Log.e(TAG, "login google account failed");
return false;
}
// login with custom domain if necessary 使用域名登录
// login with custom domain if necessary
if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase()
.endsWith("googlemail.com"))) {
StringBuilder url = new StringBuilder(GTASK_URL).append("a/");
@ -151,7 +151,7 @@ public class GTaskClient {
}
}
// try to login with google official url 官方URL登录
// try to login with google official url
if (!mLoggedin) {
mGetUrl = GTASK_GET_URL;
mPostUrl = GTASK_POST_URL;
@ -176,7 +176,7 @@ public class GTaskClient {
String accountName = NotesPreferenceActivity.getSyncAccountName(activity);
Account account = null;
for (Account a : accounts) { //遍历
for (Account a : accounts) {
if (a.name.equals(accountName)) {
account = a;
break;
@ -189,7 +189,7 @@ public class GTaskClient {
return null;
}
// get the token now 获取通行许可
// get the token now
AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthToken(account,
"goanna_mobile", null, activity, null, null);
try {
@ -207,7 +207,7 @@ public class GTaskClient {
return authToken;
}
private boolean tryToLoginGtask(Activity activity, String authToken) { //尝试登录GTask
private boolean tryToLoginGtask(Activity activity, String authToken) {
if (!loginGtask(authToken)) {
// maybe the auth token is out of date, now let's invalidate the
// token and try again
@ -225,7 +225,7 @@ public class GTaskClient {
return true;
}
private boolean loginGtask(String authToken) { //登录具体操作
private boolean loginGtask(String authToken) {
int timeoutConnection = 10000;
int timeoutSocket = 15000;
HttpParams httpParameters = new BasicHttpParams();
@ -238,8 +238,8 @@ public class GTaskClient {
// login gtask
try {
String loginUrl = mGetUrl + "?auth=" + authToken; //设置登录URL
HttpGet httpGet = new HttpGet(loginUrl); //实例化登录URL
String loginUrl = mGetUrl + "?auth=" + authToken;
HttpGet httpGet = new HttpGet(loginUrl);
HttpResponse response = null;
response = mHttpClient.execute(httpGet);

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#88555555" />
<item android:state_selected="true" android:color="#ff999999" />
<item android:color="#ff000000" />
</selector>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#50000000" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save