项目合并 #16

Closed
pevl7hxk5 wants to merge 0 commits from b_branch into develop

@ -5,9 +5,6 @@
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
<SelectionState runConfigName="MainActivity">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="StudioBotProjectSettings">
<option name="shareContext" value="OptedOut" />
</component>
</project>

@ -3,6 +3,15 @@ plugins {
}
android {
packaging {
resources.excludes.add("META-INF/DEPENDENCIES");
resources.excludes.add("META-INF/NOTICE");
resources.excludes.add("META-INF/LICENSE");
resources.excludes.add("META-INF/LICENSE.txt");
resources.excludes.add("META-INF/NOTICE.txt");
}
namespace = "net.micode.notes"
compileSdk = 35
@ -37,7 +46,17 @@ dependencies {
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
// 部分需要重新修改
// implementation(fileTree(mapOf(
// "dir" to "D:\\Code\\AndroidCode\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib",
// "include" to listOf("*.aar", "*.jar"),
// "exclude" to listOf("")
// )))
//修改为如下代码:
implementation(files("C:\\0000\\Install\\Android\\AndroidProject\\MiNote\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-osgi-4.5.14.jar"))
implementation(files("C:\\0000\\Install\\Android\\AndroidProject\\MiNote\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-win-4.5.14.jar"))
implementation(files("C:\\0000\\Install\\Android\\AndroidProject\\MiNote\\Notesmaster\\httpcomponents-client-4.5.14-bin\\lib\\httpcore-4.4.16.jar"))
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
}

@ -2,6 +2,16 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
@ -12,15 +22,135 @@
android:supportsRtl="true"
android:theme="@style/Theme.Notesmaster"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<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" />
<category android:name="android.intent.category.DEFAULT" />
<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.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
<provider
android:name="net.micode.notes.data.NotesProvider"
android:authorities="micode_notes"
android:multiprocess="true" />
<receiver
android:name=".widget.NoteWidgetProvider_2x"
android:label="@string/app_widget2x2"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.intent.action.PRIVACY_MODE_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_2x_info" />
</receiver>
<receiver
android:name=".widget.NoteWidgetProvider_4x"
android:label="@string/app_widget4x4"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.intent.action.PRIVACY_MODE_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" />
</receiver>
<receiver android:name=".ui.AlarmInitReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="net.micode.notes.ui.AlarmReceiver"
android:process=":remote" >
</receiver>
<activity
android:name=".ui.AlarmAlertActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" >
</activity>
<activity
android:name="net.micode.notes.ui.NotesPreferenceActivity"
android:label="@string/preferences_title"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Holo.Light" >
</activity>
<service
android:name="net.micode.notes.gtask.remote.GTaskSyncService"
android:exported="false" >
</service>
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
<!-- <activity-->
<!-- android:name=".MainActivity"-->
<!-- android:exported="true">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.MAIN" />-->
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
<!-- </intent-filter>-->
<!-- </activity>-->
</application>
</manifest>

@ -18,11 +18,11 @@ package net.micode.notes.data;
import android.net.Uri;
public class Notes {
public static final String AUTHORITY = "micode_notes";//定义内容提供者的权限标识符
public static final String TAG = "Notes";//日志标签
public static final int TYPE_NOTE = 0;//笔记类型
public static final int TYPE_FOLDER = 1;//文件夹类型
public static final int TYPE_SYSTEM = 2;//系统类型
public static final String AUTHORITY = "micode_notes";
public static final String TAG = "Notes";
public static final int TYPE_NOTE = 0;
public static final int TYPE_FOLDER = 1;
public static final int TYPE_SYSTEM = 2;
/**
* Following IDs are system folders' identifiers
@ -30,54 +30,49 @@ public class Notes {
* {@link Notes#ID_TEMPARAY_FOLDER } is for notes belonging no folder
* {@link Notes#ID_CALL_RECORD_FOLDER} is to store call records
*/
//定义系统文件夹的标识符
public static final int ID_ROOT_FOLDER = 0;//根文件夹,默认文件夹
public static final int ID_TEMPARAY_FOLDER = -1;//临时文件夹,用于移动笔记
public static final int ID_CALL_RECORD_FOLDER = -2;//通话记录文件夹
public static final int ID_TRASH_FOLER = -3;//回收站文件夹
public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";//提醒日期
public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";//背景颜色ID
public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id";//小部件ID
public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type";//小部件类型
public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id";//文件夹ID
public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date";//通话日期
//定义小部件类型
public static final int TYPE_WIDGET_INVALIDE = -1;//无效小部件
public static final int TYPE_WIDGET_2X = 0;//2X小部件
public static final int TYPE_WIDGET_4X = 1;//4X小部件
public static final int ID_ROOT_FOLDER = 0;
public static final int ID_TEMPARAY_FOLDER = -1;
public static final int ID_CALL_RECORD_FOLDER = -2;
public static final int ID_TRASH_FOLER = -3;
public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";
public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";
public static final String INTENT_EXTRA_WIDGET_ID = "net.micode.notes.widget_id";
public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type";
public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id";
public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date";
public static final int TYPE_WIDGET_INVALIDE = -1;
public static final int TYPE_WIDGET_2X = 0;
public static final int TYPE_WIDGET_4X = 1;
public static class DataConstants {
public static final String NOTE = TextNote.CONTENT_ITEM_TYPE;//文本笔记的MIME类型
public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE;//通话笔记的MIME类型
public static final String NOTE = TextNote.CONTENT_ITEM_TYPE;
public static final String CALL_NOTE = CallNote.CONTENT_ITEM_TYPE;
}
/**
* Uri to query all notes and folders
* Uri
*/
public static final Uri CONTENT_NOTE_URI = Uri.parse("content://" + AUTHORITY + "/note");
/**
* Uri to query data
* Uri
*/
public static final Uri CONTENT_DATA_URI = Uri.parse("content://" + AUTHORITY + "/data");
//NoteColumns接口包含笔记表的列名常量
public interface NoteColumns {
/**
* The unique ID for a row
* <P> Type: INTEGER (long) </P>
*/
public static final String ID = "_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";//笔记或文件夹的父级ID
public static final String PARENT_ID = "parent_id";
/**
* Created data for note or folder
@ -102,7 +97,7 @@ public class Notes {
* 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
@ -126,7 +121,6 @@ public class Notes {
* For text note, it doesn't has attachment, for multi-media
* note, it has at least one attachment
* <P> Type: INTEGER </P>
*
*/
public static final String HAS_ATTACHMENT = "has_attachment";
@ -173,7 +167,6 @@ public class Notes {
public static final String VERSION = "version";
}
//定义DataColumns接口包含数据表的列名常量
public interface DataColumns {
/**
* The unique ID for a row
@ -248,7 +241,6 @@ public class Notes {
public static final String DATA5 = "data5";
}
//定义TextNote内部类继承自dataColumns接口表示文本笔记的数据结构
public static final class TextNote implements DataColumns {
/**
* Mode to indicate the text in check list mode or not
@ -265,7 +257,6 @@ public class Notes {
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note");
}
//通话笔记的数据结构
public static final class CallNote implements DataColumns {
/**
* Call date for this record

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.micode.notes.data;//定义包名
package net.micode.notes.data;
import android.content.ContentValues;
import android.content.Context;
@ -26,216 +26,199 @@ import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
//库帮助类继承自SQLiteOpenHelper用于管理笔记应用的数据库
public class NotesDatabaseHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "note.db"; //数据库名称
private static final String DB_NAME = "note.db";
private static final int DB_VERSION = 4;//数据库版本
private static final int DB_VERSION = 4;
//内部接口,定义表名
public interface TABLE {
public static final String NOTE = "note";//笔记表名
public static final String NOTE = "note";
public static final String DATA = "data";//数据表名
public static final String DATA = "data";
}
private static final String TAG = "NotesDatabaseHelper";//日志标签
private static final String TAG = "NotesDatabaseHelper";
private static NotesDatabaseHelper mInstance;//单例实例
private static NotesDatabaseHelper mInstance;
//创建笔记表的SQL语句
private static final String CREATE_NOTE_TABLE_SQL =
"CREATE TABLE " + TABLE.NOTE + "(" +
NoteColumns.ID + " INTEGER PRIMARY KEY," +//笔记id主键
NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +//父级笔记
NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," +//提醒日期
NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," +//背景颜色id
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +// 创建日期
NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," +// 是否有附件
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +//修改日期
NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," +//笔记数量
NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," +//摘要
NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," +//小部件
NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," +
NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," +//同步id
NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," +
NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" +//版本号
")";
//创建数据表的SQL语句
"CREATE TABLE " + TABLE.NOTE + "(" +
NoteColumns.ID + " INTEGER PRIMARY KEY," +
NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," +
NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," +
NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," +
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," +
DataColumns.MIME_TYPE + " TEXT NOT NULL," +
DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," +//数据内容
DataColumns.DATA1 + " INTEGER," +//附加数据
DataColumns.DATA2 + " INTEGER," +
DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" +
")";
//创建数据表中note_id索引的SQL语句
"CREATE TABLE " + TABLE.DATA + "(" +
DataColumns.ID + " INTEGER PRIMARY KEY," +
DataColumns.MIME_TYPE + " TEXT NOT NULL," +
DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," +
NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," +
DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," +
DataColumns.DATA1 + " INTEGER," +
DataColumns.DATA2 + " INTEGER," +
DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," +
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 + ");";
"CREATE INDEX IF NOT EXISTS note_id_index ON " +
TABLE.DATA + "(" + DataColumns.NOTE_ID + ");";
/**
* Increase folder's note count when move note to the folder
*/
//当笔记被移动到文件夹时增加文件夹笔记数的触发器sql语句
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 " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
" WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
" END";
"CREATE TRIGGER increase_folder_count_on_update "+
" AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
" BEGIN " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
" WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
" END";
/**
* Decrease folder's note count when move note from folder
*/
//当笔记从文件夹中被删除时减少文件夹笔记数的触发器sql语句
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 " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
" WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
" AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
" END";
"CREATE TRIGGER decrease_folder_count_on_update " +
" AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE +
" BEGIN " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
" WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
" AND " + NoteColumns.NOTES_COUNT + ">0" + ";" +
" END";
/**
* Increase folder's note count when insert new note to the folder
*/
//当新笔记被插入到文件夹中时增加文件夹笔记数的触发器sql语句
private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER =
"CREATE TRIGGER increase_folder_count_on_insert " +
" AFTER INSERT ON " + TABLE.NOTE +
" BEGIN " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
" WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
" END";
"CREATE TRIGGER increase_folder_count_on_insert " +
" AFTER INSERT ON " + TABLE.NOTE +
" BEGIN " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" +
" WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" +
" END";
/**
* Decrease folder's note count when delete note from the folder
*/
//当笔记从文件夹中被删除时减少文件夹笔记数的触发器sql语句
private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER =
"CREATE TRIGGER decrease_folder_count_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
" WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
" AND " + NoteColumns.NOTES_COUNT + ">0;" +
" END";
"CREATE TRIGGER decrease_folder_count_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN " +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" +
" WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID +
" AND " + NoteColumns.NOTES_COUNT + ">0;" +
" END";
/**
* Update note's content when insert data with type {@link DataConstants#NOTE}
*/
//当数据类型为NOTE时插入数据时更新笔记内容的触发器sql语句
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 + "'" +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
" WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
" END";
"CREATE TRIGGER update_note_content_on_insert " +
" AFTER INSERT ON " + TABLE.DATA +
" WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
" WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
" END";
/**
* Update note's content when data with {@link DataConstants#NOTE} type has changed
*/
//当数据类型为NOTE时更新数据时更新笔记内容的触发器sql语句
private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER =
"CREATE TRIGGER update_note_content_on_update " +
" AFTER UPDATE ON " + TABLE.DATA +
" WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
" WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
" END";
"CREATE TRIGGER update_note_content_on_update " +
" AFTER UPDATE ON " + TABLE.DATA +
" WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT +
" WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" +
" END";
/**
* Update note's content when data with {@link DataConstants#NOTE} type has deleted
*/
//当数据类型为NOTE时删除数据时更新笔记内容的触发器sql语句
private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER =
"CREATE TRIGGER update_note_content_on_delete " +
" AFTER delete ON " + TABLE.DATA +
" WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.SNIPPET + "=''" +
" WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
" END";
"CREATE TRIGGER update_note_content_on_delete " +
" AFTER delete ON " + TABLE.DATA +
" WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.SNIPPET + "=''" +
" WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" +
" END";
/**
* Delete datas belong to note which has been deleted
*/
//当笔记被删除时删除与其相关的数据的触发器sql语句
private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER =
"CREATE TRIGGER delete_data_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN" +
" DELETE FROM " + TABLE.DATA +
" WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
" END";
"CREATE TRIGGER delete_data_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN" +
" DELETE FROM " + TABLE.DATA +
" WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" +
" END";
/**
* Delete notes belong to folder which has been deleted
*/
//当文件夹被删除时删除与其相关的笔记的触发器sql语句
private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER =
"CREATE TRIGGER folder_delete_notes_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN" +
" DELETE FROM " + TABLE.NOTE +
" WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
" END";
"CREATE TRIGGER folder_delete_notes_on_delete " +
" AFTER DELETE ON " + TABLE.NOTE +
" BEGIN" +
" DELETE FROM " + TABLE.NOTE +
" WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
" END";
/**
* Move notes belong to folder which has been moved to trash folder
*/
//当笔记被移动到回收站文件夹时移动与其相关的笔记到回收站文件夹的触发器sql语句
private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER =
"CREATE TRIGGER folder_move_notes_on_trash " +
" AFTER UPDATE ON " + TABLE.NOTE +
" WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
" WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" +
" END";
//构造函数,初始化数据库名称和版本号
"CREATE TRIGGER folder_move_notes_on_trash " +
" AFTER UPDATE ON " + TABLE.NOTE +
" WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER +
" BEGIN" +
" UPDATE " + TABLE.NOTE +
" 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);
}
//创建笔记表包括执行创建表的SQL语句和创建相应的触发器
public void createNoteTable(SQLiteDatabase db) {
db.execSQL(CREATE_NOTE_TABLE_SQL);//执行创建笔记表的SQL语句
reCreateNoteTableTriggers(db);//重新创建笔记表的触发器
createSystemFolder(db);//创建系统文件夹
Log.d(TAG, "note table has been created");//日志输出
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 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");
db.execSQL("DROP TRIGGER IF EXISTS delete_data_on_delete");
@ -243,7 +226,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL("DROP TRIGGER IF EXISTS folder_delete_notes_on_delete");
db.execSQL("DROP TRIGGER IF EXISTS folder_move_notes_on_trash");
db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER);//创建新的触发器
db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER);
db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER);
db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER);
db.execSQL(NOTE_DELETE_DATA_ON_DELETE_TRIGGER);
@ -252,7 +235,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER);
}
///创建系统文件夹
private void createSystemFolder(SQLiteDatabase db) {
ContentValues values = new ContentValues();
@ -288,26 +270,23 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
db.insert(TABLE.NOTE, null, values);
}
//创建数据表方法包括执行创建表的SQL语句、创建相应的触发器和创建索引
public void createDataTable(SQLiteDatabase db) {
db.execSQL(CREATE_DATA_TABLE_SQL);
reCreateDataTableTriggers(db);//重新创建数据表的触发器
db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL);//创建note_id索引
Log.d(TAG, "data table has been created");//记录日志
reCreateDataTableTriggers(db);
db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL);
Log.d(TAG, "data table has been created");
}
//重新创建数据表的触发器
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_insert");
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update");
db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_delete");
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER);//创建新的触发器
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER);
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER);
db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER);
}
//获取单例实例
static synchronized NotesDatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new NotesDatabaseHelper(context);
@ -315,33 +294,30 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
return mInstance;
}
//数据库第一次被创建时调用,用于初始化数据库结构
@Override
public void onCreate(SQLiteDatabase db) {
createNoteTable(db);//笔记表
createDataTable(db);//数据表创建
createNoteTable(db);
createDataTable(db);
}
//数据库升级时调用,根据版本号进行相应的升级操作
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
boolean reCreateTriggers = false;//标志是否需要重新创建触发器
boolean skipV2 = false;//标志是否跳过v2版本的升级
boolean reCreateTriggers = false;
boolean skipV2 = false;
//根据不用的版本号进行升级操作
if (oldVersion == 1) {
upgradeToV2(db);
skipV2 = true; // this upgrade including the upgrade from v2 to v3
oldVersion++;
}
if (oldVersion == 2 && !skipV2) {//从v2升级到v3
if (oldVersion == 2 && !skipV2) {
upgradeToV3(db);
reCreateTriggers = true;//标志需要重新创建触发器
reCreateTriggers = true;
oldVersion++;
}
if (oldVersion == 3) {//从v3升级到v4
if (oldVersion == 3) {
upgradeToV4(db);
oldVersion++;
}
@ -351,7 +327,6 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper {
reCreateDataTableTriggers(db);
}
//如果版本号没有升级成功,抛出异常
if (oldVersion != newVersion) {
throw new IllegalStateException("Upgrade notes database to version " + newVersion
+ "fails");

@ -16,6 +16,7 @@
package net.micode.notes.data;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentUris;
@ -33,7 +34,7 @@ import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.data.NotesDatabaseHelper.TABLE;
// NotesProvider 类继承自 ContentProvider用于处理笔记和数据的存储和检索
public class NotesProvider extends ContentProvider {
private static final UriMatcher mMatcher;
@ -65,30 +66,28 @@ public class NotesProvider extends ContentProvider {
* we will trim '\n' and white space in order to show more information.
*/
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 + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + ","
+ R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + ","
+ "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
+ "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
+ NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + ","
+ "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + ","
+ R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + ","
+ "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + ","
+ "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA;
private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION
+ " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER
+ " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
+ " FROM " + TABLE.NOTE
+ " WHERE " + NoteColumns.SNIPPET + " LIKE ?"
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER
+ " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
// 初始化 ContentProvider获取数据库帮助类实例
@Override
public boolean onCreate() {
mHelper = NotesDatabaseHelper.getInstance(getContext());
return true;
}
// 处理查询请求,根据不同的 URI 返回相应的数据
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
String sortOrder) {
Cursor c = null;
SQLiteDatabase db = mHelper.getReadableDatabase();
String id = null;
@ -148,7 +147,6 @@ public class NotesProvider extends ContentProvider {
return c;
}
// 处理插入请求,根据不同的 URI 插入相应的数据
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = mHelper.getWritableDatabase();
@ -183,7 +181,6 @@ public class NotesProvider extends ContentProvider {
return ContentUris.withAppendedId(uri, insertedId);
}
// 处理删除请求,根据不同的 URI 删除相应的数据
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
@ -230,7 +227,6 @@ public class NotesProvider extends ContentProvider {
return count;
}
// 处理更新请求,根据不同的 URI 更新相应的数据
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int count = 0;
@ -271,12 +267,10 @@ public class NotesProvider extends ContentProvider {
return count;
}
// 解析查询条件,如果存在查询条件则添加 AND 关键字
private String parseSelection(String selection) {
return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : "");
}
// 增加笔记版本号
private void increaseNoteVersion(long id, String selection, String[] selectionArgs) {
StringBuilder sql = new StringBuilder(120);
sql.append("UPDATE ");
@ -302,7 +296,6 @@ public class NotesProvider extends ContentProvider {
mHelper.getWritableDatabase().execSQL(sql.toString());
}
// 获取 URI 对应的 MIME 类型,目前返回 null
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub

@ -24,13 +24,12 @@ import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
// 该类继承自Task类用于处理与Google任务相关的元数据
public class MetaData extends Task {
private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null;
// 设置元数据信息包括Google任务ID和元数据信息
public void setMeta(String gid, JSONObject metaInfo) {
try {
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
@ -41,18 +40,15 @@ public class MetaData extends Task {
setName(GTaskStringUtils.META_NOTE_NAME);
}
// 获取相关的Google任务ID
public String getRelatedGid() {
return mRelatedGid;
}
// 判断该元数据是否值得保存
@Override
public boolean isWorthSaving() {
return getNotes() != null;
}
// 通过远程JSON数据设置内容
@Override
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
@ -67,20 +63,17 @@ public class MetaData extends Task {
}
}
// 该方法不应用于MetaData类调用时会抛出异常
@Override
public void setContentByLocalJSON(JSONObject js) {
// this function should not be called
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
// 该方法不应用于MetaData类调用时会抛出异常
@Override
public JSONObject getLocalJSONFromContent() {
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
}
// 该方法不应用于MetaData类调用时会抛出异常
@Override
public int getSyncAction(Cursor c) {
throw new IllegalAccessError("MetaData:getSyncAction should not be called");

@ -63,43 +63,25 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
});
}
// 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,
// NotesPreferenceActivity.class), 0);
//
// } else {
// pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
// NotesListActivity.class), 0);
// }
// notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
// pendingIntent);
// mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
// }
private void showNotification(int tickerId, String content) {
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE);
} else {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), PendingIntent.FLAG_IMMUTABLE);
private void showNotification(int tickerId, String content) {
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE);
} else {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), PendingIntent.FLAG_IMMUTABLE);
}
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();
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
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();
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
@Override
protected Integer doInBackground(Void... unused) {

@ -41,133 +41,98 @@ import java.io.IOException;
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
// 存储当前提醒便签的ID
private long mNoteId;
// 存储便签的摘要内容
private String mSnippet;
// 定义便签摘要显示的最大长度
private static final int SNIPPET_PREW_MAX_LEN = 60;
// 媒体播放器,用于播放闹钟提醒声音
MediaPlayer mPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 不显示Activity的标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
final Window win = getWindow();
// 添加窗口标志使Activity在锁屏状态下也能显示
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
// 如果屏幕当前处于关闭状态
if (!isScreenOn()) {
// 添加窗口标志,点亮屏幕并保持常亮,同时允许在屏幕开启时锁屏
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
}
// 获取启动Activity的Intent
Intent intent = getIntent();
try {
// 从Intent的Data中解析出便签ID
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
// 通过ContentResolver获取便签的摘要内容
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
// 如果摘要内容超过最大长度,进行截断并添加省略标记
mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0,
SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info)
: mSnippet;
} catch (IllegalArgumentException e) {
// 处理参数异常打印堆栈信息并结束Activity
e.printStackTrace();
return;
}
// 创建媒体播放器实例
mPlayer = new MediaPlayer();
// 检查便签是否存在且为普通便签类型
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) {
// 显示提醒对话框
showActionDialog();
// 播放闹钟提醒声音
playAlarmSound();
} else {
// 便签不存在或类型不符结束Activity
finish();
}
}
// 检查屏幕是否处于开启状态
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn();
}
// 播放闹钟提醒声音
private void playAlarmSound() {
// 获取系统默认闹钟铃声的URI
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
// 获取设置中静默模式影响的音频流
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
// 根据静默模式设置音频流类型
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) {
mPlayer.setAudioStreamType(silentModeStreams);
} else {
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
}
try {
// 设置音频数据源
mPlayer.setDataSource(this, url);
// 准备播放器
mPlayer.prepare();
// 设置循环播放
mPlayer.setLooping(true);
// 开始播放
mPlayer.start();
} catch (IllegalArgumentException e) {
// 参数异常处理
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// 安全异常处理
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// 状态异常处理
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// IO异常处理
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 显示提醒操作对话框
private void showActionDialog() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
// 设置对话框标题为应用名称
dialog.setTitle(R.string.app_name);
// 设置对话框内容为便签摘要
dialog.setMessage(mSnippet);
// 添加"确定"按钮,并设置点击监听器
dialog.setPositiveButton(R.string.notealert_ok, this);
// 如果屏幕已开启,添加"进入"按钮
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);
}
// 显示对话框并设置消失监听器
dialog.show().setOnDismissListener(this);
}
// 对话框按钮点击事件处理
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_NEGATIVE:
// 点击"进入"按钮启动便签编辑Activity查看便签详情
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_UID, mNoteId);
@ -178,22 +143,15 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
}
// 对话框消失时的回调处理
public void onDismiss(DialogInterface dialog) {
// 停止闹钟声音播放
stopAlarmSound();
// 结束当前Activity
finish();
}
// 停止闹钟声音并释放资源
private void stopAlarmSound() {
if (mPlayer != null) {
// 停止播放
mPlayer.stop();
// 释放媒体播放器资源
mPlayer.release();
// 将引用置为null便于垃圾回收
mPlayer = null;
}
}

@ -28,65 +28,38 @@ import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
/**
* 广便
*/
public class AlarmInitReceiver extends BroadcastReceiver {
// 查询闹钟提醒相关便签数据时使用的列投影
private static final String [] PROJECTION = new String [] {
NoteColumns.ID, // 便签ID
NoteColumns.ALERTED_DATE // 提醒日期时间
NoteColumns.ID,
NoteColumns.ALERTED_DATE
};
// 投影列索引常量,便于代码引用
private static final int COLUMN_ID = 0; // ID列索引
private static final int COLUMN_ALERTED_DATE = 1; // 提醒日期列索引
private static final int COLUMN_ID = 0;
private static final int COLUMN_ALERTED_DATE = 1;
/**
* 广
* @param context
* @param intent Intent
*/
@Override
public void onReceive(Context context, Intent intent) {
// 获取当前时间戳
long currentDate = System.currentTimeMillis();
// 查询所有提醒时间在当前时间之后的普通便签
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
PROJECTION,
// 查询条件:提醒时间大于当前时间且类型为普通便签
NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
new String[] { String.valueOf(currentDate) }, // 查询参数
null); // 不指定排序
new String[] { String.valueOf(currentDate) },
null);
// 处理查询结果
if (c != null) {
if (c.moveToFirst()) {
// 遍历所有符合条件的便签
do {
// 获取便签的提醒时间
long alertDate = c.getLong(COLUMN_ALERTED_DATE);
// 创建一个将在提醒时间触发的广播Intent
Intent sender = new Intent(context, AlarmReceiver.class);
// 设置Intent的数据为便签的URI以便在广播接收器中识别具体便签
sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID)));
// 创建一个PendingIntent用于在指定时间触发广播
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0);
// 获取系统闹钟服务
AlarmManager alermManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
// 设置一个精确的闹钟,当到达提醒时间时唤醒设备并触发广播
alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);
} while (c.moveToNext());
}
// 关闭Cursor释放资源
c.close();
}
}
}
}

@ -227,17 +227,6 @@ public class DateTimePicker extends FrameLayout {
mIsEnabled = enabled;
}
@Override
public boolean isEnabled() {
return mIsEnabled;

@ -31,113 +31,60 @@ import android.text.format.DateUtils;
public class DateTimePickerDialog extends AlertDialog implements OnClickListener {
// 存储当前选择的日期和时间
private Calendar mDate = Calendar.getInstance();
// 是否使用24小时制
private boolean mIs24HourView;
// 日期时间设置监听器,用于回调选择结果
private OnDateTimeSetListener mOnDateTimeSetListener;
// 自定义的日期时间选择器视图
private DateTimePicker mDateTimePicker;
/**
*
*/
public interface OnDateTimeSetListener {
/**
*
* @param dialog
* @param date
*/
void OnDateTimeSet(AlertDialog dialog, long date);
}
/**
*
* @param context
* @param date
*/
public DateTimePickerDialog(Context context, long date) {
super(context);
// 创建自定义的日期时间选择器
mDateTimePicker = new DateTimePicker(context);
// 设置对话框的视图为日期时间选择器
setView(mDateTimePicker);
// 设置日期时间变化监听器
mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
public void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute) {
// 更新Calendar对象中的日期时间
int dayOfMonth, int hourOfDay, int minute) {
mDate.set(Calendar.YEAR, year);
mDate.set(Calendar.MONTH, month);
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
mDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
mDate.set(Calendar.MINUTE, minute);
// 更新对话框标题,显示当前选择的日期时间
updateTitle(mDate.getTimeInMillis());
}
});
// 设置初始日期时间并将秒数设为0
mDate.setTimeInMillis(date);
mDate.set(Calendar.SECOND, 0);
// 在日期时间选择器中显示初始日期时间
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
// 设置对话框按钮
setButton(context.getString(R.string.datetime_dialog_ok), this);
setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null);
// 根据系统设置确定是否使用24小时制
set24HourView(DateFormat.is24HourFormat(this.getContext()));
// 更新对话框标题
updateTitle(mDate.getTimeInMillis());
}
/**
* 使24
* @param is24HourView true使24false使12
*/
public void set24HourView(boolean is24HourView) {
mIs24HourView = is24HourView;
}
/**
*
* @param callBack OnDateTimeSetListener
*/
public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) {
mOnDateTimeSetListener = callBack;
}
/**
*
* @param date
*/
private void updateTitle(long date) {
// 设置日期时间显示格式标志
int flag =
DateUtils.FORMAT_SHOW_YEAR |
DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_SHOW_TIME;
// 根据是否使用24小时制添加相应的格式标志
DateUtils.FORMAT_SHOW_YEAR |
DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_SHOW_TIME;
flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR;
// 更新对话框标题
setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
}
/**
*
* @param arg0
* @param arg1
*/
public void onClick(DialogInterface arg0, int arg1) {
// 当点击"确定"按钮时,调用回调函数通知日期时间已设置
if (mOnDateTimeSetListener != null) {
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
}
}
}

@ -33,16 +33,11 @@ public class DropdownMenu {
private Menu mMenu;
public DropdownMenu(Context context, Button button, int menuId) {
// 保存按钮引用并设置下拉图标背景
mButton = button;
mButton.setBackgroundResource(R.drawable.dropdown_icon);
// 创建PopupMenu实例并加载菜单资源
mPopupMenu = new PopupMenu(context, mButton);
mMenu = mPopupMenu.getMenu();
mPopupMenu.getMenuInflater().inflate(menuId, mMenu);
// 设置按钮点击事件,点击时显示菜单
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mPopupMenu.show();

@ -29,97 +29,52 @@ import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
/**
* ListView
*/
public class FoldersListAdapter extends CursorAdapter {
// 查询文件夹数据时使用的列投影,指定需要查询的数据库列
public static final String [] PROJECTION = {
NoteColumns.ID, // 文件夹ID
NoteColumns.SNIPPET // 文件夹名称(摘要)
NoteColumns.ID,
NoteColumns.SNIPPET
};
// 列索引常量,方便后续代码引用
public static final int ID_COLUMN = 0; // ID列的索引
public static final int NAME_COLUMN = 1; // 名称列的索引
public static final int ID_COLUMN = 0;
public static final int NAME_COLUMN = 1;
/**
*
* @param context
* @param c Cursor
*/
public FoldersListAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
}
/**
*
* @param context
* @param cursor
* @param parent
* @return
*/
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// 创建自定义的文件夹列表项视图
return new FolderListItem(context);
}
/**
*
* @param view
* @param context
* @param cursor
*/
@Override
public void bindView(View view, Context context, Cursor cursor) {
if (view instanceof FolderListItem) {
// 如果是根文件夹,则显示"上级文件夹"文本,否则显示实际文件夹名称
String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
// 将文件夹名称绑定到视图上
((FolderListItem) view).bind(folderName);
}
}
/**
*
* @param context
* @param position
* @return
*/
public String getFolderName(Context context, int position) {
Cursor cursor = (Cursor) getItem(position);
// 如果是根文件夹,则显示"上级文件夹"文本,否则显示实际文件夹名称
return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
.getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN);
}
/**
*
*/
private class FolderListItem extends LinearLayout {
private TextView mName; // 文件夹名称显示文本视图
private TextView mName;
/**
*
* @param context
*/
public FolderListItem(Context context) {
super(context);
// 加载布局文件
inflate(context, R.layout.folder_list_item, this);
// 获取文件夹名称文本视图引用
mName = (TextView) findViewById(R.id.tv_folder_name);
}
/**
*
* @param name
*/
public void bind(String name) {
mName.setText(name);
}
}
}
}

@ -430,7 +430,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.VISIBLE);
- View.VISIBLE);
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@ -507,48 +507,45 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_note:
createNewNote();
break;
case R.id.menu_delete:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_note));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteCurrentNote();
finish();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.menu_font_size:
mFontSizeSelector.setVisibility(View.VISIBLE);
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
break;
case R.id.menu_list_mode:
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
TextNote.MODE_CHECK_LIST : 0);
break;
case R.id.menu_share:
getWorkingText();
sendTo(this, mWorkingNote.getContent());
break;
case R.id.menu_send_to_desktop:
sendToDesktop();
break;
case R.id.menu_alert:
setReminder();
break;
case R.id.menu_delete_remind:
mWorkingNote.setAlertDate(0, false);
break;
default:
break;
int id = item.getItemId();
if(id == R.id.menu_new_note) {
createNewNote();
}
else if(id == R.id.menu_delete) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_note));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteCurrentNote();
finish();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
else if(id == R.id.menu_font_size) {
mFontSizeSelector.setVisibility(View.VISIBLE);
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
}
else if(id == R.id.menu_list_mode) {
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
TextNote.MODE_CHECK_LIST : 0);
}
else if(id == R.id.menu_share) {
getWorkingText();
sendTo(this, mWorkingNote.getContent());
}
else if(id == R.id.menu_send_to_desktop) {
sendToDesktop();
}
else if(id == R.id.menu_alert) {
setReminder();
}
else if(id == R.id.menu_delete_remind) {
mWorkingNote.setAlertDate(0, false);
}
return true;
}
@ -623,7 +620,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (mWorkingNote.getNoteId() > 0) {
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
showAlertHeader();
if(!set) {

@ -318,28 +318,27 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
Toast.LENGTH_SHORT).show();
return true;
}
switch (item.getItemId()) {
case R.id.delete:
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.move:
startQueryDestinationFolders();
break;
default:
int id = item.getItemId();
if(id == R.id.delete) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
else if(id == R.id.move) {
startQueryDestinationFolders();
}
else{
return false;
}
return true;
@ -558,12 +557,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_new_note:
int id = v.getId();
if(id == R.id.btn_new_note){
createNewNote();
break;
default:
break;
}
}
@ -780,40 +776,32 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_folder: {
showCreateOrModifyFolderDialog(true);
break;
}
case R.id.menu_export_text: {
exportNoteToText();
break;
}
case R.id.menu_sync: {
if (isSyncMode()) {
if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) {
GTaskSyncService.startSync(this);
} else {
GTaskSyncService.cancelSync(this);
}
int id = item.getItemId();
if(id == R.id.menu_new_folder) {
showCreateOrModifyFolderDialog(true);
}
else if(id == R.id.menu_export_text) {
exportNoteToText();
}
else if(id == R.id.menu_sync) {
if (isSyncMode()) {
if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) {
GTaskSyncService.startSync(this);
} else {
startPreferenceActivity();
GTaskSyncService.cancelSync(this);
}
break;
}
case R.id.menu_setting: {
} else {
startPreferenceActivity();
break;
}
case R.id.menu_new_note: {
createNewNote();
break;
}
case R.id.menu_search:
onSearchRequested();
break;
default:
break;
}
else if(id == R.id.menu_setting) {
startPreferenceActivity();
}
else if(id == R.id.menu_new_note) {
createNewNote();
}
else if(id == R.id.menu_search) {
onSearchRequested();
}
return true;
}

@ -49,7 +49,6 @@ public class NotesListItem extends LinearLayout {
}
public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) {
// 根据选择模式和笔记类型决定是否显示复选框
if (choiceMode && data.getType() == Notes.TYPE_NOTE) {
mCheckBox.setVisibility(View.VISIBLE);
mCheckBox.setChecked(checked);
@ -57,49 +56,36 @@ public class NotesListItem extends LinearLayout {
mCheckBox.setVisibility(View.GONE);
}
// 保存笔记数据引用
mItemData = data;
// 处理通话记录文件夹
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mCallName.setVisibility(View.GONE);
mAlert.setVisibility(View.VISIBLE);
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
// 设置文件夹名称和包含的文件数量
mTitle.setText(context.getString(R.string.call_record_folder_name)
+ context.getString(R.string.format_folder_files_count, data.getNotesCount()));
mAlert.setImageResource(R.drawable.call_record);
}
// 处理通话记录子项
else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) {
} else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) {
mCallName.setVisibility(View.VISIBLE);
mCallName.setText(data.getCallName());
mTitle.setTextAppearance(context,R.style.TextAppearanceSecondaryItem);
mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
// 根据是否有提醒设置提醒图标
if (data.hasAlert()) {
mAlert.setImageResource(R.drawable.clock);
mAlert.setVisibility(View.VISIBLE);
} else {
mAlert.setVisibility(View.GONE);
}
}
// 处理普通笔记和文件夹
else {
} else {
mCallName.setVisibility(View.GONE);
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
// 处理文件夹
if (data.getType() == Notes.TYPE_FOLDER) {
mTitle.setText(data.getSnippet()
+ context.getString(R.string.format_folder_files_count,
data.getNotesCount()));
data.getNotesCount()));
mAlert.setVisibility(View.GONE);
}
// 处理普通笔记
else {
} else {
mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
// 根据是否有提醒设置提醒图标
if (data.hasAlert()) {
mAlert.setImageResource(R.drawable.clock);
mAlert.setVisibility(View.VISIBLE);
@ -108,13 +94,11 @@ public class NotesListItem extends LinearLayout {
}
}
}
// 设置修改时间,使用相对时间格式(如"1小时前"
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
// 根据笔记状态设置背景
setBackground(data);
}
private void setBackground(NoteItemData data) {
int id = data.getBgColorId();
if (data.getType() == Notes.TYPE_NOTE) {

@ -56,7 +56,7 @@
android:layout_marginRight="8dip"
android:textAppearance="@style/TextAppearanceSecondaryItem" />
<ImageButton
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"

@ -1,5 +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.
-->
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>
<color name="user_query_highlight">#335b5b5b</color>
</resources>

@ -1,3 +1,135 @@
<resources>
<string name="app_name">Notes-master</string>
</resources>
<?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.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Notes</string>
<string name="app_widget2x2">Notes 2x2</string>
<string name="app_widget4x4">Notes 4x4</string>
<string name="widget_havenot_content">No associated note found, click to create associated note.</string>
<string name="widget_under_visit_mode">Privacy modecan not see note content</string>
<string name="notelist_string_info">...</string>
<string name="notelist_menu_new">Add note</string>
<string name="delete_remind_time_message">Delete reminder successfully</string>
<string name="set_remind_time_message">Set reminder</string>
<string name="note_alert_expired">Expired</string>
<string name="format_date_ymd">yyyyMMdd</string>
<string name="format_datetime_mdhm">MMMd kk:mm</string>
<string name="notealert_ok">Got it</string>
<string name="notealert_enter">Take a look</string>
<string name="note_link_tel">Call</string>
<string name="note_link_email">Send email</string>
<string name="note_link_web">Browse web</string>
<string name="note_link_other">Open map</string>
<!-- Text export file information -->
<string name="file_path">/MIUI/notes/</string>
<string name="file_name_txt_format">notes_%s.txt</string>
<!-- notes list string -->
<string name="format_folder_files_count">(%d)</string>
<string name="menu_create_folder">New Folder</string>
<string name="menu_export_text">Export text</string>
<string name="menu_sync">Sync</string>
<string name="menu_sync_cancel">Cancel syncing</string>
<string name="menu_setting">Settings</string>
<string name="menu_search">Search</string>
<string name="menu_delete">Delete</string>
<string name="menu_move">Move to folder</string>
<string name="menu_select_title">%d selected</string>
<string name="menu_select_none">Nothing selected, the operation is invalid</string>
<string name="menu_select_all">Select all</string>
<string name="menu_deselect_all">Deselect all</string>
<string name="menu_font_size">Font size</string>
<string name="menu_font_small">Small</string>
<string name="menu_font_normal">Medium</string>
<string name="menu_font_large">Large</string>
<string name="menu_font_super">Super</string>
<string name="menu_list_mode">Enter check list</string>
<string name="menu_normal_mode">Leave check list</string>
<string name="menu_folder_view">View folder</string>
<string name="menu_folder_delete">Delete folder</string>
<string name="menu_folder_change_name">Change folder name</string>
<string name="folder_exist">The folder %1$s exist, please rename</string>
<string name="menu_share">Share</string>
<string name="menu_send_to_desktop">Send to home</string>
<string name="menu_alert">Remind me</string>
<string name="menu_remove_remind">Delete reminder</string>
<string name="menu_title_select_folder">Select folder</string>
<string name="menu_move_parent_folder">Parent folder</string>
<string name="info_note_enter_desktop">Note added to home</string>
<string name="alert_message_delete_folder">Confirm to delete folder and its notes?</string>
<string name="alert_title_delete">Delete selected notes</string>
<string name="alert_message_delete_notes">Confirm to delete the selected %d notes?</string>
<string name="alert_message_delete_note">Confirm to delete this note?</string>
<string name="format_move_notes_to_folder">Have moved selected %1$d notes to %2$s folder</string>
<!-- Error information -->
<string name="error_sdcard_unmounted">SD card busy, not available now</string>
<string name="error_sdcard_export">Export failed, please check SD card</string>
<string name="error_note_not_exist">The note is not exist</string>
<string name="error_note_empty_for_clock">Sorry, can not set clock on empty note</string>
<string name="error_note_empty_for_send_to_desktop">Sorry, can not send and empty note to home</string>
<string name="success_sdcard_export">Export successful</string>
<string name="failed_sdcard_export">Export fail</string>
<string name="format_exported_file_location">Export text file (%1$s) to SD (%2$s) directory</string>
<!-- Sync -->
<string name="ticker_syncing">Syncing notes...</string>
<string name="ticker_success">Sync is successful</string>
<string name="ticker_fail">Sync is failed</string>
<string name="ticker_cancel">Sync is canceled</string>
<string name="success_sync_account">Sync is successful with account %1$s</string>
<string name="error_sync_network">Sync failed, please check network and account settings</string>
<string name="error_sync_internal">Sync failed, internal error occurs</string>
<string name="error_sync_cancelled">Sync is canceled</string>
<string name="sync_progress_login">Logging into %1$s...</string>
<string name="sync_progress_init_list">Getting remote note list...</string>
<string name="sync_progress_syncing">Synchronize local notes with Google Task...</string>
<!-- Preferences -->
<string name="preferences_title">Settings</string>
<string name="preferences_account_title">Sync account</string>
<string name="preferences_account_summary">Sync notes with google task</string>
<string name="preferences_last_sync_time">Last sync time %1$s</string>
<string name="preferences_last_sync_time_format">yyyy-MM-dd hh:mm:ss</string>
<string name="preferences_add_account">Add account</string>
<string name="preferences_menu_change_account">Change sync account</string>
<string name="preferences_menu_remove_account">Remove sync account</string>
<string name="preferences_menu_cancel">Cancel</string>
<string name="preferences_button_sync_immediately">Sync immediately</string>
<string name="preferences_button_sync_cancel">Cancel syncing</string>
<string name="preferences_dialog_change_account_title">Current account %1$s</string>
<string name="preferences_dialog_change_account_warn_msg">All sync related information will be deleted, which may result in duplicated items sometime</string>
<string name="preferences_dialog_select_account_title">Sync notes</string>
<string name="preferences_dialog_select_account_tips">Please select a google account. Local notes will be synced with google task.</string>
<string name="preferences_toast_cannot_change_account">Cannot change the account because sync is in progress</string>
<string name="preferences_toast_success_set_accout">%1$s has been set as the sync account</string>
<string name="preferences_bg_random_appear_title">New note background color random</string>
<string name="button_delete">Delete</string>
<string name="call_record_folder_name">Call notes</string>
<string name="hint_foler_name">Input name</string>
<string name="search_label">Searching Notes</string>
<string name="search_hint">Search notes</string>
<string name="search_setting_description">Text in your notes</string>
<string name="search">Notes</string>
<string name="datetime_dialog_ok">set</string>
<string name="datetime_dialog_cancel">cancel</string>
<plurals name="search_results_title">
<item quantity="one"><xliff:g id="number" example="1">%1$s</xliff:g> result for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item>
<!-- Case of 0 or 2 or more results. -->
<item quantity="other"><xliff:g id="number" example="15">%1$s</xliff:g> results for \"<xliff:g id="search" example="???">%2$s</xliff:g>\"</item>
</plurals>
</resources>

@ -63,6 +63,7 @@
</style>
<style name="NoteActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid">
<item name="android:visibility">visible</item>
<item name="android:displayOptions" />
<item name="android:visibility">gone</item>
</style>
</resources>

@ -1,4 +1,4 @@
#Mon Apr 21 20:22:51 CST 2025
#Mon Apr 21 20:32:54 CST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip

Loading…
Cancel
Save