# Conflicts:
#	src/notes/ui/NoteEditActivity.java
#	src/notes/ui/NotesListActivity.java
#	src/notes/ui/NotesPreferenceActivity.java
功能合并提交
pull/8/head
s2_cc 4 weeks ago
commit aceefdb2e3

@ -26,6 +26,8 @@ import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
@ -210,8 +212,12 @@ public class NotesProvider extends ContentProvider {
try {
searchString = String.format("%%%s%%", searchString);
c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY,
Cursor rawCursor = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY,
new String[] { searchString });
// 包装Cursor以处理HTML内容
if (rawCursor != null) {
c = new HtmlCursorWrapper(rawCursor);
}
} catch (IllegalStateException ex) {
Log.e(TAG, "got exception: " + ex.toString());
}
@ -225,6 +231,240 @@ public class NotesProvider extends ContentProvider {
return c;
}
/**
* CursorHTML
* HTML
*/
private class HtmlCursorWrapper implements Cursor {
private Cursor mCursor;
public HtmlCursorWrapper(Cursor cursor) {
mCursor = cursor;
}
@Override
public int getCount() {
return mCursor.getCount();
}
@Override
public int getPosition() {
return mCursor.getPosition();
}
@Override
public boolean move(int offset) {
return mCursor.move(offset);
}
@Override
public boolean moveToPosition(int position) {
return mCursor.moveToPosition(position);
}
@Override
public boolean moveToFirst() {
return mCursor.moveToFirst();
}
@Override
public boolean moveToLast() {
return mCursor.moveToLast();
}
@Override
public boolean moveToNext() {
return mCursor.moveToNext();
}
@Override
public boolean moveToPrevious() {
return mCursor.moveToPrevious();
}
@Override
public boolean isFirst() {
return mCursor.isFirst();
}
@Override
public boolean isLast() {
return mCursor.isLast();
}
@Override
public boolean isBeforeFirst() {
return mCursor.isBeforeFirst();
}
@Override
public boolean isAfterLast() {
return mCursor.isAfterLast();
}
@Override
public int getColumnIndex(String columnName) {
return mCursor.getColumnIndex(columnName);
}
@Override
public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {
return mCursor.getColumnIndexOrThrow(columnName);
}
@Override
public String getColumnName(int columnIndex) {
return mCursor.getColumnName(columnIndex);
}
@Override
public String[] getColumnNames() {
return mCursor.getColumnNames();
}
@Override
public int getColumnCount() {
return mCursor.getColumnCount();
}
@Override
public byte[] getBlob(int columnIndex) {
return mCursor.getBlob(columnIndex);
}
@Override
public String getString(int columnIndex) {
String value = mCursor.getString(columnIndex);
// 处理搜索结果中的HTML内容
if (value != null && (
columnIndex == mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1) ||
columnIndex == mCursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2))
) {
// 将HTML转换为普通文本
return Html.fromHtml(value).toString();
}
return value;
}
@Override
public short getShort(int columnIndex) {
return mCursor.getShort(columnIndex);
}
@Override
public int getInt(int columnIndex) {
return mCursor.getInt(columnIndex);
}
@Override
public long getLong(int columnIndex) {
return mCursor.getLong(columnIndex);
}
@Override
public float getFloat(int columnIndex) {
return mCursor.getFloat(columnIndex);
}
@Override
public double getDouble(int columnIndex) {
return mCursor.getDouble(columnIndex);
}
@Override
public int getType(int columnIndex) {
return mCursor.getType(columnIndex);
}
@Override
public boolean isNull(int columnIndex) {
return mCursor.isNull(columnIndex);
}
@Override
public void deactivate() {
mCursor.deactivate();
}
@Override
public boolean requery() {
return mCursor.requery();
}
@Override
public void close() {
mCursor.close();
}
@Override
public boolean isClosed() {
return mCursor.isClosed();
}
@Override
public void registerContentObserver(android.database.ContentObserver observer) {
mCursor.registerContentObserver(observer);
}
@Override
public void unregisterContentObserver(android.database.ContentObserver observer) {
mCursor.unregisterContentObserver(observer);
}
@Override
public void registerDataSetObserver(android.database.DataSetObserver observer) {
mCursor.registerDataSetObserver(observer);
}
@Override
public void unregisterDataSetObserver(android.database.DataSetObserver observer) {
mCursor.unregisterDataSetObserver(observer);
}
@Override
public void setNotificationUri(android.content.ContentResolver cr, Uri uri) {
mCursor.setNotificationUri(cr, uri);
}
@Override
public Uri getNotificationUri() {
return mCursor.getNotificationUri();
}
@Override
public boolean getWantsAllOnMoveCalls() {
return mCursor.getWantsAllOnMoveCalls();
}
@Override
public void setExtras(Bundle extras) {
mCursor.setExtras(extras);
}
@Override
public Bundle getExtras() {
return mCursor.getExtras();
}
@Override
public Bundle respond(Bundle extras) {
return mCursor.respond(extras);
}
@Override
public void copyStringToBuffer(int columnIndex, android.database.CharArrayBuffer buffer) {
String value = getString(columnIndex);
if (value != null) {
char[] data = value.toCharArray();
if (buffer.data == null || buffer.data.length < data.length) {
buffer.data = new char[data.length];
}
System.arraycopy(data, 0, buffer.data, 0, data.length);
buffer.sizeCopied = data.length;
}
}
}
/**
*
* @param uri URI

@ -34,12 +34,18 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.InputType;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -469,7 +475,10 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent()); // 切换到列表模式
} else {
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
// 加载富文本内容
String content = mWorkingNote.getContent();
CharSequence htmlContent = Html.fromHtml(content != null ? content : "");
mNoteEditor.setText(getHighlightQueryResult(htmlContent, mUserQuery));
mNoteEditor.setSelection(mNoteEditor.getText().length()); // 光标移到最后
}
@ -841,6 +850,18 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
case R.id.menu_delete_remind:
mWorkingNote.setAlertDate(0, false); // 删除提醒
break;
case R.id.menu_bold:
applyRichTextStyle(android.graphics.Typeface.BOLD);
break;
case R.id.menu_italic:
applyRichTextStyle(android.graphics.Typeface.ITALIC);
break;
case R.id.menu_underline:
applyUnderlineStyle();
break;
case R.id.menu_strikethrough:
applyStrikethroughStyle();
break;
default:
break;
}
@ -1045,9 +1066,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
/**
* Spannable
*/
private Spannable getHighlightQueryResult(String fullText, String userQuery) {
private Spannable getHighlightQueryResult(CharSequence fullText, String userQuery) {
SpannableString spannable = new SpannableString(fullText == null ? "" : fullText);
if (!TextUtils.isEmpty(userQuery)) {
if (!TextUtils.isEmpty(userQuery) && !TextUtils.isEmpty(fullText)) {
mPattern = Pattern.compile(userQuery);
Matcher m = mPattern.matcher(fullText);
int start = 0;
@ -1099,7 +1120,8 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
// 设置编辑文本变化监听器
edit.setOnTextViewChangeListener(this);
edit.setIndex(index); // 设置索引
edit.setText(getHighlightQueryResult(item, mUserQuery)); // 设置文本(支持高亮)
// 列表模式下不使用富文本,直接设置文本
edit.setText(item); // 设置文本
return view;
}
@ -1153,17 +1175,22 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
if (!TextUtils.isEmpty(edit.getText())) {
// 根据复选框状态添加不同的标记
if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) {
sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
sb.append(TAG_CHECKED).append(" " ).append(edit.getText()).append("\n" );
hasChecked = true;
} else {
sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
sb.append(TAG_UNCHECKED).append(" " ).append(edit.getText()).append("\n" );
}
}
}
mWorkingNote.setWorkingText(sb.toString());
} else {
// 普通模式:直接获取编辑框文本
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
// 普通模式将富文本转换为HTML格式保存
if (mNoteEditor.getText() instanceof Spanned) {
String htmlContent = Html.toHtml((Spanned) mNoteEditor.getText());
mWorkingNote.setWorkingText(htmlContent);
} else {
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
}
}
return hasChecked;
}
@ -1185,6 +1212,152 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
return saved;
}
/**
*
*/
private void applyRichTextStyle(int style) {
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
// 列表模式下,获取当前焦点的编辑框
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
NoteEditText editText = (NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text);
if (editText.hasFocus()) {
applyStyleToEditText(editText, style);
break;
}
}
} else {
// 普通模式下,直接应用到主编辑框
applyStyleToEditText(mNoteEditor, style);
}
}
/**
* 线
*/
private void applyUnderlineStyle() {
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
// 列表模式下,获取当前焦点的编辑框
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
NoteEditText editText = (NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text);
if (editText.hasFocus()) {
applyUnderlineToEditText(editText);
break;
}
}
} else {
// 普通模式下,直接应用到主编辑框
applyUnderlineToEditText(mNoteEditor);
}
}
/**
* 线
*/
private void applyStrikethroughStyle() {
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
// 列表模式下,获取当前焦点的编辑框
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
NoteEditText editText = (NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text);
if (editText.hasFocus()) {
applyStrikethroughToEditText(editText);
break;
}
}
} else {
// 普通模式下,直接应用到主编辑框
applyStrikethroughToEditText(mNoteEditor);
}
}
/**
* EditText
*/
private void applyStyleToEditText(EditText editText, int style) {
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
if (start != end) {
SpannableString spannable = new SpannableString(editText.getText());
StyleSpan[] existingSpans = spannable.getSpans(start, end, StyleSpan.class);
// 检查是否已经应用了相同的样式
boolean hasStyle = false;
for (StyleSpan span : existingSpans) {
if (span.getStyle() == style) {
hasStyle = true;
break;
}
}
if (hasStyle) {
// 如果已经应用了相同的样式,则移除
for (StyleSpan span : existingSpans) {
if (span.getStyle() == style) {
spannable.removeSpan(span);
}
}
} else {
// 如果没有应用相同的样式,则添加
spannable.setSpan(new StyleSpan(style), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
editText.setText(spannable);
editText.setSelection(end);
}
}
/**
* EditText线
*/
private void applyUnderlineToEditText(EditText editText) {
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
if (start != end) {
SpannableString spannable = new SpannableString(editText.getText());
UnderlineSpan[] existingSpans = spannable.getSpans(start, end, UnderlineSpan.class);
if (existingSpans.length > 0) {
// 如果已经应用了下划线,则移除
for (UnderlineSpan span : existingSpans) {
spannable.removeSpan(span);
}
} else {
// 如果没有应用下划线,则添加
spannable.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
editText.setText(spannable);
editText.setSelection(end);
}
}
/**
* EditText线
*/
private void applyStrikethroughToEditText(EditText editText) {
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
if (start != end) {
SpannableString spannable = new SpannableString(editText.getText());
StrikethroughSpan[] existingSpans = spannable.getSpans(start, end, StrikethroughSpan.class);
if (existingSpans.length > 0) {
// 如果已经应用了删除线,则移除
for (StrikethroughSpan span : existingSpans) {
spannable.removeSpan(span);
}
} else {
// 如果没有应用删除线,则添加
spannable.setSpan(new StrikethroughSpan(), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
}
editText.setText(spannable);
editText.setSelection(end);
}
}
/**
*
*/

@ -18,6 +18,7 @@ package net.micode.notes.ui;
import android.content.Context;
import android.database.Cursor;
import android.text.Html;
import android.text.TextUtils;
import net.micode.notes.data.Contact;
@ -105,6 +106,10 @@ public class NoteItemData {
mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN);
mParentId = cursor.getLong(PARENT_ID_COLUMN);
mSnippet = cursor.getString(SNIPPET_COLUMN);
// 将HTML格式转换为普通文本解决富文本编辑后显示乱码的问题
if (!TextUtils.isEmpty(mSnippet)) {
mSnippet = Html.fromHtml(mSnippet).toString();
}
// 移除摘要中的复选框标记(已勾选和未勾选)
mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED, "").replace(
NoteEditActivity.TAG_UNCHECKED, "");

@ -23,11 +23,16 @@ import android.appwidget.AppWidgetManager;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.text.InputType;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -97,6 +102,8 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
private static final int MENU_FOLDER_CHANGE_NAME = 2; // 文件夹改名菜单项
private static final int MENU_LOCK_NOTE = 3; // 便签加锁菜单项
private static final int MENU_UNLOCK_NOTE = 4; // 便签解锁菜单项
private static final int MENU_FOLDER_ENCRYPT = 3; // 文件夹加密菜单项
private static final int MENU_FOLDER_DECRYPT = 4; // 文件夹取消加密菜单项
// 首次使用引导标记的偏好设置键
private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction";
@ -143,11 +150,12 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
// 普通查询条件(非根文件夹)
private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?";
// 根文件夹查询条件(包含通话记录文件夹
// 根文件夹查询条件(包含通话记录文件夹和回收站
private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>"
+ Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR ("
+ Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?) OR ("
+ NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND "
+ NoteColumns.NOTES_COUNT + ">0)";
+ NoteColumns.NOTES_COUNT + ">0) OR ("
+ NoteColumns.ID + "=" + Notes.ID_TRASH_FOLDER + ")";
// 请求码常量
private final static int REQUEST_CODE_OPEN_NODE = 102; // 打开笔记请求码
@ -161,6 +169,58 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
// 首次使用时插入应用介绍笔记
setAppInfoFromRawRes();
// 清理一周前的回收站笔记
cleanOldTrashNotes();
}
/**
*
*/
private void cleanOldTrashNotes() {
long oneWeekAgo = System.currentTimeMillis() - (7 * 24 * 60 * 60 * 1000);
String selection = NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLDER + " AND "
+ NoteColumns.MODIFIED_DATE + "<" + oneWeekAgo;
try {
int deletedCount = getContentResolver().delete(Notes.CONTENT_NOTE_URI, selection, null);
if (deletedCount > 0) {
Log.d(TAG, "Cleaned " + deletedCount + " old trash notes");
}
} catch (Exception e) {
Log.e(TAG, "Error cleaning old trash notes", e);
}
}
/**
*
* @param itemData
*/
private void restoreNote(final NoteItemData itemData) {
if (itemData == null || itemData.getType() != Notes.TYPE_NOTE) {
return;
}
// 显示确认对话框
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("恢复笔记");
builder.setMessage("确定要恢复这条笔记吗?");
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 恢复笔记到根文件夹
HashSet<Long> ids = new HashSet<Long>();
ids.add(itemData.getId());
if (DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_ROOT_FOLDER)) {
Toast.makeText(NotesListActivity.this, "笔记已恢复", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(NotesListActivity.this, "恢复失败", Toast.LENGTH_SHORT).show();
}
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
@Override
@ -276,6 +336,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
// 加载操作模式菜单
getMenuInflater().inflate(R.menu.note_list_options, menu);
menu.findItem(R.id.delete).setOnMenuItemClickListener(this);
menu.findItem(R.id.pin).setOnMenuItemClickListener(this);
mMoveMenu = menu.findItem(R.id.move);
// 根据条件设置移动菜单可见性
if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER
@ -397,6 +458,10 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case R.id.pin:
// 批量置顶笔记
batchPinNotes();
break;
case R.id.move:
// 批量移动到文件夹
startQueryDestinationFolders();
@ -564,19 +629,54 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
protected HashSet<AppWidgetAttribute> doInBackground(Void... unused) {
// 获取选中笔记的小部件属性
HashSet<AppWidgetAttribute> widgets = mNotesListAdapter.getSelectedWidget();
if (!isSyncMode()) {
// 非同步模式下直接删除笔记
if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter
.getSelectedItemIds())) {
// 删除成功
} else {
Log.e(TAG, "Delete notes error, should not happens");
// 无论是否同步模式,都将笔记移动到回收站
if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter
.getSelectedItemIds(), Notes.ID_TRASH_FOLDER)) {
Log.e(TAG, "Move notes to trash folder error, should not happens");
}
return widgets;
}
@Override
protected void onPostExecute(HashSet<AppWidgetAttribute> widgets) {
// 更新相关小部件
if (widgets != null) {
for (AppWidgetAttribute widget : widgets) {
if (widget.widgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& widget.widgetType != Notes.TYPE_WIDGET_INVALIDE) {
updateWidget(widget.widgetId, widget.widgetType);
}
}
} else {
// 同步模式下将笔记移动到回收站
if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter
.getSelectedItemIds(), Notes.ID_TRASH_FOLDER)) {
Log.e(TAG, "Move notes to trash folder error, should not happens");
}
mModeCallBack.finishActionMode(); // 结束多选模式
}
}.execute();
}
/**
*
*/
private void batchPinNotes() {
new AsyncTask<Void, Void, HashSet<AppWidgetAttribute>>() {
@Override
protected HashSet<AppWidgetAttribute> doInBackground(Void... unused) {
// 获取选中笔记的小部件属性
HashSet<AppWidgetAttribute> widgets = mNotesListAdapter.getSelectedWidget();
HashSet<Long> selectedIds = mNotesListAdapter.getSelectedItemIds();
// 批量更新笔记的alerted_date字段为一个很大的值表示置顶
for (Long noteId : selectedIds) {
ContentValues values = new ContentValues();
values.put(NoteColumns.ALERTED_DATE, 9999999999999L); // 很大的值,表示置顶
values.put(NoteColumns.LOCAL_MODIFIED, 1);
values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis());
try {
getContentResolver().update(
ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId),
values, null, null);
} catch (Exception e) {
Log.e(TAG, "Error pinning note: " + noteId, e);
}
}
return widgets;
@ -593,6 +693,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
}
}
Toast.makeText(NotesListActivity.this, "已置顶" + mNotesListAdapter.getSelectedCount() + "条笔记", Toast.LENGTH_SHORT).show();
mModeCallBack.finishActionMode(); // 结束多选模式
}
}.execute();
@ -629,6 +730,8 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
}
}
/**
*
@ -644,18 +747,30 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
*
*/
private void openFolder(NoteItemData data) {
// 检查文件夹是否加密
if (data.getType() == Notes.TYPE_FOLDER && isFolderEncrypted(data.getId())) {
// 加密文件夹需要输入密码才能进入
showFolderPasswordDialog(data.getId());
return;
}
mCurrentFolderId = data.getId();
startAsyncNotesListQuery(); // 查询文件夹内容
// 根据文件夹类型设置状态
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mState = ListEditState.CALL_RECORD_FOLDER;
mAddNewNote.setVisibility(View.GONE); // 通话记录文件夹不能新建笔记
} else if (data.getId() == Notes.ID_TRASH_FOLDER) {
mState = ListEditState.SUB_FOLDER;
mAddNewNote.setVisibility(View.GONE); // 回收站不能新建笔记
} else {
mState = ListEditState.SUB_FOLDER;
}
// 设置标题栏
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mTitleBar.setText(R.string.call_record_folder_name);
} else if (data.getId() == Notes.ID_TRASH_FOLDER) {
mTitleBar.setText("回收站");
} else {
mTitleBar.setText(data.getSnippet());
}
@ -842,6 +957,12 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
menu.add(0, MENU_FOLDER_VIEW, 0, R.string.menu_folder_view);
menu.add(0, MENU_FOLDER_DELETE, 0, R.string.menu_folder_delete);
menu.add(0, MENU_FOLDER_CHANGE_NAME, 0, R.string.menu_folder_change_name);
// 添加加密选项
if (isFolderEncrypted(mFocusNoteDataItem.getId())) {
menu.add(0, MENU_FOLDER_DECRYPT, 0, "取消加密");
} else {
menu.add(0, MENU_FOLDER_ENCRYPT, 0, "加密文件夹");
}
}
}
};
@ -901,6 +1022,14 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
case MENU_FOLDER_CHANGE_NAME:
showCreateOrModifyFolderDialog(false); // 显示修改文件夹名对话框
break;
case MENU_FOLDER_ENCRYPT:
// 加密文件夹
showEncryptFolderDialog(mFocusNoteDataItem.getId());
break;
case MENU_FOLDER_DECRYPT:
// 取消加密文件夹
decryptFolder(mFocusNoteDataItem.getId());
break;
case MENU_LOCK_NOTE:
handleLockNote(); // 加锁便签
break;
@ -1057,11 +1186,21 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
break;
case SUB_FOLDER:
// 检查是否是回收站中的笔记
if (item.getType() == Notes.TYPE_NOTE && mCurrentFolderId == Notes.ID_TRASH_FOLDER) {
// 回收站中的笔记点击时显示恢复选项
restoreNote(item);
} else if (item.getType() == Notes.TYPE_NOTE) {
openNode(item); // 打开笔记
} else {
Log.e(TAG, "Wrong note type in SUB_FOLDER");
}
break;
case CALL_RECORD_FOLDER:
if (item.getType() == Notes.TYPE_NOTE) {
openNode(item); // 打开笔记
} else {
Log.e(TAG, "Wrong note type in SUB_FOLDER");
Log.e(TAG, "Wrong note type in CALL_RECORD_FOLDER");
}
break;
default:
@ -1262,4 +1401,280 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
return false;
}
/**
*
* @param folderId ID
* @return
*/
private boolean isFolderEncrypted(long folderId) {
SharedPreferences preferences = getSharedPreferences("notes_prefs", Context.MODE_PRIVATE);
String password = preferences.getString("folder_" + folderId + "_password", "");
return !password.isEmpty();
}
/**
*
* @param folderId ID
*/
private void showEncryptFolderDialog(final long folderId) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("加密文件夹");
builder.setIcon(android.R.drawable.ic_lock_idle_lock);
// 创建密码输入框
final EditText passwordInput = new EditText(this);
passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordInput.setHint("请设置密码");
builder.setView(passwordInput);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String password = passwordInput.getText().toString();
if (!password.isEmpty()) {
// 保存密码
SharedPreferences preferences = getSharedPreferences("notes_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("folder_" + folderId + "_password", password);
editor.apply();
// 显示提示
Toast.makeText(NotesListActivity.this, "文件夹已加密", Toast.LENGTH_SHORT).show();
} else {
// 密码为空,显示提示
Toast.makeText(NotesListActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 添加忘记密码按钮
builder.setNeutralButton("忘记密码", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 显示通过密保问题重置密码的对话框
showResetPasswordWithSecurityQuestionsDialog(folderId);
}
});
// 显示对话框
builder.show();
}
/**
*
* @param folderId ID
*/
private void decryptFolder(final long folderId) {
// 显示密码输入对话框,验证身份
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("取消加密");
builder.setIcon(android.R.drawable.ic_lock_idle_lock);
// 创建密码输入框
final EditText passwordInput = new EditText(this);
passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordInput.setHint("请输入密码");
builder.setView(passwordInput);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String password = passwordInput.getText().toString();
if (checkFolderPassword(folderId, password)) {
// 密码正确,取消加密
SharedPreferences preferences = getSharedPreferences("notes_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.remove("folder_" + folderId + "_password");
editor.apply();
// 显示提示
Toast.makeText(NotesListActivity.this, "文件夹已取消加密", Toast.LENGTH_SHORT).show();
} else {
// 密码错误,显示提示
Toast.makeText(NotesListActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 添加忘记密码按钮
builder.setNeutralButton("忘记密码", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 显示通过密保问题重置密码的对话框
showResetPasswordWithSecurityQuestionsDialog(folderId);
}
});
// 显示对话框
builder.show();
}
/**
*
* @param folderId ID
* @param password
* @return
*/
private boolean checkFolderPassword(long folderId, String password) {
SharedPreferences preferences = getSharedPreferences("notes_prefs", Context.MODE_PRIVATE);
String savedPassword = preferences.getString("folder_" + folderId + "_password", "");
return savedPassword.equals(password);
}
/**
*
* @param folderId ID
*/
private void enterEncryptedFolder(long folderId) {
mCurrentFolderId = folderId;
startAsyncNotesListQuery(); // 查询文件夹内容
mState = ListEditState.SUB_FOLDER;
}
/**
*
* @param folderId ID
*/
private void showFolderPasswordDialog(final long folderId) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("输入密码");
builder.setIcon(android.R.drawable.ic_lock_idle_lock);
// 创建密码输入框
final EditText passwordInput = new EditText(this);
passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordInput.setHint("请输入文件夹密码");
builder.setView(passwordInput);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String password = passwordInput.getText().toString();
if (checkFolderPassword(folderId, password)) {
// 密码正确,进入文件夹
enterEncryptedFolder(folderId);
} else {
// 密码错误,显示提示
Toast.makeText(NotesListActivity.this, "密码错误,请重新输入", Toast.LENGTH_SHORT).show();
// 重新显示密码输入对话框
showFolderPasswordDialog(folderId);
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 显示对话框
builder.show();
}
/**
*
* @param folderId ID
*/
private void showResetPasswordWithSecurityQuestionsDialog(final long folderId) {
// 检查是否设置了密保问题
if (!NotesPreferenceActivity.hasSecurityQuestionsSet(this)) {
Toast.makeText(this, "请先在设置中设置密保问题", Toast.LENGTH_SHORT).show();
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("忘记密码");
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage("请回答密保问题以重置密码");
// 创建布局
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(40, 20, 40, 20);
// 创建姓名输入框
final EditText nameInput = new EditText(this);
nameInput.setHint("请输入姓名");
layout.addView(nameInput);
// 创建生日输入框
final EditText birthdayInput = new EditText(this);
birthdayInput.setHint("请输入生日 (YYYY-MM-DD)");
layout.addView(birthdayInput);
builder.setView(layout);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = nameInput.getText().toString();
String birthday = birthdayInput.getText().toString();
if (NotesPreferenceActivity.verifySecurityQuestions(NotesListActivity.this, name, birthday)) {
// 验证成功,显示设置新密码的对话框
showSetNewFolderPasswordDialog(folderId);
} else {
// 验证失败,显示提示
Toast.makeText(NotesListActivity.this, "密保问题回答错误", Toast.LENGTH_SHORT).show();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 显示对话框
builder.show();
}
/**
*
* @param folderId ID
*/
private void showSetNewFolderPasswordDialog(final long folderId) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("设置新密码");
builder.setIcon(android.R.drawable.ic_dialog_info);
// 创建密码输入框
final EditText passwordInput = new EditText(this);
passwordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
passwordInput.setHint("请输入新密码");
builder.setView(passwordInput);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String newPassword = passwordInput.getText().toString();
if (!newPassword.isEmpty()) {
// 保存新密码
SharedPreferences preferences = getSharedPreferences("notes_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("folder_" + folderId + "_password", newPassword);
editor.apply();
// 显示提示
Toast.makeText(NotesListActivity.this, "密码重置成功", Toast.LENGTH_SHORT).show();
} else {
// 密码为空,显示提示
Toast.makeText(NotesListActivity.this, "密码不能为空", Toast.LENGTH_SHORT).show();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 显示对话框
builder.show();
}
}

@ -98,6 +98,16 @@ public class NotesListItem extends LinearLayout {
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.getId() == Notes.ID_TRASH_FOLDER) {
// 回收站文件夹的特殊显示
mCallName.setVisibility(View.GONE);
mAlert.setVisibility(View.VISIBLE);
mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); // 设置主标题样式
// 显示回收站名称和包含的笔记数量
mTitle.setText("回收站"
+ context.getString(R.string.format_folder_files_count, data.getNotesCount()));
// 设置回收站图标(使用系统默认图标)
mAlert.setImageResource(android.R.drawable.ic_delete);
} else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) {
// 通话记录笔记的显示
mCallName.setVisibility(View.VISIBLE);
@ -135,8 +145,13 @@ public class NotesListItem extends LinearLayout {
}
}
// 显示相对时间(如"2小时前"
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
// 显示相对时间(如"2小时前"- 回收站中的笔记和回收站文件夹本身都不显示时间
if (data.getParentId() != Notes.ID_TRASH_FOLDER && data.getId() != Notes.ID_TRASH_FOLDER) {
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
mTime.setVisibility(View.VISIBLE);
} else {
mTime.setVisibility(View.GONE);
}
// 根据数据类型和位置设置背景
setBackground(data);
@ -151,8 +166,9 @@ public class NotesListItem extends LinearLayout {
*/
private void setBackground(NoteItemData data) {
int id = data.getBgColorId(); // 获取背景颜色ID
if (data.getType() == Notes.TYPE_NOTE) {
// 笔记类型的背景设置
// 普通笔记类型的背景设置
if (data.isSingle() || data.isOneFollowingFolder()) {
// 单一条目或紧跟在文件夹后的单个笔记:使用单个笔记背景
setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id));
@ -170,6 +186,13 @@ public class NotesListItem extends LinearLayout {
// 文件夹类型:使用文件夹背景
setBackgroundResource(NoteItemBgResources.getFolderBgRes());
}
// 回收站中的笔记使用半透明效果,与普通笔记区分
if (data.getType() == Notes.TYPE_NOTE && data.getParentId() == Notes.ID_TRASH_FOLDER) {
setAlpha(0.6f); // 设置透明度为60%
} else {
setAlpha(1.0f); // 普通笔记使用完全不透明
}
}
/**

@ -29,7 +29,10 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import net.micode.notes.R;
@ -47,7 +50,21 @@ public class NotesPreferenceActivity extends PreferenceActivity {
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
/* 使用应用图标作为导航按钮 */
getActionBar().setDisplayHomeAsUpEnabled(true);
// 检查并设置密保问题(只在首次设置时显示)
if (!hasSecurityQuestionsSet()) {
showSetSecurityQuestionsDialog();
}
// 从XML文件加载偏好设置
addPreferencesFromResource(R.xml.preferences);
mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY);
mReceiver = new GTaskReceiver(); // 创建广播接收器
IntentFilter filter = new IntentFilter();
filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); // 注册同步服务广播
registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); // 注册广播接收器
MaterialToolbar toolbar = (MaterialToolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
@ -107,6 +124,183 @@ public class NotesPreferenceActivity extends PreferenceActivity {
});
}
}
/**
*
* @return
*/
private boolean hasSecurityQuestionsSet() {
SharedPreferences preferences = getSharedPreferences(PREFERENCE_NAME, MODE_PRIVATE);
String name = preferences.getString("security_question_name", "");
String birthday = preferences.getString("security_question_birthday", "");
return !name.isEmpty() && !birthday.isEmpty();
}
/**
*
*/
private void showSetSecurityQuestionsDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("设置密保问题");
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setMessage("请设置您的个人信息作为密保,用于重置密码时验证身份");
// 创建布局
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(40, 20, 40, 20);
// 创建姓名输入框
final EditText nameInput = new EditText(this);
nameInput.setHint("请输入姓名");
layout.addView(nameInput);
// 创建生日输入框
final EditText birthdayInput = new EditText(this);
birthdayInput.setHint("请输入生日 (YYYY-MM-DD)");
layout.addView(birthdayInput);
builder.setView(layout);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = nameInput.getText().toString();
String birthday = birthdayInput.getText().toString();
if (!name.isEmpty() && !birthday.isEmpty()) {
// 保存密保信息
SharedPreferences preferences = getSharedPreferences(PREFERENCE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("security_question_name", name);
editor.putString("security_question_birthday", birthday);
editor.apply();
// 显示提示
Toast.makeText(NotesPreferenceActivity.this, "密保设置成功", Toast.LENGTH_SHORT).show();
} else {
// 信息为空,显示提示
Toast.makeText(NotesPreferenceActivity.this, "请完整填写个人信息", Toast.LENGTH_SHORT).show();
// 重新显示对话框
showSetSecurityQuestionsDialog();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 如果用户取消,退出设置界面
finish();
}
});
// 设置对话框不可取消
builder.setCancelable(false);
// 显示对话框
builder.show();
}
/**
*
*/
private void showVerifySecurityQuestionsDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("验证身份");
builder.setIcon(android.R.drawable.ic_lock_idle_lock);
builder.setMessage("请回答您的密保问题以验证身份");
// 创建布局
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(40, 20, 40, 20);
// 创建姓名输入框
final EditText nameInput = new EditText(this);
nameInput.setHint("请输入姓名");
layout.addView(nameInput);
// 创建生日输入框
final EditText birthdayInput = new EditText(this);
birthdayInput.setHint("请输入生日 (YYYY-MM-DD)");
layout.addView(birthdayInput);
builder.setView(layout);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = nameInput.getText().toString();
String birthday = birthdayInput.getText().toString();
if (verifySecurityQuestions(name, birthday)) {
// 验证成功,允许进入设置
Toast.makeText(NotesPreferenceActivity.this, "验证成功", Toast.LENGTH_SHORT).show();
} else {
// 验证失败,显示提示
Toast.makeText(NotesPreferenceActivity.this, "验证失败,请重新输入", Toast.LENGTH_SHORT).show();
// 重新显示验证对话框
showVerifySecurityQuestionsDialog();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 如果用户取消,退出设置界面
finish();
}
});
// 设置对话框不可取消
builder.setCancelable(false);
// 显示对话框
builder.show();
}
/**
*
* @param name
* @param birthday
* @return
*/
private boolean verifySecurityQuestions(String name, String birthday) {
SharedPreferences preferences = getSharedPreferences(PREFERENCE_NAME, MODE_PRIVATE);
String savedName = preferences.getString("security_question_name", "");
String savedBirthday = preferences.getString("security_question_birthday", "");
return savedName.equals(name) && savedBirthday.equals(birthday);
}
/**
*
* @param context
* @param name
* @param birthday
* @return
*/
public static boolean verifySecurityQuestions(Context context, String name, String birthday) {
SharedPreferences preferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
String savedName = preferences.getString("security_question_name", "");
String savedBirthday = preferences.getString("security_question_birthday", "");
return savedName.equals(name) && savedBirthday.equals(birthday);
}
/**
*
* @param context
* @return
*/
public static boolean hasSecurityQuestionsSet(Context context) {
SharedPreferences preferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
String name = preferences.getString("security_question_name", "");
String birthday = preferences.getString("security_question_birthday", "");
return !name.isEmpty() && !birthday.isEmpty();
}
private void showUserCenterDialog() {
final boolean isLoggedIn = AccountManager.isUserLoggedIn(this);
@ -144,6 +338,129 @@ public class NotesPreferenceActivity extends PreferenceActivity {
}
});
builder.show();
// 添加修改密保问题的选项
Preference securityPref = new Preference(this);
securityPref.setTitle("修改密保问题");
securityPref.setSummary("修改用于重置密码的个人信息");
securityPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// 验证当前密保才能修改
showVerifySecurityQuestionsForModificationDialog();
return true;
}
});
mAccountCategory.addPreference(accountPref); // 添加到设置类别
mAccountCategory.addPreference(securityPref); // 添加密保设置选项
}
/**
*
*/
private void showChangeSecurityQuestionsDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("修改密保问题");
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setMessage("请重新设置您的个人信息作为密保");
// 创建布局
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(40, 20, 40, 20);
// 创建姓名输入框
final EditText nameInput = new EditText(this);
nameInput.setHint("请输入姓名");
layout.addView(nameInput);
// 创建生日输入框
final EditText birthdayInput = new EditText(this);
birthdayInput.setHint("请输入生日 (YYYY-MM-DD)");
layout.addView(birthdayInput);
builder.setView(layout);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = nameInput.getText().toString();
String birthday = birthdayInput.getText().toString();
if (!name.isEmpty() && !birthday.isEmpty()) {
// 保存新的密保信息
SharedPreferences preferences = getSharedPreferences(PREFERENCE_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("security_question_name", name);
editor.putString("security_question_birthday", birthday);
editor.apply();
// 显示提示
Toast.makeText(NotesPreferenceActivity.this, "密保修改成功", Toast.LENGTH_SHORT).show();
} else {
// 信息为空,显示提示
Toast.makeText(NotesPreferenceActivity.this, "请完整填写个人信息", Toast.LENGTH_SHORT).show();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 显示对话框
builder.show();
}
/**
*
*/
private void showVerifySecurityQuestionsForModificationDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("验证身份");
builder.setIcon(android.R.drawable.ic_lock_idle_lock);
builder.setMessage("请回答您的密保问题以验证身份,验证成功后才能修改密保");
// 创建布局
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setPadding(40, 20, 40, 20);
// 创建姓名输入框
final EditText nameInput = new EditText(this);
nameInput.setHint("请输入姓名");
layout.addView(nameInput);
// 创建生日输入框
final EditText birthdayInput = new EditText(this);
birthdayInput.setHint("请输入生日 (YYYY-MM-DD)");
layout.addView(birthdayInput);
builder.setView(layout);
// 设置确定按钮
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = nameInput.getText().toString();
String birthday = birthdayInput.getText().toString();
if (verifySecurityQuestions(name, birthday)) {
// 验证成功,显示修改密保对话框
Toast.makeText(NotesPreferenceActivity.this, "验证成功", Toast.LENGTH_SHORT).show();
showChangeSecurityQuestionsDialog();
} else {
// 验证失败,显示提示
Toast.makeText(NotesPreferenceActivity.this, "验证失败,请重新输入", Toast.LENGTH_SHORT).show();
// 重新显示验证对话框
showVerifySecurityQuestionsForModificationDialog();
}
}
});
// 设置取消按钮
builder.setNegativeButton("取消", null);
// 显示对话框
builder.show();
}
private void handleLogout() {

Loading…
Cancel
Save