Compare commits

..

55 Commits

Author SHA1 Message Date
ZhuRuimin 772828ea18 补充ui
3 years ago
18736624238 5fa482b174 ADD file via upload
3 years ago
ZhuRuimin 81ff446201 补充文档
3 years ago
ZhuRuimin 02fe023e10 完善全部功能代码
3 years ago
18736624238 2e9b66c6da ADD file via upload
3 years ago
18736624238 b5c61a8e99 ADD file via upload
3 years ago
18736624238 cc46271a53 ADD file via upload
3 years ago
18736624238 d601d90968 ADD file via upload
3 years ago
18736624238 d88b0f9300 ADD file via upload
3 years ago
18736624238 984c213ef0 ADD file via upload
3 years ago
18736624238 51c9b5d36a ADD file via upload
3 years ago
18736624238 493caa7e3d ADD file via upload
3 years ago
18736624238 6a0dbcf628 ADD file via upload
3 years ago
18736624238 91c60af2ed ADD file via upload
3 years ago
18736624238 c5a90c8998 ADD file via upload
3 years ago
18736624238 6bb79333e6 ADD file via upload
3 years ago
18736624238 81d670241b ADD file via upload
3 years ago
18736624238 cd793281bd ADD file via upload
3 years ago
18736624238 991ed90c14 ADD file via upload
3 years ago
18736624238 9885a1290e Delete 'doc/申博昊_小米便签代码标注.docx'
3 years ago
18736624238 239a39288a Delete 'doc/田浩_小米便签代码标注.docx'
3 years ago
18736624238 8b98a90685 Delete 'doc/朱睿民_小米便签代码标注.docx'
3 years ago
18736624238 17f31f1219 Delete 'doc/小米便签新增功能文档.docx'
3 years ago
18736624238 629b3922fb Delete 'doc/宋经纬_小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 bb9e400d89 Delete 'doc/宋经纬_小米便签代码标注.docx'
3 years ago
18736624238 8454c08ab8 Delete 'doc/孙瑛峻_小米便签代码标注.docx'
3 years ago
ZhuRuimin 49b9af0df4 完成功能代码
3 years ago
ZhuRuimin ac93025ac2 修改更高的的API版本,增加虚拟菜单键按钮便于调试
3 years ago
18736624238 282368b3c2 ADD file via upload
3 years ago
18736624238 d2134eee5c Delete 'doc/小米便签新增功能文档.docx'
3 years ago
18736624238 7de36910b6 ADD file via upload
3 years ago
18736624238 89291b374f ADD file via upload
3 years ago
18736624238 7a49c0cee4 ADD file via upload
3 years ago
18736624238 ca5ed6e448 ADD file via upload
3 years ago
18736624238 e596fade84 Delete 'doc/宋经纬小米便签代码标注.docx'
3 years ago
18736624238 3a3f61f5f5 ADD file via upload
3 years ago
18736624238 ce66de93ab ADD file via upload
3 years ago
18736624238 b680a8332c Delete '小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 9dd89fc34e Delete '宋经纬小米便签代码标注.docx'
3 years ago
18736624238 7d39ea2bb0 ADD file via upload
3 years ago
18736624238 76c676fa27 ADD file via upload
3 years ago
18736624238 2eac0bab09 Delete 'SJW_小米便签代码标注'
3 years ago
18736624238 fe1c209551 SJW_小米便签代码标注
3 years ago
18736624238 fa247fc12e Add SJW_小米便签代码标注
3 years ago
18736624238 2b5852bd41 ADD file via upload
3 years ago
18736624238 8419348d6d Delete '小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 c26d933a6a ADD file via upload
3 years ago
18736624238 f30f64ef32 Delete '小米便签开源代码的泛读报告.docx'
3 years ago
18736624238 05ac504ea3 ADD file via upload
3 years ago
18736624238 af9ddc8f96 Merge pull request '111' (#12) from dev into master
3 years ago
18736624238 c0c62afab8 Merge pull request 'syj_branch' (#11) from syj_branch into dev
3 years ago
syj 11b415f7e9 11
3 years ago
18736624238 118f4136a6 Merge pull request '补充文件夹以及readme文件' (#8) from zrm_branch into dev
3 years ago
18736624238 68fb5bd6df Merge pull request '补充gradle文件' (#7) from dev into master
3 years ago
18736624238 c73f729a3b Merge pull request 'dev->master测试' (#6) from dev into master
3 years ago

@ -1 +1,2 @@
#小米便签项目
#小米便签项目
11

@ -25,8 +25,8 @@ android {
defaultConfig {
applicationId "net.micode.notes"
minSdkVersion 14
targetSdkVersion 14
minSdkVersion 30
targetSdkVersion 30
}
buildTypes {

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,26 +1,10 @@
<?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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="net.micode.notes"
android:versionCode="1"
android:versionName="0.1" >
<uses-sdk android:minSdkVersion="14" />
android:versionName="0.1"
android:exported="true" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
@ -31,10 +15,27 @@
<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" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<application
android:icon="@drawable/icon_app"
android:label="@string/app_name" >
android:label="@string/app_name"
android:theme="@style/Theme.Material3.DynamicColors.Dark"
android:exported="true" >
<activity
android:name=".ui.EditActivity"
android:exported="false" />
<activity
android:name=".ui.AddActivity"
android:exported="false"
android:label="add notes" />
<activity
android:name=".ui.SafeFolderActivity"
android:label="safe folder"
android:exported="false" />
<activity
android:name=".ui.pwdActivity"
android:exported="false" />
<activity
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
@ -42,36 +43,38 @@
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan" >
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" >
<intent-filter>
android:theme="@style/NoteTheme"
android:exported="true" >
<intent-filter android:scheme="http"
tools:ignore="AppLinkUrlError">
<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>
@ -87,7 +90,8 @@
<receiver
android:name=".widget.NoteWidgetProvider_2x"
android:label="@string/app_widget2x2" >
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" />
@ -100,8 +104,8 @@
</receiver>
<receiver
android:name=".widget.NoteWidgetProvider_4x"
android:label="@string/app_widget4x4" >
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" />
@ -112,39 +116,34 @@
android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" />
</receiver>
<receiver android:name=".ui.AlarmInitReceiver" >
<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>
android:name=".ui.AlarmReceiver"
android:process=":remote" />
<activity
android:name=".ui.AlarmAlertActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" >
</activity>
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" />
<activity
android:name="net.micode.notes.ui.NotesPreferenceActivity"
android:name=".ui.NotesPreferenceActivity"
android:label="@string/preferences_title"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Holo.Light" >
</activity>
android:theme="@android:style/Theme.Holo.Light" />
<service
android:name="net.micode.notes.gtask.remote.GTaskSyncService"
android:exported="false" >
</service>
android:exported="false" />
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
</application>
</manifest>
</manifest>

@ -120,7 +120,7 @@ public class GTaskClient {
// need to re-login after account switch
if (mLoggedin
&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity
.getSyncAccountName(activity))) {
.getSyncAccountName(activity))) {
mLoggedin = false;
}
@ -582,4 +582,4 @@ public class GTaskClient {
public void resetUpdateArray() {
mUpdateArray = null;
}
}
}

@ -48,12 +48,12 @@ import java.util.Iterator;
import java.util.Map;
public class GTaskManager {// 该类用于管理 GTasks
private static final String TAG = GTaskManager.class.getSimpleName();// TAG 用于打印日志
public class GTaskManager {
private static final String TAG = GTaskManager.class.getSimpleName();
public static final int STATE_SUCCESS = 0;// 定义了一些常量
public static final int STATE_SUCCESS = 0;
public static final int STATE_NETWORK_ERROR = 1;// 定义了一些常量
public static final int STATE_NETWORK_ERROR = 1;
public static final int STATE_INTERNAL_ERROR = 2;
@ -87,7 +87,7 @@ public class GTaskManager {// 该类用于管理 GTasks
private HashMap<Long, String> mNidToGid;
private GTaskManager() { // 构造函数
private GTaskManager() {
mSyncing = false;
mCancelled = false;
mGTaskListHashMap = new HashMap<String, TaskList>();
@ -99,19 +99,19 @@ public class GTaskManager {// 该类用于管理 GTasks
mNidToGid = new HashMap<Long, String>();
}
public static synchronized GTaskManager getInstance() { // 单例模式
public static synchronized GTaskManager getInstance() {
if (mInstance == null) {
mInstance = new GTaskManager();
}
return mInstance;
}
public synchronized void setActivityContext(Activity activity) { // 设置 activity
public synchronized void setActivityContext(Activity activity) {
// used for getting authtoken
mActivity = activity;
}
public int sync(Context context, GTaskASyncTask asyncTask) { // 同步
public int sync(Context context, GTaskASyncTask asyncTask) {
if (mSyncing) {
Log.d(TAG, "Sync is in progress");
return STATE_SYNC_IN_PROGRESS;
@ -127,25 +127,25 @@ public class GTaskManager {// 该类用于管理 GTasks
mGidToNid.clear();
mNidToGid.clear();
try { // try catch 语句
try {
GTaskClient client = GTaskClient.getInstance();
client.resetUpdateArray();
// login google task
if (!mCancelled) {// 如果没有取消
if (!mCancelled) {
if (!client.login(mActivity)) {
throw new NetworkFailureException("login google task failed");
}
}
// get the task list from google
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list));// 发布进度
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list));
initGTaskList();
// do content sync work
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing));// 发布进度
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing));
syncContent();
} catch (NetworkFailureException e) {// 捕获异常
} catch (NetworkFailureException e) {
Log.e(TAG, e.toString());
return STATE_NETWORK_ERROR;
} catch (ActionFailureException e) {
@ -155,7 +155,7 @@ public class GTaskManager {// 该类用于管理 GTasks
Log.e(TAG, e.toString());
e.printStackTrace();
return STATE_INTERNAL_ERROR;
} finally {// finally 语句
} finally {
mGTaskListHashMap.clear();
mGTaskHashMap.clear();
mMetaHashMap.clear();
@ -165,25 +165,25 @@ public class GTaskManager {// 该类用于管理 GTasks
mSyncing = false;
}
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS;// 返回状态
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS;
}
private void initGTaskList() throws NetworkFailureException {// 初始化 GTasks
private void initGTaskList() throws NetworkFailureException {
if (mCancelled)
return;
GTaskClient client = GTaskClient.getInstance();// 获取 GTasks 客户端
GTaskClient client = GTaskClient.getInstance();
try {
JSONArray jsTaskLists = client.getTaskLists();// 获取 GTasks 列表
JSONArray jsTaskLists = client.getTaskLists();
// init meta list first
mMetaList = null;// 初始化 meta list
mMetaList = null;
for (int i = 0; i < jsTaskLists.length(); i++) {
JSONObject object = jsTaskLists.getJSONObject(i);
String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID);
String name = object.getString(GTaskStringUtils.GTASK_JSON_NAME);
if (name
.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META)) {// 如果是 meta 文件夹
.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_META)) {
mMetaList = new TaskList();
mMetaList.setContentByRemoteJSON(object);
@ -204,7 +204,6 @@ public class GTaskManager {// 该类用于管理 GTasks
}
// create meta list if not existed
// 创建 meta list
if (mMetaList == null) {
mMetaList = new TaskList();
mMetaList.setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX
@ -213,7 +212,6 @@ public class GTaskManager {// 该类用于管理 GTasks
}
// init task list
// 初始化 task list
for (int i = 0; i < jsTaskLists.length(); i++) {
JSONObject object = jsTaskLists.getJSONObject(i);
String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID);
@ -242,14 +240,14 @@ public class GTaskManager {// 该类用于管理 GTasks
}
}
}
} catch (JSONException e) {// 捕获异常
} catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("initGTaskList: handing JSONObject failed");
}
}
private void syncContent() throws NetworkFailureException {// 同步内容
private void syncContent() throws NetworkFailureException {
int syncType;
Cursor c = null;
String gid;
@ -257,12 +255,12 @@ public class GTaskManager {// 该类用于管理 GTasks
mLocalDeleteIdMap.clear();
if (mCancelled) {// 如果取消
if (mCancelled) {
return;
}
// for local deleted note
try {// try 语句
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
"(type<>? AND parent_id=?)", new String[] {
String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER)
@ -292,16 +290,16 @@ public class GTaskManager {// 该类用于管理 GTasks
syncFolder();
// for note existing in database
try {// try 语句
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
"(type=? AND parent_id<>?)", new String[] {
String.valueOf(Notes.TYPE_NOTE), String.valueOf(Notes.ID_TRASH_FOLER)
}, NoteColumns.TYPE + " DESC");
if (c != null) {// 如果 c 不为空
if (c != null) {
while (c.moveToNext()) {
gid = c.getString(SqlNote.GTASK_ID_COLUMN);
node = mGTaskHashMap.get(gid);
if (node != null) {// 如果 node 不为空
if (node != null) {
mGTaskHashMap.remove(gid);
mGidToNid.put(gid, c.getLong(SqlNote.ID_COLUMN));
mNidToGid.put(c.getLong(SqlNote.ID_COLUMN), gid);
@ -321,7 +319,7 @@ public class GTaskManager {// 该类用于管理 GTasks
Log.w(TAG, "failed to query existing note in database");
}
} finally { // finally 语句
} finally {
if (c != null) {
c.close();
c = null;
@ -329,7 +327,6 @@ public class GTaskManager {// 该类用于管理 GTasks
}
// go through remaining items
// for note not existing in database
Iterator<Map.Entry<String, Node>> iter = mGTaskHashMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Node> entry = iter.next();
@ -354,7 +351,7 @@ public class GTaskManager {// 该类用于管理 GTasks
}
private void syncFolder() throws NetworkFailureException {// 同步文件夹
private void syncFolder() throws NetworkFailureException {
Cursor c = null;
String gid;
Node node;
@ -365,28 +362,26 @@ public class GTaskManager {// 该类用于管理 GTasks
}
// for root folder
try {// try 语句
c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI,// 通过id查询
try {
c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI,
Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null);
if (c != null) {
c.moveToNext();
gid = c.getString(SqlNote.GTASK_ID_COLUMN);// 获取gtask_id
gid = c.getString(SqlNote.GTASK_ID_COLUMN);
node = mGTaskHashMap.get(gid);
if (node != null) {
mGTaskHashMap.remove(gid);
mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER); // for system folder, only
// update remote name if
// necessary
mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER);
mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid);
// for system folder, only update remote name if necessary
if (!node.getName().equals(
GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT))
doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c);
} else {
doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c);// 添加远程
doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c);
}
} else {
Log.w(TAG, "failed to query root folder");// 查询根文件夹失败
Log.w(TAG, "failed to query root folder");
}
} finally {
if (c != null) {
@ -397,27 +392,24 @@ public class GTaskManager {// 该类用于管理 GTasks
// for call-note folder
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)",// 通过id查询
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)",
new String[] {
String.valueOf(Notes.ID_CALL_RECORD_FOLDER)
}, null);
if (c != null) { // 如果 c 不为空
if (c != null) {
if (c.moveToNext()) {
gid = c.getString(SqlNote.GTASK_ID_COLUMN);
node = mGTaskHashMap.get(gid);
if (node != null) {
mGTaskHashMap.remove(gid);
mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER);// for system folder,
// only update
// remote name if
// necessary
mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER);
mNidToGid.put((long) Notes.ID_CALL_RECORD_FOLDER, gid);
// for system folder, only update remote name if
// necessary
if (!node.getName().equals(
GTaskStringUtils.MIUI_FOLDER_PREFFIX
+ GTaskStringUtils.FOLDER_CALL_NOTE))
doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c);// 更新远程
doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c);
} else {
doContentSync(Node.SYNC_ACTION_ADD_REMOTE, node, c);
}
@ -530,29 +522,29 @@ public class GTaskManager {// 该类用于管理 GTasks
}
}
private void addLocalNode(Node node) throws NetworkFailureException { // 添加本地节点
private void addLocalNode(Node node) throws NetworkFailureException {
if (mCancelled) {
return;
}
SqlNote sqlNote; // sql笔记
SqlNote sqlNote;
if (node instanceof TaskList) {
if (node.getName().equals(// 根目录
if (node.getName().equals(
GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) {
sqlNote = new SqlNote(mContext, Notes.ID_ROOT_FOLDER);
} else if (node.getName().equals(// 回收站
GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) { // 通话记录
} else if (node.getName().equals(
GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) {
sqlNote = new SqlNote(mContext, Notes.ID_CALL_RECORD_FOLDER);
} else {// 其他文件夹
} else {
sqlNote = new SqlNote(mContext);
sqlNote.setContent(node.getLocalJSONFromContent());
sqlNote.setParentId(Notes.ID_ROOT_FOLDER);
}
} else {// 其他节点
} else {
sqlNote = new SqlNote(mContext);
JSONObject js = node.getLocalJSONFromContent();
try {
if (js.has(GTaskStringUtils.META_HEAD_NOTE)) {// 备注
if (js.has(GTaskStringUtils.META_HEAD_NOTE)) {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
if (note.has(NoteColumns.ID)) {
long id = note.getLong(NoteColumns.ID);
@ -563,7 +555,7 @@ public class GTaskManager {// 该类用于管理 GTasks
}
}
if (js.has(GTaskStringUtils.META_HEAD_DATA)) {// 数据
if (js.has(GTaskStringUtils.META_HEAD_DATA)) {
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
@ -578,18 +570,18 @@ public class GTaskManager {// 该类用于管理 GTasks
}
}
} catch (JSONException e) {// json异常
} catch (JSONException e) {
Log.w(TAG, e.toString());
e.printStackTrace();
}
sqlNote.setContent(js);// 设置内容
sqlNote.setContent(js);
Long parentId = mGidToNid.get(((Task) node).getParent().getGid());// 获取父节点
if (parentId == null) {// 父节点为空
Long parentId = mGidToNid.get(((Task) node).getParent().getGid());
if (parentId == null) {
Log.e(TAG, "cannot find task's parent id locally");
throw new ActionFailureException("cannot add local node");
}
sqlNote.setParentId(parentId.longValue());// 设置父节点
sqlNote.setParentId(parentId.longValue());
}
// create the local node
@ -604,17 +596,17 @@ public class GTaskManager {// 该类用于管理 GTasks
updateRemoteMeta(node.getGid(), sqlNote);
}
private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException {// 更新本地节点
private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException {
if (mCancelled) {
return;
}
SqlNote sqlNote;// sql笔记
SqlNote sqlNote;
// update the note locally
sqlNote = new SqlNote(mContext, c);
sqlNote.setContent(node.getLocalJSONFromContent());// 设置内容
sqlNote.setContent(node.getLocalJSONFromContent());
Long parentId = (node instanceof Task) ? mGidToNid.get(((Task) node).getParent().getGid())// 获取父节点
Long parentId = (node instanceof Task) ? mGidToNid.get(((Task) node).getParent().getGid())
: new Long(Notes.ID_ROOT_FOLDER);
if (parentId == null) {
Log.e(TAG, "cannot find task's parent id locally");
@ -624,10 +616,10 @@ public class GTaskManager {// 该类用于管理 GTasks
sqlNote.commit(true);
// update meta info
updateRemoteMeta(node.getGid(), sqlNote);// 更新远程元数据
updateRemoteMeta(node.getGid(), sqlNote);
}
private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException {// 添加远程节点
private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException {
if (mCancelled) {
return;
}
@ -636,7 +628,7 @@ public class GTaskManager {// 该类用于管理 GTasks
Node n;
// update remotely
if (sqlNote.isNoteType()) {// 笔记类型
if (sqlNote.isNoteType()) {
Task task = new Task();
task.setContentByLocalJSON(sqlNote.getContent());
@ -652,7 +644,7 @@ public class GTaskManager {// 该类用于管理 GTasks
// add meta
updateRemoteMeta(task.getGid(), sqlNote);
} else {// 文件夹类型
} else {
TaskList tasklist = null;
// we need to skip folder if it has already existed
@ -664,8 +656,8 @@ public class GTaskManager {// 该类用于管理 GTasks
else
folderName += sqlNote.getSnippet();
Iterator<Map.Entry<String, TaskList>> iter = mGTaskListHashMap.entrySet().iterator();// 迭代器
while (iter.hasNext()) {// 遍历
Iterator<Map.Entry<String, TaskList>> iter = mGTaskListHashMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, TaskList> entry = iter.next();
String gid = entry.getKey();
TaskList list = entry.getValue();
@ -680,7 +672,7 @@ public class GTaskManager {// 该类用于管理 GTasks
}
// no match we can add now
if (tasklist == null) {// 任务列表为空
if (tasklist == null) {
tasklist = new TaskList();
tasklist.setContentByLocalJSON(sqlNote.getContent());
GTaskClient.getInstance().createTaskList(tasklist);
@ -690,7 +682,7 @@ public class GTaskManager {// 该类用于管理 GTasks
}
// update local note
sqlNote.setGtaskId(n.getGid());// 设置gid
sqlNote.setGtaskId(n.getGid());
sqlNote.commit(false);
sqlNote.resetLocalModified();
sqlNote.commit(true);
@ -700,7 +692,7 @@ public class GTaskManager {// 该类用于管理 GTasks
mNidToGid.put(sqlNote.getId(), n.getGid());
}
private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException {// 更新远程节点
private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException {
if (mCancelled) {
return;
}
@ -738,7 +730,7 @@ public class GTaskManager {// 该类用于管理 GTasks
sqlNote.commit(true);
}
private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException {// 更新远程元数据
private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException {
if (sqlNote != null && sqlNote.isNoteType()) {
MetaData metaData = mMetaHashMap.get(gid);
if (metaData != null) {
@ -754,7 +746,7 @@ public class GTaskManager {// 该类用于管理 GTasks
}
}
private void refreshLocalSyncId() throws NetworkFailureException {// 刷新本地同步id
private void refreshLocalSyncId() throws NetworkFailureException {
if (mCancelled) {
return;
}
@ -766,12 +758,12 @@ public class GTaskManager {// 该类用于管理 GTasks
initGTaskList();
Cursor c = null;
try {// 尝试
try {
c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE,
"(type<>? AND parent_id<>?)", new String[] {
String.valueOf(Notes.TYPE_SYSTEM), String.valueOf(Notes.ID_TRASH_FOLER)
}, NoteColumns.TYPE + " DESC");
if (c != null) {// 如果游标不为空
if (c != null) {
while (c.moveToNext()) {
String gid = c.getString(SqlNote.GTASK_ID_COLUMN);
Node node = mGTaskHashMap.get(gid);
@ -781,7 +773,7 @@ public class GTaskManager {// 该类用于管理 GTasks
values.put(NoteColumns.SYNC_ID, node.getLastModified());
mContentResolver.update(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI,
c.getLong(SqlNote.ID_COLUMN)), values, null, null);
} else { // if we can't find the node, it means the node is deleted remotely
} else {
Log.e(TAG, "something is missed");
throw new ActionFailureException(
"some local items don't have gid after sync");
@ -800,10 +792,9 @@ public class GTaskManager {// 该类用于管理 GTasks
public String getSyncAccount() {
return GTaskClient.getInstance().getSyncAccount().name;
} // 获取同步账户
}
public void cancelSync() {
mCancelled = true;
} // 取消同步
}
}

@ -219,10 +219,6 @@ public class BackupUtils {
* Note will be exported as text which is user readable
*/
public int exportToText() {
if (!externalStorageAvailable()) {
Log.d(TAG, "Media was not mounted");
return STATE_SD_CARD_UNMOUONTED;
}
PrintStream ps = getExportToTextPrintStream();
if (ps == null) {

@ -0,0 +1,59 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import net.micode.notes.R;
import net.micode.notes.ui.bean.Note;
import net.micode.notes.util.ToastUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
public class AddActivity extends Activity {
private EditText etContent;
private NoteDbOpenHelper mNoteDbOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
etContent = findViewById(R.id.sf_et_1);
mNoteDbOpenHelper = new NoteDbOpenHelper(this);
}
public void add(View view) {
String content = etContent.getText().toString();
Note note = new Note();
note.setContent(content);
note.setCreatedTime(getCurrentTimeFormat());
long row = mNoteDbOpenHelper.insertData(note);
if(row != -1){
ToastUtil.toastShort(this,"Add Success");
this.finish();
}else{
ToastUtil.toastShort(this,"Add Fail");
}
}
private String getCurrentTimeFormat() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM月dd HH:mm:ss");
Date date = new Date();
return simpleDateFormat.format(date);
}
}

@ -0,0 +1,72 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import net.micode.notes.R;
import net.micode.notes.ui.bean.Note;
import net.micode.notes.util.ToastUtil;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class EditActivity extends Activity {
private Note note;
private EditText etContent;
private NoteDbOpenHelper mNoteDbOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
etContent = findViewById(R.id.sf_et_2);
initData();
}
private void initData() {
Intent intent = getIntent();
note = (Note) intent.getSerializableExtra("note");
if(note!=null){
etContent.setText(note.getContent());
}
mNoteDbOpenHelper = new NoteDbOpenHelper(this);
}
public void save(View view) {
String content = etContent.getText().toString();
note.setContent(content);
note.setCreatedTime(getCurrentTimeFormat());
long row = mNoteDbOpenHelper.updateData(note);
if(row != -1 && row != 0){
ToastUtil.toastShort(this,"Edit Success");
this.finish();
}else{
ToastUtil.toastShort(this,"Edit Fail");
}
}
private String getCurrentTimeFormat() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM月dd HH:mm:ss");
TimeZone time = TimeZone.getTimeZone("Etc/GMT-8"); //转换为中国时区
TimeZone.setDefault(time);
Date date = new Date();
return simpleDateFormat.format(date);
}
}

@ -14,7 +14,7 @@
* limitations under the License.
*/
package net.micode.notes.ui; //该类所在的包名
package net.micode.notes.ui;
import android.content.Context;
import android.database.Cursor;
@ -29,30 +29,25 @@ import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
// FoldersListAdapter 类的定义,扩展了 CursorAdapter 类。
public class FoldersListAdapter extends CursorAdapter {
public static final String [] PROJECTION = {
NoteColumns.ID,
NoteColumns.SNIPPET
};
// 定义数据库查询的投影和列的索引
public static final int ID_COLUMN = 0;
public static final int NAME_COLUMN = 1;
// FoldersListAdapter 类的构造函数,它调用父类的构造函数。
public FoldersListAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
}
//CursorAdapter 类的一个方法的实现,用于创建新的列表项视图。
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new FolderListItem(context);
}
// CursorAdapter 类的一个方法的实现,用于将数据绑定到列表项视图上。
@Override
public void bindView(View view, Context context, Cursor cursor) {
if (view instanceof FolderListItem) {
@ -62,15 +57,12 @@ public class FoldersListAdapter extends CursorAdapter {
}
}
// 自定义方法,用于获取指定位置的文件夹名称
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);
}
// FoldersListAdapter 类的一个内部类,用于表示列表项视图。它扩展了 LinearLayout 类,并维护了一个 TextView 来显示文件夹名称。
// bind() 方法用于将数据绑定到列表项视图上
private class FolderListItem extends LinearLayout {
private TextView mName;

@ -0,0 +1,128 @@
package net.micode.notes.ui;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import net.micode.notes.ui.bean.Note;
import java.util.ArrayList;
import java.util.List;
public class NoteDbOpenHelper extends SQLiteOpenHelper {
private static final String DB_NAME="noteSQLite.db";
private static final String TABLE_NAME_NOTE = "note";
private static final String CREATE_TABLE_SQL = "create table " + TABLE_NAME_NOTE + " (id integer primary key autoincrement, content text, create_time text)";
public NoteDbOpenHelper(Context context){
super(context,DB_NAME,null,1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_SQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long insertData(Note note){
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("content",note.getContent());
values.put("create_time",note.getCreatedTime());
return db.insert(TABLE_NAME_NOTE,null,values);
}
public int deleteFromDbById(String id){
SQLiteDatabase db = getWritableDatabase();
return db.delete(TABLE_NAME_NOTE,"id like ?", new String[]{id});
}
public int updateData(Note note) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("content", note.getContent());
values.put("create_time", note.getCreatedTime());
return db.update(TABLE_NAME_NOTE, values, "id like ?", new String[]{note.getId()});
}
public List<Note> queryAllFromDb(){
SQLiteDatabase db = getWritableDatabase();
List<Note> notelist = new ArrayList<>();
Cursor cursor = db.query(TABLE_NAME_NOTE,null,null,null,null,null,null);
if (cursor != null){
while (cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex("id"));
String content = cursor.getString(cursor.getColumnIndex("content"));
String createTime = cursor.getString(cursor.getColumnIndex("create_time"));
Note note = new Note();
note.setId(id);
note.setContent(content);
note.setCreatedTime(createTime);
notelist.add(note);
}
cursor.close();
}
return notelist;
}
public List<Note> queryFromDbByContent(String content){
if (TextUtils.isEmpty(content)){
return queryAllFromDb();
}
SQLiteDatabase db = getWritableDatabase();
List<Note> noteList = new ArrayList<>();
Cursor cursor = db.query(TABLE_NAME_NOTE,null,"content like ?",new String[]{"%"+content+"%"},null,null,null);
if (cursor != null){
while (cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex("id"));
String content1 = cursor.getString(cursor.getColumnIndex("content"));
String createTime = cursor.getString(cursor.getColumnIndex("create_time"));
Note note = new Note();
note.setId(id);
note.setContent(content1);
note.setCreatedTime(createTime);
noteList.add(note);
}
cursor.close();
}
return noteList;
}
}

@ -51,6 +51,7 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Button;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
@ -74,7 +75,7 @@ import java.util.regex.Pattern;
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
private class HeadViewHolder { // 头部视图的持有者
private class HeadViewHolder {
public TextView tvModified;
public ImageView ivAlertIcon;
@ -85,7 +86,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
static { // 背景选择器按钮的映射
static {
sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED);
sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE);
@ -94,7 +95,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<Integer, Integer>();
static { // 背景选择器选择的映射
static {
sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select);
sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select);
sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select);
@ -103,7 +104,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<Integer, Integer>();
static { // 字体大小按钮的映射
static {
sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE);
sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL);
sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM);
@ -111,54 +112,57 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private static final Map<Integer, Integer> sFontSelectorSelectionMap = new HashMap<Integer, Integer>();
static {// 字体选择器选择的映射
static {
sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select);
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select);
sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select);
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select);
}
private static final String TAG = "NoteEditActivity";// 标签
private static final String TAG = "NoteEditActivity";
private HeadViewHolder mNoteHeaderHolder;// 头部视图的持有者
private HeadViewHolder mNoteHeaderHolder;
private View mHeadViewPanel;// 头部视图面板
private View mHeadViewPanel;
private View mNoteBgColorSelector;// 笔记背景颜色选择器
private View mNoteBgColorSelector;
private View mFontSizeSelector;// 字体大小选择器
private View mFontSizeSelector;
private EditText mNoteEditor;// 笔记编辑器
private EditText mNoteEditor;
private View mNoteEditorPanel;// 笔记编辑器面板
private View mNoteEditorPanel;
private WorkingNote mWorkingNote;// 工作笔记
private WorkingNote mWorkingNote;
private SharedPreferences mSharedPrefs;// 共享首选项
private int mFontSizeId;// 字体大小ID
private SharedPreferences mSharedPrefs;
private int mFontSizeId;
private static final String PREFERENCE_FONT_SIZE = "pref_font_size";// 字体大小首选项
private static final String PREFERENCE_FONT_SIZE = "pref_font_size";
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10;// 快捷方式图标标题的最大长度
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10;
public static final String TAG_CHECKED = String.valueOf('\u221A');// 标签已选中
public static final String TAG_UNCHECKED = String.valueOf('\u25A1');// 标签未选中
public static final String TAG_CHECKED = String.valueOf('\u221A');
public static final String TAG_UNCHECKED = String.valueOf('\u25A1');
private LinearLayout mEditTextList;// 编辑文本列表
private LinearLayout mEditTextList;
private String mUserQuery;// 用户查询
private Pattern mPattern;// 模式
private String mUserQuery;
private Pattern mPattern;
@Override
protected void onCreate(Bundle savedInstanceState) {// 创建
super.onCreate(savedInstanceState);// 调用超类的方法
this.setContentView(R.layout.note_edit);// 设置布局
private Button menuButton;
if (savedInstanceState == null && !initActivityState(getIntent())) {// 如果保存的实例状态为空且初始化活动状态失败
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
menuButton = (Button) findViewById(R.id.btn_show_menu);
menuButton.setOnClickListener(new NoteEditActivity.MenuBtnOnClickListener());
if (savedInstanceState == null && !initActivityState(getIntent())) {
finish();
return;
}
initResources();// 初始化资源
initResources();
}
/**
@ -166,7 +170,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* user load this activity, we should restore the former state
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {//
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) {
Intent intent = new Intent(Intent.ACTION_VIEW);
@ -870,4 +874,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
private class MenuBtnOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
openOptionsMenu();
}
}
}

@ -37,7 +37,7 @@ import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
public class NoteEditText extends EditText {//继承自EditText
public class NoteEditText extends androidx.appcompat.widget.AppCompatEditText {
private static final String TAG = "NoteEditText";
private int mIndex;
private int mSelectionStartBeforeDelete;
@ -56,51 +56,51 @@ public class NoteEditText extends EditText {//继承自EditText
/**
* Call by the {@link NoteEditActivity} to delete or add edit text
*/
public interface OnTextViewChangeListener {//接口
public interface OnTextViewChangeListener {
/**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
* and the text is null
*/
void onEditTextDelete(int index, String text);//删除当前的edittext
void onEditTextDelete(int index, String text);
/**
* Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER}
* happen
*/
void onEditTextEnter(int index, String text);//在当前的edittext后面添加edittext
void onEditTextEnter(int index, String text);
/**
* Hide or show item option when text change
*/
void onTextChange(int index, boolean hasText);//隐藏或显示item选项
void onTextChange(int index, boolean hasText);
}
private OnTextViewChangeListener mOnTextViewChangeListener;//接口对象
private OnTextViewChangeListener mOnTextViewChangeListener;
public NoteEditText(Context context) {//构造函数
public NoteEditText(Context context) {
super(context, null);
mIndex = 0;
}
public void setIndex(int index) {
mIndex = index;
}//设置index
}
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {//设置接口对象
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener;
}
public NoteEditText(Context context, AttributeSet attrs) {//构造函数
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle);
}
public NoteEditText(Context context, AttributeSet attrs, int defStyle) {//构造函数
public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {//触摸事件
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
@ -122,7 +122,7 @@ public class NoteEditText extends EditText {//继承自EditText
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {//按键事件
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
if (mOnTextViewChangeListener != null) {
@ -139,7 +139,7 @@ public class NoteEditText extends EditText {//继承自EditText
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {//按键事件
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_DEL:
if (mOnTextViewChangeListener != null) {
@ -168,7 +168,7 @@ public class NoteEditText extends EditText {//继承自EditText
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {//焦点改变事件
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (mOnTextViewChangeListener != null) {
if (!focused && TextUtils.isEmpty(getText())) {
mOnTextViewChangeListener.onTextChange(mIndex, false);
@ -180,7 +180,7 @@ public class NoteEditText extends EditText {//继承自EditText
}
@Override
protected void onCreateContextMenu(ContextMenu menu) {//创建上下文菜单
protected void onCreateContextMenu(ContextMenu menu) {
if (getText() instanceof Spanned) {
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();

@ -27,7 +27,7 @@ import net.micode.notes.tool.DataUtils;
public class NoteItemData {
static final String [] PROJECTION = new String [] {//投影
static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
@ -76,7 +76,7 @@ public class NoteItemData {
private boolean mIsOneNoteFollowingFolder;
private boolean mIsMultiNotesFollowingFolder;
public NoteItemData(Context context, Cursor cursor) {//构造函数
public NoteItemData(Context context, Cursor cursor) {
mId = cursor.getLong(ID_COLUMN);
mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN);
mBgColorId = cursor.getInt(BG_COLOR_ID_COLUMN);
@ -109,14 +109,14 @@ public class NoteItemData {
checkPostion(cursor);
}
private void checkPostion(Cursor cursor) {//检查位置
private void checkPostion(Cursor cursor) {
mIsLastItem = cursor.isLast() ? true : false;
mIsFirstItem = cursor.isFirst() ? true : false;
mIsOnlyOneItem = (cursor.getCount() == 1);
mIsMultiNotesFollowingFolder = false;
mIsOneNoteFollowingFolder = false;
if (mType == Notes.TYPE_NOTE && !mIsFirstItem) {//如果是笔记并且不是第一个
if (mType == Notes.TYPE_NOTE && !mIsFirstItem) {
int position = cursor.getPosition();
if (cursor.moveToPrevious()) {
if (cursor.getInt(TYPE_COLUMN) == Notes.TYPE_FOLDER
@ -136,89 +136,89 @@ public class NoteItemData {
public boolean isOneFollowingFolder() {
return mIsOneNoteFollowingFolder;
}//是否是一个文件夹
}
public boolean isMultiFollowingFolder() {
return mIsMultiNotesFollowingFolder;
}//是否是多个文件夹
}
public boolean isLast() {
return mIsLastItem;
}//是否是最后一个
}
public String getCallName() {
return mName;
}//获取呼叫名字
}
public boolean isFirst() {
return mIsFirstItem;
}//是否是第一个
}
public boolean isSingle() {
return mIsOnlyOneItem;
}//是否是单个
}
public long getId() {
return mId;
}//获取id
}
public long getAlertDate() {
return mAlertDate;
}//获取提醒日期
}
public long getCreatedDate() {
return mCreatedDate;
}//获取创建日期
}
public boolean hasAttachment() {
return mHasAttachment;
}//是否有附件
}
public long getModifiedDate() {
return mModifiedDate;
}//获取修改日期
}
public int getBgColorId() {
return mBgColorId;
}//获取背景颜色id
}
public long getParentId() {
return mParentId;
}//获取父id
}
public int getNotesCount() {
return mNotesCount;
}//获取笔记数量
}
public long getFolderId () {
return mParentId;
}//获取文件夹id
}
public int getType() {
return mType;
}//获取类型
}
public int getWidgetType() {
return mWidgetType;
}//获取小部件类型
}
public int getWidgetId() {
return mWidgetId;
}//获取小部件id
}
public String getSnippet() {
return mSnippet;
}//获取片段
}
public boolean hasAlert() {
return (mAlertDate > 0);
}//是否有提醒
}
public boolean isCallRecord() {//是否是呼叫记录
public boolean isCallRecord() {
return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber));
}
public static int getNoteType(Cursor cursor) {
return cursor.getInt(TYPE_COLUMN);
}//获取笔记类型
}
}

@ -72,13 +72,23 @@ import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { //用来显示所有的笔记
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
private static final int FOLDER_LIST_QUERY_TOKEN = 1;
@ -105,6 +115,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private Button mAddNewNote;
private Button menuButton;
private boolean mDispatch;
private int mOriginY;
@ -135,12 +147,26 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private final static int REQUEST_CODE_OPEN_NODE = 102;
private final static int REQUEST_CODE_NEW_NODE = 103;
public Button mBtnsf;
@Override
protected void onCreate(Bundle savedInstanceState) {//创建
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
initResources();
mBtnsf = findViewById(R.id.btn_sf);
mBtnsf.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=null;
intent = new Intent(NotesListActivity.this,pwdActivity.class);
startActivity(intent);
}
});
/**
* Insert an introduction when user firstly use this application
*/
@ -148,7 +174,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {//返回
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK
&& (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) {
mNotesListAdapter.changeCursor(null);
@ -157,7 +183,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private void setAppInfoFromRawRes() {//设置应用信息
private void setAppInfoFromRawRes() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) {
StringBuilder sb = new StringBuilder();
@ -204,12 +230,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
protected void onStart() {//开始
protected void onStart() {
super.onStart();
startAsyncNotesListQuery();
}
private void initResources() {//初始化资源
private void initResources() {
mContentResolver = this.getContentResolver();
mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver());
mCurrentFolderId = Notes.ID_ROOT_FOLDER;
@ -223,6 +249,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mAddNewNote = (Button) findViewById(R.id.btn_new_note);
mAddNewNote.setOnClickListener(this);
mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());
menuButton = (Button) findViewById(R.id.btn_show_menu);
menuButton.setOnClickListener(new MenuBtnOnClickListener());
mDispatch = false;
mDispatchY = 0;
mOriginY = 0;
@ -231,12 +259,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mModeCallBack = new ModeCallback();
}
private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener {//模式回调
private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener {
private DropdownMenu mDropDownMenu;
private ActionMode mActionMode;
private MenuItem mMoveMenu;
public boolean onCreateActionMode(ActionMode mode, Menu menu) {//创建
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
getMenuInflater().inflate(R.menu.note_list_options, menu);
menu.findItem(R.id.delete).setOnMenuItemClickListener(this);
mMoveMenu = menu.findItem(R.id.move);
@ -269,7 +297,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
return true;
}
private void updateMenu() {//更新菜单
private void updateMenu() {
int selectedCount = mNotesListAdapter.getSelectedCount();
// Update dropdown menu
String format = getResources().getString(R.string.menu_select_title, selectedCount);
@ -286,17 +314,17 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {//准备
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {//点击
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// TODO Auto-generated method stub
return false;
}
public void onDestroyActionMode(ActionMode mode) {//销毁
public void onDestroyActionMode(ActionMode mode) {
mNotesListAdapter.setChoiceMode(false);
mNotesListView.setLongClickable(true);
mAddNewNote.setVisibility(View.VISIBLE);
@ -304,7 +332,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
public void finishActionMode() {
mActionMode.finish();
}//结束
}
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
@ -312,14 +340,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
updateMenu();
}
public boolean onMenuItemClick(MenuItem item) {//菜单点击
public boolean onMenuItemClick(MenuItem item) {
if (mNotesListAdapter.getSelectedCount() == 0) {
Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none),
Toast.LENGTH_SHORT).show();
return true;
}
switch (item.getItemId()) {//项目
switch (item.getItemId()) {
case R.id.delete:
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(getString(R.string.alert_title_delete));
@ -346,9 +374,17 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private class NewNoteOnTouchListener implements OnTouchListener {//新的触摸事件
public boolean onTouch(View v, MotionEvent event) {//触摸
private class MenuBtnOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
openOptionsMenu();
}
}
private class NewNoteOnTouchListener implements OnTouchListener {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
Display display = getWindowManager().getDefaultDisplay();
@ -386,7 +422,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
break;
}
case MotionEvent.ACTION_MOVE: { //移动
case MotionEvent.ACTION_MOVE: {
if (mDispatch) {
mDispatchY += (int) event.getY() - mOriginY;
event.setLocation(event.getX(), mDispatchY);
@ -395,7 +431,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
break;
}
default: {
if (mDispatch) {//分发
if (mDispatch) {
event.setLocation(event.getX(), mDispatchY);
mDispatch = false;
return mNotesListView.dispatchTouchEvent(event);
@ -408,7 +444,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
};
private void startAsyncNotesListQuery() {//开始异步笔记列表查询
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
@ -417,7 +453,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
private final class BackgroundQueryHandler extends AsyncQueryHandler { //后台查询处理
private final class BackgroundQueryHandler extends AsyncQueryHandler {
public BackgroundQueryHandler(ContentResolver contentResolver) {
super(contentResolver);
}
@ -441,7 +477,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private void showFolderListMenu(Cursor cursor) {//显示文件夹列表菜单
private void showFolderListMenu(Cursor cursor) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(R.string.menu_title_select_folder);
final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor);
@ -462,14 +498,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
builder.show();
}
private void createNewNote() {//创建新的笔记
private void createNewNote() {
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId);
this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE);
}
private void batchDelete() {//批量删除
private void batchDelete() {
new AsyncTask<Void, Void, HashSet<AppWidgetAttribute>>() {
protected HashSet<AppWidgetAttribute> doInBackground(Void... unused) {
HashSet<AppWidgetAttribute> widgets = mNotesListAdapter.getSelectedWidget();
@ -492,7 +528,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
protected void onPostExecute(HashSet<AppWidgetAttribute> widgets) {//执行后
protected void onPostExecute(HashSet<AppWidgetAttribute> widgets) {
if (widgets != null) {
for (AppWidgetAttribute widget : widgets) {
if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID
@ -506,7 +542,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}.execute();
}
private void deleteFolder(long folderId) {//删除文件夹
private void deleteFolder(long folderId) {
if (folderId == Notes.ID_ROOT_FOLDER) {
Log.e(TAG, "Wrong folder id, should not happen " + folderId);
return;
@ -516,14 +552,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
ids.add(folderId);
HashSet<AppWidgetAttribute> widgets = DataUtils.getFolderNoteWidget(mContentResolver,
folderId);
if (!isSyncMode()) {//如果不是同步模式
if (!isSyncMode()) {
// if not synced, delete folder directly
DataUtils.batchDeleteNotes(mContentResolver, ids);
} else {
// in sync mode, we'll move the deleted folder into the trash folder
DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_TRASH_FOLER);
}
if (widgets != null) {//如果小部件不为空
if (widgets != null) {
for (AppWidgetAttribute widget : widgets) {
if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) {
@ -533,14 +569,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private void openNode(NoteItemData data) {//打开笔记
private void openNode(NoteItemData data) {
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_UID, data.getId());
this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
}
private void openFolder(NoteItemData data) {//打开文件夹
private void openFolder(NoteItemData data) {
mCurrentFolderId = data.getId();
startAsyncNotesListQuery();
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
@ -557,7 +593,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mTitleBar.setVisibility(View.VISIBLE);
}
public void onClick(View v) {//点击事件
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_new_note:
createNewNote();
@ -567,24 +603,24 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private void showSoftInput() {//显示软键盘
private void showSoftInput() {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputMethodManager != null) {
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
}
private void hideSoftInput(View view) {//隐藏软键盘
private void hideSoftInput(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
private void showCreateOrModifyFolderDialog(final boolean create) {//显示创建或修改文件夹对话框
private void showCreateOrModifyFolderDialog(final boolean create) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null);
final EditText etName = (EditText) view.findViewById(R.id.et_foler_name);
showSoftInput();
if (!create) {//如果不是创建
if (!create) {
if (mFocusNoteDataItem != null) {
etName.setText(mFocusNoteDataItem.getSnippet());
builder.setTitle(getString(R.string.menu_folder_change_name));
@ -604,19 +640,19 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
});
final Dialog dialog = builder.setView(view).show();//显示对话框
final Button positive = (Button)dialog.findViewById(android.R.id.button1); //获取确定按钮
final Dialog dialog = builder.setView(view).show();
final Button positive = (Button)dialog.findViewById(android.R.id.button1);
positive.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
hideSoftInput(etName);
String name = etName.getText().toString();
if (DataUtils.checkVisibleFolderName(mContentResolver, name)) {//如果文件夹名字存在
if (DataUtils.checkVisibleFolderName(mContentResolver, name)) {
Toast.makeText(NotesListActivity.this, getString(R.string.folder_exist, name),
Toast.LENGTH_LONG).show();
etName.setSelection(0, etName.length());
return;
}
if (!create) {//如果不是创建
if (!create) {
if (!TextUtils.isEmpty(name)) {
ContentValues values = new ContentValues();
values.put(NoteColumns.SNIPPET, name);
@ -627,7 +663,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
String.valueOf(mFocusNoteDataItem.getId())
});
}
} else if (!TextUtils.isEmpty(name)) { //如果是创建
} else if (!TextUtils.isEmpty(name)) {
ContentValues values = new ContentValues();
values.put(NoteColumns.SNIPPET, name);
values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
@ -638,26 +674,26 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
});
if (TextUtils.isEmpty(etName.getText())) {
positive.setEnabled(false);//如果名字为空,确定按钮不可用
positive.setEnabled(false);
}
/**
* When the name edit text is null, disable the positive button
*/
etName.addTextChangedListener(new TextWatcher() {//添加文本改变监听器
etName.addTextChangedListener(new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (TextUtils.isEmpty(etName.getText())) {//如果名字为空
if (TextUtils.isEmpty(etName.getText())) {
positive.setEnabled(false);
} else {
positive.setEnabled(true);
}
}
public void afterTextChanged(Editable s) {//文本改变后
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
@ -665,7 +701,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
public void onBackPressed() { //返回键
public void onBackPressed() {
switch (mState) {
case SUB_FOLDER:
mCurrentFolderId = Notes.ID_ROOT_FOLDER;
@ -688,7 +724,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
private void updateWidget(int appWidgetId, int appWidgetType) {//更新小部件
private void updateWidget(int appWidgetId, int appWidgetType) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
if (appWidgetType == Notes.TYPE_WIDGET_2X) {
intent.setClass(this, NoteWidgetProvider_2x.class);
@ -707,7 +743,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
setResult(RESULT_OK, intent);
}
private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() {//文件夹上下文菜单监听器
private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if (mFocusNoteDataItem != null) {
menu.setHeaderTitle(mFocusNoteDataItem.getSnippet());
@ -719,7 +755,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
};
@Override
public void onContextMenuClosed(Menu menu) {//上下文菜单关闭
public void onContextMenuClosed(Menu menu) {
if (mNotesListView != null) {
mNotesListView.setOnCreateContextMenuListener(null);
}
@ -727,7 +763,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
public boolean onContextItemSelected(MenuItem item) {//上下文菜单项被选中
public boolean onContextItemSelected(MenuItem item) {
if (mFocusNoteDataItem == null) {
Log.e(TAG, "The long click data item is null");
return false;
@ -737,7 +773,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
openFolder(mFocusNoteDataItem);
break;
case MENU_FOLDER_DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(this);//弹出对话框
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_folder));
@ -747,11 +783,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
deleteFolder(mFocusNoteDataItem.getId());
}
});
builder.setNegativeButton(android.R.string.cancel, null);//取消
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case MENU_FOLDER_CHANGE_NAME:
showCreateOrModifyFolderDialog(false);//显示创建或修改文件夹对话框
showCreateOrModifyFolderDialog(false);
break;
default:
break;
@ -761,7 +797,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {//准备菜单
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
if (mState == ListEditState.NOTE_LIST) {
getMenuInflater().inflate(R.menu.note_list, menu);
@ -779,19 +815,19 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {//菜单项被选中
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_new_folder: {
showCreateOrModifyFolderDialog(true);
break;
}
case R.id.menu_export_text: {
exportNoteToText();
sendNoteToServer("text/plain");
break;
}
case R.id.menu_sync: {
if (isSyncMode()) {
if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) { // start sync
if (TextUtils.equals(item.getTitle(), getString(R.string.menu_sync))) {
GTaskSyncService.startSync(this);
} else {
GTaskSyncService.cancelSync(this);
@ -801,15 +837,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
break;
}
case R.id.menu_setting: {//设置
case R.id.menu_setting: {
startPreferenceActivity();
break;
}
case R.id.menu_new_note: {//新建便签
case R.id.menu_new_note: {
createNewNote();
break;
}
case R.id.menu_search://搜索
case R.id.menu_search:
onSearchRequested();
break;
default:
@ -819,64 +855,90 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
@Override
public boolean onSearchRequested() {//搜索请求
public boolean onSearchRequested() {
startSearch(null, false, null /* appData */, false);
return true;
}
private void exportNoteToText() {//导出便签到文本
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
new AsyncTask<Void, Void, Integer>() {
private void sendNoteToServer(String noteContent) {
// 创建一个OkHttpClient实例
OkHttpClient client = new OkHttpClient();
// 创建一个RequestBody对象包含要发送的数据
RequestBody requestBody = new FormBody.Builder()
.add("note_content", noteContent)
.build();
// 创建一个Request对象包含请求的URL和请求方式
Request request = new Request.Builder()
.url("http://dustin-z.com/notes")
.post(requestBody)
.build();
// 发送请求并处理响应
client.newCall(request).enqueue(new Callback() {
@Override
protected Integer doInBackground(Void... unused) {
return backup.exportToText();
public void onFailure(Call call, IOException e) {
// 处理请求失败的情况
e.printStackTrace();
// 在UI线程中显示失败提示
runOnUiThread(() -> {
Toast.makeText(NotesListActivity.this, "发送成功", Toast.LENGTH_SHORT).show();
});
}
@Override
protected void onPostExecute(Integer result) {
if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) {//SD卡未挂载
public void onResponse(Call call, Response response) throws IOException {
// 处理响应数据
String responseData = response.body().string();
// 在UI线程中显示响应内容
runOnUiThread(() -> {
Toast.makeText(NotesListActivity.this, responseData, Toast.LENGTH_SHORT).show();
});
}
});
}
private void exportNoteToText() {
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
int result = backup.exportToText();
runOnUiThread(() -> {
if (result == BackupUtils.STATE_SD_CARD_UNMOUONTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this
.getString(R.string.error_sdcard_unmounted));
builder.setTitle(NotesListActivity.this.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(R.string.error_sdcard_unmounted));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
} else if (result == BackupUtils.STATE_SUCCESS) {//成功
} else if (result == BackupUtils.STATE_SUCCESS) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.success_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(
R.string.format_exported_file_location, backup
.getExportedTextFileName(), backup.getExportedTextFileDir()));
builder.setTitle(NotesListActivity.this.getString(R.string.success_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(R.string.format_exported_file_location, backup.getExportedTextFileName(), backup.getExportedTextFileDir()));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
} else if (result == BackupUtils.STATE_SYSTEM_ERROR) {//系统错误
} else if (result == BackupUtils.STATE_SYSTEM_ERROR) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(NotesListActivity.this
.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this
.getString(R.string.error_sdcard_export));
builder.setTitle(NotesListActivity.this.getString(R.string.failed_sdcard_export));
builder.setMessage(NotesListActivity.this.getString(R.string.error_sdcard_export));
builder.setPositiveButton(android.R.string.ok, null);
builder.show();
}
}
}.execute();
});
});
}
private boolean isSyncMode() {//是否同步模式
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
}
private void startPreferenceActivity() {//启动首选项活动
private void startPreferenceActivity() {
Activity from = getParent() != null ? getParent() : this;
Intent intent = new Intent(from, NotesPreferenceActivity.class);
from.startActivityIfNeeded(intent, -1);
}
private class OnListItemClickListener implements OnItemClickListener {//列表项点击监听器
private class OnListItemClickListener implements OnItemClickListener {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (view instanceof NotesListItem) {
@ -890,8 +952,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
return;
}
switch (mState) {//状态
case NOTE_LIST://便签列表
switch (mState) {
case NOTE_LIST:
if (item.getType() == Notes.TYPE_FOLDER
|| item.getType() == Notes.TYPE_SYSTEM) {
openFolder(item);
@ -901,8 +963,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
Log.e(TAG, "Wrong note type in NOTE_LIST");
}
break;
case SUB_FOLDER://子文件夹
case CALL_RECORD_FOLDER://通话记录文件夹
case SUB_FOLDER:
case CALL_RECORD_FOLDER:
if (item.getType() == Notes.TYPE_NOTE) {
openNode(item);
} else {
@ -917,7 +979,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
private void startQueryDestinationFolders() { //开始查询目标文件夹
private void startQueryDestinationFolders() {
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?";
selection = (mState == ListEditState.NOTE_LIST) ? selection:
"(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
@ -935,7 +997,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
NoteColumns.MODIFIED_DATE + " DESC");
}
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {//列表项长按监听器
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if (view instanceof NotesListItem) {
mFocusNoteDataItem = ((NotesListItem) view).getItemData();
if (mFocusNoteDataItem.getType() == Notes.TYPE_NOTE && !mNotesListAdapter.isInChoiceMode()) {

@ -31,19 +31,19 @@ import java.util.HashSet;
import java.util.Iterator;
public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorAdapter 类
public class NotesListAdapter extends CursorAdapter {
private static final String TAG = "NotesListAdapter";
private Context mContext;
private HashMap<Integer, Boolean> mSelectedIndex;
private int mNotesCount;
private boolean mChoiceMode;
public static class AppWidgetAttribute { // 定义了一个静态内部类
public static class AppWidgetAttribute {
public int widgetId;
public int widgetType;
};
public NotesListAdapter(Context context) { // 构造函数
public NotesListAdapter(Context context) {
super(context, null);
mSelectedIndex = new HashMap<Integer, Boolean>();
mContext = context;
@ -51,12 +51,12 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) { // 重写了 CursorAdapter 类的 newView() 方法
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new NotesListItem(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {// 重写了 CursorAdapter 类的 bindView() 方法
public void bindView(View view, Context context, Cursor cursor) {
if (view instanceof NotesListItem) {
NoteItemData itemData = new NoteItemData(context, cursor);
((NotesListItem) view).bind(context, itemData, mChoiceMode,
@ -64,21 +64,21 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
}
}
public void setCheckedItem(final int position, final boolean checked) { // 该方法用于设置选中的条目
public void setCheckedItem(final int position, final boolean checked) {
mSelectedIndex.put(position, checked);
notifyDataSetChanged();
}
public boolean isInChoiceMode() {
return mChoiceMode;
}// 该方法用于判断是否处于多选模式
}
public void setChoiceMode(boolean mode) {// 该方法用于设置多选模式
public void setChoiceMode(boolean mode) {
mSelectedIndex.clear();
mChoiceMode = mode;
}
public void selectAll(boolean checked) {// 该方法用于设置是否全选
public void selectAll(boolean checked) {
Cursor cursor = getCursor();
for (int i = 0; i < getCount(); i++) {
if (cursor.moveToPosition(i)) {
@ -89,7 +89,7 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
}
}
public HashSet<Long> getSelectedItemIds() {// 该方法用于获取选中的条目的 id
public HashSet<Long> getSelectedItemIds() {
HashSet<Long> itemSet = new HashSet<Long>();
for (Integer position : mSelectedIndex.keySet()) {
if (mSelectedIndex.get(position) == true) {
@ -105,7 +105,7 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
return itemSet;
}
public HashSet<AppWidgetAttribute> getSelectedWidget() {// 该方法用于获取选中的条目的 widget
public HashSet<AppWidgetAttribute> getSelectedWidget() {
HashSet<AppWidgetAttribute> itemSet = new HashSet<AppWidgetAttribute>();
for (Integer position : mSelectedIndex.keySet()) {
if (mSelectedIndex.get(position) == true) {
@ -128,12 +128,12 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
return itemSet;
}
public int getSelectedCount() {// 该方法用于获取选中的条目的数量
public int getSelectedCount() {
Collection<Boolean> values = mSelectedIndex.values();
if (null == values) {
return 0;
}
Iterator<Boolean> iter = values.iterator();// 该方法用于获取迭代器
Iterator<Boolean> iter = values.iterator();
int count = 0;
while (iter.hasNext()) {
if (true == iter.next()) {
@ -143,12 +143,12 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
return count;
}
public boolean isAllSelected() {// 该方法用于判断是否全选
public boolean isAllSelected() {
int checkedCount = getSelectedCount();
return (checkedCount != 0 && checkedCount == mNotesCount);
}
public boolean isSelectedItem(final int position) {// 该方法用于判断是否选中
public boolean isSelectedItem(final int position) {
if (null == mSelectedIndex.get(position)) {
return false;
}
@ -156,23 +156,23 @@ public class NotesListAdapter extends CursorAdapter { // 该类扩展了 CursorA
}
@Override
protected void onContentChanged() { // 重写了 CursorAdapter 类的 onContentChanged() 方法
protected void onContentChanged() {
super.onContentChanged();
calcNotesCount();
}
@Override
public void changeCursor(Cursor cursor) {// 重写了 CursorAdapter 类的 changeCursor() 方法
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
calcNotesCount();
}
private void calcNotesCount() { // 该方法用于计算条目的数量
private void calcNotesCount() {
mNotesCount = 0;
for (int i = 0; i < getCount(); i++) {
Cursor c = (Cursor) getItem(i);
if (c != null) {
if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) {// 该方法用于获取条目的类型
if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) {
mNotesCount++;
}
} else {

@ -30,7 +30,7 @@ import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser.NoteItemBgResources;
public class NotesListItem extends LinearLayout { // 继承自 LinearLayout 类
public class NotesListItem extends LinearLayout {
private ImageView mAlert;
private TextView mTitle;
private TextView mTime;
@ -38,7 +38,7 @@ public class NotesListItem extends LinearLayout { // 继承自 LinearLayout 类
private NoteItemData mItemData;
private CheckBox mCheckBox;
public NotesListItem(Context context) { // 构造函数
public NotesListItem(Context context) {
super(context);
inflate(context, R.layout.note_item, this);
mAlert = (ImageView) findViewById(R.id.iv_alert_icon);
@ -48,7 +48,7 @@ public class NotesListItem extends LinearLayout { // 继承自 LinearLayout 类
mCheckBox = (CheckBox) findViewById(android.R.id.checkbox);
}
public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) { // 绑定数据
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,14 +57,14 @@ public class NotesListItem extends LinearLayout { // 继承自 LinearLayout 类
}
mItemData = data;
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { // 如果是通话记录文件夹
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);
@ -75,7 +75,7 @@ public class NotesListItem extends LinearLayout { // 继承自 LinearLayout 类
} else {
mAlert.setVisibility(View.GONE);
}
} else { // 如果是笔记
} else {
mCallName.setVisibility(View.GONE);
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
@ -94,12 +94,13 @@ public class NotesListItem extends LinearLayout { // 继承自 LinearLayout 类
}
}
}
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));// 设置时间
//mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
mTime.setText(DateUtils.formatDateTime(getContext(),data.getModifiedDate(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL));
setBackground(data);
}
private void setBackground(NoteItemData data) {// 设置背景
private void setBackground(NoteItemData data) {
int id = data.getBgColorId();
if (data.getType() == Notes.TYPE_NOTE) {
if (data.isSingle() || data.isOneFollowingFolder()) {

@ -48,21 +48,20 @@ import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.remote.GTaskSyncService;
public class NotesPreferenceActivity extends PreferenceActivity { // implements
public static final String PREFERENCE_NAME = "notes_preferences";// "notes_preferences";
public class NotesPreferenceActivity extends PreferenceActivity {
public static final String PREFERENCE_NAME = "notes_preferences";
public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name";// "pref_key_account_name";
public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name";
public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time";// "pref_last_sync_time";
public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time";
public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear";// "pref_key_bg_random_appear";
public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear";
private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key";// "pref_sync_account_key";
private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key";
private static final String AUTHORITIES_FILTER_KEY = "authorities";// "authorities";
private static final String AUTHORITIES_FILTER_KEY = "authorities";
private PreferenceCategory mAccountCategory;// = (PreferenceCategory)
// findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);
private PreferenceCategory mAccountCategory;
private GTaskReceiver mReceiver;
@ -71,17 +70,17 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
private boolean mHasAddedAccount;
@Override
protected void onCreate(Bundle icicle) { //创建
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* using the app icon for navigation */
getActionBar().setDisplayHomeAsUpEnabled(true);//设置返回键
getActionBar().setDisplayHomeAsUpEnabled(true);
addPreferencesFromResource(R.xml.preferences);
mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);//获取PreferenceCategory
mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);
mReceiver = new GTaskReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME);//添加广播
filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME);
registerReceiver(mReceiver, filter);
mOriAccounts = null;
@ -90,14 +89,14 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
@Override
protected void onResume() {//恢复
protected void onResume() {
super.onResume();
// need to set sync account automatically if user has added a new
// account
if (mHasAddedAccount) {//如果已经添加了账户
if (mHasAddedAccount) {
Account[] accounts = getGoogleAccounts();
if (mOriAccounts != null && accounts.length > mOriAccounts.length) {//如果原来的账户不为空并且账户数大于原来的账户数
if (mOriAccounts != null && accounts.length > mOriAccounts.length) {
for (Account accountNew : accounts) {
boolean found = false;
for (Account accountOld : mOriAccounts) {
@ -118,21 +117,21 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
@Override
protected void onDestroy() {//销毁
protected void onDestroy() {
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
super.onDestroy();
}
private void loadAccountPreference() {//加载账户
private void loadAccountPreference() {
mAccountCategory.removeAll();
Preference accountPref = new Preference(this);
final String defaultAccount = getSyncAccountName(this);
accountPref.setTitle(getString(R.string.preferences_account_title));
accountPref.setSummary(getString(R.string.preferences_account_summary));
accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() { //点击事件
accountPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
if (!GTaskSyncService.isSyncing()) {
if (TextUtils.isEmpty(defaultAccount)) {
@ -152,15 +151,15 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
});
mAccountCategory.addPreference(accountPref); //添加账户
mAccountCategory.addPreference(accountPref);
}
private void loadSyncButton() { //加载同步按钮
private void loadSyncButton() {
Button syncButton = (Button) findViewById(R.id.preference_sync_button);
TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview);
// set button state
if (GTaskSyncService.isSyncing()) {//如果正在同步
if (GTaskSyncService.isSyncing()) {
syncButton.setText(getString(R.string.preferences_button_sync_cancel));
syncButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
@ -168,22 +167,22 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
});
} else {
syncButton.setText(getString(R.string.preferences_button_sync_immediately));//立即同步
syncButton.setText(getString(R.string.preferences_button_sync_immediately));
syncButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
GTaskSyncService.startSync(NotesPreferenceActivity.this);
}
});
}
syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this)));//如果账户名不为空
syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this)));
// set last sync time
if (GTaskSyncService.isSyncing()) {//如果正在同步
if (GTaskSyncService.isSyncing()) {
lastSyncTimeView.setText(GTaskSyncService.getProgressString());
lastSyncTimeView.setVisibility(View.VISIBLE);
} else {
long lastSyncTime = getLastSyncTime(this);
if (lastSyncTime != 0) {//如果最后同步时间不为0
if (lastSyncTime != 0) {
lastSyncTimeView.setText(getString(R.string.preferences_last_sync_time,
DateFormat.format(getString(R.string.preferences_last_sync_time_format),
lastSyncTime)));
@ -194,13 +193,13 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
}
private void refreshUI() {//刷新UI
private void refreshUI() {
loadAccountPreference();
loadSyncButton();
}
private void showSelectAccountAlertDialog() {//显示选择账户对话框
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);//创建对话框
private void showSelectAccountAlertDialog() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null);
TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title);
@ -217,7 +216,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
mOriAccounts = accounts;
mHasAddedAccount = false;
if (accounts.length > 0) { //如果账户数大于0
if (accounts.length > 0) {
CharSequence[] items = new CharSequence[accounts.length];
final CharSequence[] itemMapping = items;
int checkedItem = -1;
@ -228,7 +227,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
items[index++] = account.name;
}
dialogBuilder.setSingleChoiceItems(items, checkedItem, //设置单选按钮
dialogBuilder.setSingleChoiceItems(items, checkedItem,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
setSyncAccount(itemMapping[which].toString());
@ -239,9 +238,9 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null);
dialogBuilder.setView(addAccountView);//设置视图
dialogBuilder.setView(addAccountView);
final AlertDialog dialog = dialogBuilder.show(); //显示对话框
final AlertDialog dialog = dialogBuilder.show();
addAccountView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mHasAddedAccount = true;
@ -255,7 +254,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
});
}
private void showChangeAccountConfirmAlertDialog() { //显示更改账户确认对话框
private void showChangeAccountConfirmAlertDialog() {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null);
@ -271,7 +270,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
getString(R.string.preferences_menu_remove_account),
getString(R.string.preferences_menu_cancel)
};
dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() {//设置列表项
dialogBuilder.setItems(menuItemArray, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
showSelectAccountAlertDialog();
@ -284,12 +283,12 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
dialogBuilder.show();
}
private Account[] getGoogleAccounts() {//获取谷歌账户
private Account[] getGoogleAccounts() {
AccountManager accountManager = AccountManager.get(this);
return accountManager.getAccountsByType("com.google");
}
private void setSyncAccount(String account) {//设置同步账户
private void setSyncAccount(String account) {
if (!getSyncAccountName(this).equals(account)) {
SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
@ -319,7 +318,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
}
private void removeSyncAccount() {//移除同步账户
private void removeSyncAccount() {
SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
if (settings.contains(PREFERENCE_SYNC_ACCOUNT_NAME)) {
@ -331,7 +330,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
editor.commit();
// clean up local gtask related info
new Thread(new Runnable() {//新建线程
new Thread(new Runnable() {
public void run() {
ContentValues values = new ContentValues();
values.put(NoteColumns.GTASK_ID, "");
@ -341,13 +340,13 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}).start();
}
public static String getSyncAccountName(Context context) {//获取同步账户名
public static String getSyncAccountName(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, "");
}
public static void setLastSyncTime(Context context, long time) {//设置最后同步时间
public static void setLastSyncTime(Context context, long time) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
@ -355,13 +354,13 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
editor.commit();
}
public static long getLastSyncTime(Context context) {//获取最后同步时间
public static long getLastSyncTime(Context context) {
SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME,
Context.MODE_PRIVATE);
return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0);
}
private class GTaskReceiver extends BroadcastReceiver {//广播接收器
private class GTaskReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@ -375,7 +374,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { // implements
}
}
public boolean onOptionsItemSelected(MenuItem item) {//选项菜单
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, NotesListActivity.class);

@ -0,0 +1,168 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.SearchView;
import androidx.core.view.MenuItemCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.micode.notes.R;
import net.micode.notes.ui.adapter.MyAdapter;
import net.micode.notes.ui.bean.Note;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class SafeFolderActivity extends Activity {
private RecyclerView mRecyclerView;
private Button mBtnNew;
private List<Note> mNotes;
private MyAdapter mMyAdapter;
private NoteDbOpenHelper mNoteDbOpenHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_safe_folder);
initView();
initData();
initEvent();
}
@Override
protected void onResume() {
super.onResume();
refreshDataFromDb();
}
private void refreshDataFromDb() {
mNotes = getDataFromDB();
mMyAdapter.refreshData(mNotes);
}
private void initEvent() {
mMyAdapter = new MyAdapter(this,mNotes);
mRecyclerView.setAdapter(mMyAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
}
private void initData() {
mNotes = new ArrayList<>();
mNoteDbOpenHelper = new NoteDbOpenHelper(this);
}
private List<Note> getDataFromDB() {
return mNoteDbOpenHelper.queryAllFromDb();
}
private String getCurrentTimeFormat(){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM月dd HH:mm:ss");
Date date = new Date();
return simpleDateFormat.format(date);
}
private void initView(){
mRecyclerView = findViewById(R.id.sf_list);
}
public void NewNotes(View view) {
Intent intent = new Intent(SafeFolderActivity.this,AddActivity.class);
startActivity(intent);
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
//
// getMenuInflater().inflate(R.menu.menu_main, menu);
// SearchView searchView = (SearchView) menu.findItem(R.id.sf_menu_search).getActionView();
//
//
// searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
// @Override
// public boolean onQueryTextSubmit(String query) {
// return false;
// }
//
// @Override
// public boolean onQueryTextChange(String newText) {
// mNotes = mNoteDbOpenHelper.queryFromDbByContent(newText);
// mMyAdapter.refreshData(mNotes);
// return true;
// }
// });
// return super.onCreateOptionsMenu(menu);
// }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.safe, menu);
MenuItem x = menu.findItem(R.id.sf_menu_search);
if (x.getActionView() != null) {
Log.i("-------------","okk");
}else{
Log.i("-------------","false");
}
SearchView searchView = (SearchView) menu.findItem(R.id.sf_menu_search).getActionView();
if (searchView != null) {
Log.i("=====================","okk");
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) {
return false;
}
@Override
public boolean onQueryTextChange(String s) {
mNotes = mNoteDbOpenHelper.queryFromDbByContent(s);
mMyAdapter.refreshData(mNotes);
return true;
}
});
}else{
Log.i("=====================","false");
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
return super.onOptionsItemSelected(item);
}
}

@ -0,0 +1,134 @@
package net.micode.notes.ui.adapter;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.micode.notes.R;
import net.micode.notes.ui.EditActivity;
import net.micode.notes.ui.NoteDbOpenHelper;
import net.micode.notes.ui.NoteEditActivity;
import net.micode.notes.ui.bean.Note;
import net.micode.notes.util.ToastUtil;
import java.util.List;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Note> mBeanList;
private LayoutInflater mLayoutInflater;
private Context mContext;
private NoteDbOpenHelper mNoteDbOpenHelper;
public MyAdapter(Context context,List<Note> mBeanList){
this.mBeanList = mBeanList;
this.mContext = context;
mLayoutInflater = LayoutInflater.from(mContext);
mNoteDbOpenHelper = new NoteDbOpenHelper(mContext);
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.list_item_layout,parent,false);
MyViewHolder myViewHolder= new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, @SuppressLint("RecyclerView") int position) {
Note note = mBeanList.get(position);
holder.mTvContent.setText(note.getContent());
holder.mTvTime.setText(note.getCreatedTime());
holder.rlContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(mContext, EditActivity.class);
intent.putExtra("note",note);
mContext.startActivity(intent);
}
});
holder.rlContainer.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
//长按
Dialog dialog = new Dialog(mContext,android.R.style.Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth);
View view = mLayoutInflater.inflate(R.layout.list_item_dialog_layout, null);
TextView tvDelete = view.findViewById(R.id.tv_delete);
tvDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int row = mNoteDbOpenHelper.deleteFromDbById(note.getId());
if (row > 0){
removeData(position);
ToastUtil.toastShort(mContext,"Delete Success");
}else{
ToastUtil.toastShort(mContext,"Delete Fail");
}
dialog.dismiss();
}
});
dialog.setContentView(view);
dialog.show();
return false;
}
});
}
@Override
public int getItemCount() {
return mBeanList.size();
}
public void refreshData(List<Note> notes){
this.mBeanList = notes;
notifyDataSetChanged();
}
public void removeData(int pos){
mBeanList.remove(pos);
notifyItemRemoved(pos);
}
class MyViewHolder extends RecyclerView.ViewHolder{
TextView mTvContent;
TextView mTvTime;
ViewGroup rlContainer;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
this.mTvContent = itemView.findViewById(R.id.tv_content);
this.mTvTime = itemView.findViewById(R.id.tv_time);
this.rlContainer = itemView.findViewById(R.id.rl_item_container);
}
}
}

@ -0,0 +1,43 @@
package net.micode.notes.ui.bean;
import java.io.Serializable;
public class Note implements Serializable {
private String content;
private String createdTime;
private String id;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getCreatedTime() {
return createdTime;
}
public void setCreatedTime(String createdTime) {
this.createdTime = createdTime;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "Note{" +
"content='" + content + '\'' +
", createdTime='" + createdTime + '\'' +
", id='" + id + '\'' +
'}';
}
}

@ -0,0 +1,98 @@
package net.micode.notes.ui;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.biometric.BiometricPrompt;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.micode.notes.R;
import net.micode.notes.util.ToastUtil;
import java.util.concurrent.Executor;
public class pwdActivity extends FragmentActivity {
//private Executor executor;
public Button mBtnpwd;
public EditText mEtpwd;
public Button mFingerBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pwd);
mBtnpwd = findViewById(R.id.btn_pwd);
mEtpwd = findViewById(R.id.et_1);
mFingerBtn = findViewById(R.id.btn_fingerprint);
mBtnpwd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String pwd = mEtpwd.getText().toString();
Intent intent=null;
if(pwd.equals("123456")){
intent = new Intent(pwdActivity.this,SafeFolderActivity.class);
startActivity(intent);
}else{
ToastUtil.toastShort(pwdActivity.this,String.valueOf(getResources().getString(R.string.pwdwrong)));
}
}
});
mFingerBtn.setOnClickListener(
view->{
BiometricPrompt biometricPrompt;
BiometricPrompt.PromptInfo promptInfo;
Executor executor;
executor = ContextCompat.getMainExecutor(this);
biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
super.onAuthenticationError(errorCode, errString);
Toast.makeText(getApplicationContext(), String.valueOf(getResources().getString(R.string.AuthenticationFailed)) + errString, Toast.LENGTH_SHORT).show();
}
@Override
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
Toast.makeText(getApplicationContext(), String.valueOf(getResources().getString(R.string.AuthenticationSuccess)), Toast.LENGTH_SHORT).show();
// Replace the below code with your code to start the SafeFolderActivity
// if authentication is successful
Intent intent = new Intent(pwdActivity.this, SafeFolderActivity.class);
startActivity(intent);
}
@Override
public void onAuthenticationFailed() {
super.onAuthenticationFailed();
Toast.makeText(getApplicationContext(), String.valueOf(getResources().getString(R.string.AuthenticationFailed)), Toast.LENGTH_SHORT).show();
}
});
promptInfo = new BiometricPrompt.PromptInfo.Builder()
.setTitle(String.valueOf(getResources().getString(R.string.BioAuth)))
.setSubtitle(String.valueOf(getResources().getString(R.string.LogUseBio)))
.setNegativeButtonText(String.valueOf(getResources().getString(R.string.datetime_dialog_cancel)))
.build();
biometricPrompt.authenticate(promptInfo);
}
);
}
}

@ -0,0 +1,38 @@
package net.micode.notes.util;
import android.content.Context;
import android.content.SharedPreferences;
public class SpfUtil {
private static String SPF_NAME = "noteSpf";
public static void saveString(Context context, String key, String value) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = spf.edit();
edit.putString(key, value);
edit.apply();
}
public static String getString(Context context, String key) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
return spf.getString(key, "");
}
public static void saveInt(Context context, String key, int value) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = spf.edit();
edit.putInt(key, value);
edit.apply();
}
public static int getInt(Context context, String key) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
return spf.getInt(key, -1);
}
public static int getIntWithDefault(Context context, String key, int defValue) {
SharedPreferences spf = context.getSharedPreferences(SPF_NAME, Context.MODE_PRIVATE);
return spf.getInt(key, defValue);
}
}

@ -0,0 +1,15 @@
package net.micode.notes.util;
import android.content.Context;
import android.widget.Toast;
public class ToastUtil {
public static void toastShort(Context context, String msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
public static void toastLong(Context context, String msg) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.AddActivity">
<EditText
android:id="@+id/sf_et_1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/edit_yellow"
android:gravity="top"
android:padding="10dp"
android:maxLength="300"
android:layout_weight="1"
android:textColor="#070707"/>
<Button
android:id="@+id/sf_btn_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:textSize="25sp"
android:text="Add"
android:onClick="add"
/>
</LinearLayout>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.EditActivity">
<EditText
android:id="@+id/sf_et_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/edit_yellow"
android:gravity="top"
android:padding="10dp"
android:maxLength="300"
android:layout_weight="1"
android:textColor="#070707"/>
<Button
android:id="@+id/sf_btn_add2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:textSize="25sp"
android:text="Save"
android:onClick="save"
/>
</LinearLayout>

@ -0,0 +1,43 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
android:background="@drawable/list_background"
android:gravity="center|center_horizontal|center_vertical"
tools:context=".ui.pwdActivity">
<EditText
android:id="@+id/et_1"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:hint="@string/inputPassword"
android:inputType="textPassword"
android:maxLines="1"
android:padding="10dp"/>
<View
android:layout_width="match_parent"
android:layout_height="20dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_pwd"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="@string/open"/>
<View
android:layout_width="match_parent"
android:layout_height="20dp"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_fingerprint"
android:layout_width="200dp"
android:layout_height="50dp"
android:text="@string/finger"/>
</LinearLayout>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".ui.SafeFolderActivity"
android:background="@drawable/list_background">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sf_list"
android:layout_width="match_parent"
android:layout_height="500dp" />
<Button
android:id="@+id/sf_btn_new_note"
android:background="@drawable/new_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="false"
android:layout_gravity="bottom"
android:onClick="NewNotes"
/>
</FrameLayout>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
>
<TextView
android:id="@+id/tv_delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text_font_size_large"
android:textColor="#000000"
android:text="Delete"
android:gravity="center_horizontal"/>
</LinearLayout>

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/rl_item_container"
android:padding="25dp"
android:background="@drawable/list_yellow_down"
>
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="0dp"
android:layout_toLeftOf="@id/tv_time"
android:ellipsize="end"
android:gravity="left"
android:maxLines="1"
android:text="你好"
android:textSize="20sp"
android:textStyle="bold" />
<!-- <TextView-->
<!-- android:id="@+id/tv_content"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_below="@id/tv_title"-->
<!-- android:layout_marginTop="5dp"-->
<!-- android:ellipsize="end"-->
<!-- android:maxLines="2"-->
<!-- android:text="你好拉拉拉拉谁在用琵琶弹奏一曲东风破"-->
<!-- android:textSize="16sp" />-->
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/tv_content"
android:layout_alignParentRight="true"
android:gravity="center"
android:text="2021-5-30 22:40:34"
android:textSize="14sp" />
</RelativeLayout>

@ -26,6 +26,8 @@
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title_bar"
android:layout_width="fill_parent"
@ -34,9 +36,19 @@
android:visibility="gone"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="#FFEAD1AE"
android:textColor="#EC125C"
android:textSize="@dimen/text_font_size_medium" />
<Button
android:id="@+id/btn_sf"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/safeFolder"
android:background="@drawable/list_folder"
/>
<ListView
android:id="@+id/notes_list"
android:layout_width="fill_parent"
@ -55,4 +67,12 @@
android:layout_height="wrap_content"
android:focusable="false"
android:layout_gravity="bottom" />
<Button
android:id="@+id/btn_show_menu"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="bottom|right"
android:focusable="true"
android:focusableInTouchMode="true"
android:background="@android:drawable/ic_menu_sort_by_size" />
</FrameLayout>

@ -19,5 +19,6 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/menu_search"
android:title="@string/menu_search" />
android:title="@string/menu_search"
/>
</menu>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item
android:id="@+id/sf_menu_search"
android:title="搜索"
app:showAsAction="always"
android:icon="@drawable/ic_baseline_search_24"
app:actionViewClass="androidx.appcompat.widget.SearchView$SearchAutoComplete" />
</menu>

@ -119,6 +119,15 @@
<string name="search">便签</string>
<string name="datetime_dialog_ok">设置</string>
<string name="datetime_dialog_cancel">取消</string>
<string name="safeFolder">保险文件夹</string>
<string name="open">确定</string>
<string name="inputPassword">请输入密码</string>
<string name="finger">使用指纹打开</string>
<string name="AuthenticationFailed">认证失败</string>
<string name="AuthenticationSuccess">认证成功</string>
<string name="pwdwrong">密码错误</string>
<string name="LogUseBio">使用生物信息认证</string>
<string name="BioAuth">生物认证</string>
<plurals name="search_results_title">
<item quantity="other"><xliff:g id="NUMBER">%1$s</xliff:g> 条符合“<xliff:g id="SEARCH">%2$s</xliff:g>”的搜索结果</item>
</plurals>

@ -15,8 +15,7 @@
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<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>
@ -126,10 +125,19 @@
<string name="search">Notes</string>
<string name="datetime_dialog_ok">set</string>
<string name="datetime_dialog_cancel">cancel</string>
<string name="safeFolder">Safe Folder</string>
<string name="open">Open</string>
<string name="inputPassword">Input Password</string>
<string name="finger">Use Biometric</string>
<string name="AuthenticationFailed">Authentication Failed</string>
<string name="AuthenticationSuccess">Authentication Success</string>
<string name="pwdwrong">Password Wrong</string>
<string name="LogUseBio">Login using your biometric credential</string>
<string name="BioAuth">Biometric Authentication</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>
<item quantity="one"><xliff:g example="1" id="number">%1$s</xliff:g> result for \"<xliff:g example="???" id="search">%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>
<item quantity="other"><xliff:g example="15" id="number">%1$s</xliff:g> results for \"<xliff:g example="???" id="search">%2$s</xliff:g>\"</item>
</plurals>
</resources>

Loading…
Cancel
Save