update #4

Merged
p4vbyojna merged 1 commits from Enid into master 3 years ago

@ -31,8 +31,8 @@ import net.micode.notes.data.Notes.NoteColumns;
public class AlarmInitReceiver extends BroadcastReceiver {
private static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.ALERTED_DATE
NoteColumns.ID,
NoteColumns.ALERTED_DATE
};
private static final int COLUMN_ID = 0;

@ -160,7 +160,7 @@ public class DateTimePicker extends FrameLayout {
public interface OnDateTimeChangedListener {
void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute);
int dayOfMonth, int hourOfDay, int minute);
}
public DateTimePicker(Context context) {
@ -263,7 +263,7 @@ public class DateTimePicker extends FrameLayout {
* @param minute The current minute
*/
public void setCurrentDate(int year, int month,
int dayOfMonth, int hourOfDay, int minute) {
int dayOfMonth, int hourOfDay, int minute) {
setCurrentYear(year);
setCurrentMonth(month);
setCurrentDay(dayOfMonth);

@ -46,7 +46,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
setView(mDateTimePicker);
mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
public void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute) {
int dayOfMonth, int hourOfDay, int minute) {
mDate.set(Calendar.YEAR, year);
mDate.set(Calendar.MONTH, month);
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
@ -74,9 +74,9 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener
private void updateTitle(long date) {
int flag =
DateUtils.FORMAT_SHOW_YEAR |
DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_SHOW_TIME;
DateUtils.FORMAT_SHOW_YEAR |
DateUtils.FORMAT_SHOW_DATE |
DateUtils.FORMAT_SHOW_TIME;
flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR;
setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
}

@ -31,8 +31,8 @@ import net.micode.notes.data.Notes.NoteColumns;
public class FoldersListAdapter extends CursorAdapter {
public static final String [] PROJECTION = {
NoteColumns.ID,
NoteColumns.SNIPPET
NoteColumns.ID,
NoteColumns.SNIPPET
};
public static final int ID_COLUMN = 0;

@ -27,18 +27,14 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Paint;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -56,6 +52,8 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.TextNote;
@ -76,7 +74,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NoteEditActivity extends Activity implements OnClickListener,
public class NoteEditActivity extends AppCompatActivity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
private class HeadViewHolder {
public TextView tvModified;
@ -86,6 +84,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public TextView tvAlertDate;
public ImageView ibSetBgColor;
public ImageView ivLocked;
public ImageView ivUnlocked;
}
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
@ -153,8 +155,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
private static final int PHOTO_REQUEST = 2;// 从相册中选择
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -317,6 +317,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE);
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE);
};
if(mWorkingNote.getIsLocked()){
mNoteHeaderHolder.ivUnlocked.setVisibility(View.GONE);
mNoteHeaderHolder.ivLocked.setVisibility(View.VISIBLE);
}else{
mNoteHeaderHolder.ivUnlocked.setVisibility(View.VISIBLE);
mNoteHeaderHolder.ivLocked.setVisibility(View.GONE);
}
}
@Override
@ -365,8 +373,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight())) {
return false;
}
return false;
}
return true;
}
@ -378,6 +386,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date);
mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color);
mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);
mNoteHeaderHolder.ivLocked = (ImageView) findViewById(R.id.tv_locked);
mNoteHeaderHolder.ivUnlocked = (ImageView) findViewById(R.id.tv_unlocked);
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
@ -425,7 +437,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
mWorkingNote.getWidgetId()
mWorkingNote.getWidgetId()
});
sendBroadcast(intent);
@ -459,6 +471,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
public void onChangeLock(View v){
int id = v.getId();
switch (id){
case R.id.tv_locked:
mWorkingNote.setLock(false);
break;
case R.id.tv_unlocked:
mWorkingNote.setLock(true);
break;
}
showAlertHeader();
}
@Override
public void onBackPressed() {
if(clearSettingState()) {
@ -487,8 +513,34 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu){
// if (isFinishing()) {
// return true;
// }
// clearSettingState();
// menu.clear();
// if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) {
// getMenuInflater().inflate(R.menu.call_note_edit, menu);
// } else {
// getMenuInflater().inflate(R.menu.note_edit, menu);
// }
// if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
// menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_normal_mode);
// } else {
// menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode);
// }
// if (mWorkingNote.hasClockAlert()) {
// menu.findItem(R.id.menu_alert).setVisible(false);
// } else {
// menu.findItem(R.id.menu_delete_remind).setVisible(false);
// }
// return true;
// }
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
// getMenuInflater().inflate(R.menu.call_note_edit, menu);
if (isFinishing()) {
return true;
}
@ -512,7 +564,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
@ -595,6 +646,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private void deleteCurrentNote() {
saveNote();
if (mWorkingNote.existInDatabase()) {
HashSet<Long> ids = new HashSet<Long>();
long id = mWorkingNote.getNoteId();
@ -604,9 +656,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Log.d(TAG, "Wrong note id, should not happen");
}
if (!isSyncMode()) {
if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
Log.e(TAG, "Delete Note error");
}
// if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) {
// Log.e(TAG, "Delete Note error");
// }
} else {
if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) {
Log.e(TAG, "Move notes to trash folder error, should not happens");
@ -617,7 +669,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
return true;
}
public void onClockAlertChanged(long date, boolean set) {
@ -880,47 +932,4 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
//路径字符串格式 转换为 图片image格式
private void convertToImage() {
NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view); //获取当前的edit
Editable editable = noteEditText.getText();//1.获取text
String noteText = editable.toString(); //2.将note内容转换为字符串
int length = editable.length(); //内容的长度
//3.截取img片段 [local]+uri+[local]提取uri
for(int i = 0; i < length; i++) {
for(int j = i; j < length; j++) {
String img_fragment = noteText.substring(i, j+1); //img_fragment关于图片路径的片段
if(img_fragment.length() > 15 && img_fragment.endsWith("[/local]") && img_fragment.startsWith("[local]")){
int limit = 7; //[local]为7个字符
//[local][/local]共15个字符剩下的为真正的path长度
int len = img_fragment.length()-15;
//从[local]之后的len个字符就是path
String path = img_fragment.substring(limit,limit+len);//获取到了图片路径
Bitmap bitmap = null;
Log.d(TAG, "图片的路径是:"+path);
try {
bitmap = BitmapFactory.decodeFile(path);//将图片路径解码为图片格式
} catch (Exception e) {
e.printStackTrace();
}
if(bitmap!=null){ //若图片存在
Log.d(TAG, "图片不为null");
ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
//4.创建一个SpannableString对象以便插入用ImageSpan对象封装的图像
String ss = "[local]" + path + "[/local]";
SpannableString spannableString = new SpannableString(ss);
//5.将指定的标记对象附加到文本的开始...结束范围
spannableString.setSpan(imageSpan, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Log.d(TAG, "Create spannable string success!");
Editable edit_text = noteEditText.getEditableText();
edit_text.delete(i,i+len+15); //6.删掉图片路径的文字
edit_text.insert(i, spannableString); //7.在路径的起始位置插入图片
}
}
}
}
}
}

@ -28,18 +28,19 @@ import net.micode.notes.tool.DataUtils;
public class NoteItemData {
static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE,
NoteColumns.HAS_ATTACHMENT,
NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT,
NoteColumns.PARENT_ID,
NoteColumns.SNIPPET,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE,
NoteColumns.HAS_ATTACHMENT,
NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT,
NoteColumns.PARENT_ID,
NoteColumns.SNIPPET,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
NoteColumns.LOCKED
};
private static final int ID_COLUMN = 0;
@ -54,6 +55,10 @@ public class NoteItemData {
private static final int TYPE_COLUMN = 9;
private static final int WIDGET_ID_COLUMN = 10;
private static final int WIDGET_TYPE_COLUMN = 11;
private static final int LOCKED_COLUMN = 12;
private static final String LOCKED = "locked";
private static final String UNLOCKED = "unlocked";
private long mId;
private long mAlertDate;
@ -76,6 +81,8 @@ public class NoteItemData {
private boolean mIsOneNoteFollowingFolder;
private boolean mIsMultiNotesFollowingFolder;
private boolean mIsLocked;
public NoteItemData(Context context, Cursor cursor) {
mId = cursor.getLong(ID_COLUMN);
mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN);
@ -92,6 +99,8 @@ public class NoteItemData {
mWidgetId = cursor.getInt(WIDGET_ID_COLUMN);
mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN);
mIsLocked = !cursor.getString(LOCKED_COLUMN).equals(UNLOCKED);
mPhoneNumber = "";
if (mParentId == Notes.ID_CALL_RECORD_FOLDER) {
mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId);
@ -221,4 +230,11 @@ public class NoteItemData {
public static int getNoteType(Cursor cursor) {
return cursor.getInt(TYPE_COLUMN);
}
public boolean getIsLocked(){
return mIsLocked;
}
public void setIsLocked(boolean islocked){
mIsLocked = islocked;
}
}

@ -16,9 +16,11 @@
package net.micode.notes.ui;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.KeyguardManager;
import android.appwidget.AppWidgetManager;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
@ -28,10 +30,13 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.hardware.fingerprint.FingerprintManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import androidx.appcompat.app.AppCompatActivity;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyProperties;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@ -61,6 +66,8 @@ import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
@ -68,6 +75,7 @@ import net.micode.notes.gtask.remote.GTaskSyncService;
import net.micode.notes.model.WorkingNote;
import net.micode.notes.tool.BackupUtils;
import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.FingerprintDialogFragment;
import net.micode.notes.tool.ResourceParser;
import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import net.micode.notes.widget.NoteWidgetProvider_2x;
@ -77,8 +85,13 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.util.HashSet;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class NotesListActivity extends AppCompatActivity implements OnClickListener, OnItemLongClickListener {
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
@ -90,11 +103,13 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
private static final int MENU_FOLDER_CHANGE_NAME = 2;
private static final int MENU_FOLDER_MOVE_OUT = 3;
private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction";
private enum ListEditState {
NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER
}
};
private ListEditState mState;
@ -136,11 +151,25 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
private final static int REQUEST_CODE_OPEN_NODE = 102;
private final static int REQUEST_CODE_NEW_NODE = 103;
private static final String DEFAULT_KEY_NAME = "default_key";
private static final int OPEN_NOTE = 0;
private static final int DELETE_NOTE = 1;
private static final int MOVE_NOTE = 2;
private static final int NONE_ACTION = -1;
KeyStore keyStore;
private NoteItemData mNoteDataItem;
private int mAuthenticatedType;
private long mAuthenticated_FOLDER;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
initResources();
if (supportFingerprint()) {
initKey();
}
/**
* Insert an introduction when user firstly use this application
@ -161,46 +190,56 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
private void setAppInfoFromRawRes() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) {
StringBuilder sb = new StringBuilder();
InputStream in = null;
try {
in = getResources().openRawResource(R.raw.introduction);
if (in != null) {
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
char [] buf = new char[1024];
int len = 0;
while ((len = br.read(buf)) > 0) {
sb.append(buf, 0, len);
}
} else {
Log.e(TAG, "Read introduction file error");
return;
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER,
AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE,
ResourceParser.RED);
note.setWorkingText(sb.toString());
if (note.saveNote()) {
sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit();
} else {
Log.e(TAG, "Save introduction note error");
if(!DataUtils.checkFolderId(mContentResolver,Long.valueOf(Notes.ID_TRASH_FOLER)) && !DataUtils.checkVisibleFolderName(mContentResolver,this.getString(R.string.trash_name))){
ContentValues values = new ContentValues();
values.put(NoteColumns.SNIPPET, this.getString(R.string.trash_name));
values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER);
// values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER);
mContentResolver.insert(Notes.CONTENT_NOTE_URI, values);
}
// StringBuilder sb = new StringBuilder();
// InputStream in = null;
// try {
// in = getResources().openRawResource(R.raw.introduction);
// if (in != null) {
// InputStreamReader isr = new InputStreamReader(in);
// BufferedReader br = new BufferedReader(isr);
// char [] buf = new char[1024];
// int len = 0;
// while ((len = br.read(buf)) > 0) {
// sb.append(buf, 0, len);
// }
// } else {
// Log.e(TAG, "Read introduction file error");
// return;
// }
// } catch (IOException e) {
// e.printStackTrace();
// return;
// } finally {
// if(in != null) {
// try {
// in.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// }
//
// WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER,
// AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE,
// ResourceParser.RED);
// note.setWorkingText(sb.toString());
// if (note.saveNote()) {
// sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit();
// } else {
// Log.e(TAG, "Save introduction note error");
// return;
// }
}
long id = DataUtils.getTrashIdByName(mContentResolver,this.getString(R.string.trash_name));
Notes.setID_TRASH_FOLER((int)id);
}
@Override
@ -307,7 +346,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
boolean checked) {
mNotesListAdapter.setCheckedItem(position, checked);
updateMenu();
}
@ -325,14 +364,14 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
mNotesListAdapter.getSelectedCount()));
mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
batchDelete();
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
@ -413,7 +452,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
: NORMAL_SELECTION;
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
String.valueOf(mCurrentFolderId)
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
@ -441,6 +480,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
}
private void showFolderListMenu(Cursor cursor) {
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
builder.setTitle(R.string.menu_title_select_folder);
@ -448,14 +488,27 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
DataUtils.batchMoveToFolder(mContentResolver,
mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which));
Toast.makeText(
NotesListActivity.this,
getString(R.string.format_move_notes_to_folder,
mNotesListAdapter.getSelectedCount(),
adapter.getFolderName(NotesListActivity.this, which)),
Toast.LENGTH_SHORT).show();
if(adapter.getItemId(which)==Notes.ID_TRASH_FOLER){
Toast.makeText(
NotesListActivity.this,
R.string.forbidden_move_to_trash,
Toast.LENGTH_SHORT).show();
}else{
if(mNotesListAdapter.getHasLocked() && false){
//not ready
initCipher();
mAuthenticatedType = MOVE_NOTE;
}else {
DataUtils.batchMoveToFolder(mContentResolver,
mNotesListAdapter.getSelectedItemIds(), adapter.getItemId(which));
Toast.makeText(
NotesListActivity.this,
getString(R.string.format_move_notes_to_folder,
mNotesListAdapter.getSelectedCount(),
adapter.getFolderName(NotesListActivity.this, which)),
Toast.LENGTH_SHORT).show();
}
}
mModeCallBack.finishActionMode();
}
});
@ -469,11 +522,12 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE);
}
private void batchDelete() {
private void reallyBatchDelete(){
new AsyncTask<Void, Void, HashSet<AppWidgetAttribute>>() {
protected HashSet<AppWidgetAttribute> doInBackground(Void... unused) {
HashSet<AppWidgetAttribute> widgets = mNotesListAdapter.getSelectedWidget();
if (!isSyncMode()) {
HashSet<Long> folers = mNotesListAdapter.getSelectedFolderIds();
if (folers.contains(new Long( Notes.ID_TRASH_FOLER))) {
// if not synced, delete notes directly
if (DataUtils.batchDeleteNotes(mContentResolver, mNotesListAdapter
.getSelectedItemIds())) {
@ -506,17 +560,22 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}.execute();
}
private void deleteFolder(long folderId) {
if (folderId == Notes.ID_ROOT_FOLDER) {
Log.e(TAG, "Wrong folder id, should not happen " + folderId);
return;
private void batchDelete() {
if(ifHaveLocked()){
initCipher();
mAuthenticatedType = DELETE_NOTE;
}else {
reallyBatchDelete();
}
}
private void reallyDeleteFolder(long folderId){
HashSet<Long> ids = new HashSet<Long>();
ids.add(folderId);
HashSet<AppWidgetAttribute> widgets = DataUtils.getFolderNoteWidget(mContentResolver,
folderId);
if (!isSyncMode()) {
if (DataUtils.getParentIdbyId(mContentResolver,folderId)==Notes.ID_TRASH_FOLER) {
// if not synced, delete folder directly
DataUtils.batchDeleteNotes(mContentResolver, ids);
} else {
@ -533,34 +592,129 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
}
private void deleteFolder(long folderId) {
if (folderId == Notes.ID_ROOT_FOLDER) {
Log.e(TAG, "Wrong folder id, should not happen " + folderId);
return;
}
if(folderId == Notes.ID_TRASH_FOLER){
Toast.makeText(
NotesListActivity.this,
R.string.forbidden_delete_trash,
Toast.LENGTH_SHORT).show();
return;
}
if(DataUtils.getHasLockedByFolderId(mContentResolver,folderId).contains(Notes.LOCKED)){
initCipher();
mAuthenticatedType = MOVE_NOTE;
mAuthenticated_FOLDER = folderId;
}else {
reallyDeleteFolder(folderId);
}
}
private boolean ifHaveLocked(){
return mNotesListAdapter.getHasLocked();
}
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);
if(!data.getIsLocked()){
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);
}else{
this.openLockedNote();
mNoteDataItem = data;
mAuthenticatedType = OPEN_NOTE;
}
}
private void openFolder(NoteItemData data) {
mCurrentFolderId = data.getId();
startAsyncNotesListQuery();
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mState = ListEditState.CALL_RECORD_FOLDER;
mAddNewNote.setVisibility(View.GONE);
} else {
mState = ListEditState.SUB_FOLDER;
private void openLockedNote(){
initCipher();
}
public void onAuthenticated() {
switch (mAuthenticatedType){
case OPEN_NOTE:
switch (mNoteDataItem.getType()){
case Notes.TYPE_FOLDER:
mCurrentFolderId = mNoteDataItem.getId();
startAsyncNotesListQuery();
if (mNoteDataItem.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mState = ListEditState.CALL_RECORD_FOLDER;
mAddNewNote.setVisibility(View.GONE);
} else {
mState = ListEditState.SUB_FOLDER;
}
if (mNoteDataItem.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mTitleBar.setText(R.string.call_record_folder_name);
} else {
mTitleBar.setText(mNoteDataItem.getSnippet());
}
mTitleBar.setVisibility(View.VISIBLE);
break;
case Notes.TYPE_NOTE:
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.putExtra(Intent.EXTRA_UID, mNoteDataItem.getId());
this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
break;
}
break;
case DELETE_NOTE:
reallyBatchDelete();
break;
case MOVE_NOTE:
reallyDeleteFolder(mAuthenticated_FOLDER);
break;
}
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mTitleBar.setText(R.string.call_record_folder_name);
} else {
mTitleBar.setText(data.getSnippet());
mNoteDataItem = null;
mAuthenticated_FOLDER = -1;
mAuthenticatedType = NONE_ACTION;
}
public void onStopAuthenticated() {
mNoteDataItem = null;
}
private void openFolder(NoteItemData data) {
if(!data.getIsLocked()){
mCurrentFolderId = data.getId();
startAsyncNotesListQuery();
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mState = ListEditState.CALL_RECORD_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 {
mTitleBar.setText(data.getSnippet());
}
mTitleBar.setVisibility(View.VISIBLE);
}else{
this.openLockedNote();
mNoteDataItem = data;
mAuthenticatedType = OPEN_NOTE;
}
mTitleBar.setVisibility(View.VISIBLE);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_new_note:
createNewNote();
if(mCurrentFolderId==Notes.ID_TRASH_FOLER){
Toast.makeText(
NotesListActivity.this,
R.string.forbidden_add_in_trash,
Toast.LENGTH_SHORT).show();
}else {
createNewNote();
}
break;
default:
break;
@ -586,8 +740,13 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
showSoftInput();
if (!create) {
if (mFocusNoteDataItem != null) {
etName.setText(mFocusNoteDataItem.getSnippet());
builder.setTitle(getString(R.string.menu_folder_change_name));
if(mFocusNoteDataItem.getId()==(long)Notes.ID_TRASH_FOLER){
Toast.makeText(this, R.string.forbidden_change_trash_name, Toast.LENGTH_SHORT).show();
return;
}else{
etName.setText(mFocusNoteDataItem.getSnippet());
builder.setTitle(getString(R.string.menu_folder_change_name));
}
} else {
Log.e(TAG, "The long click data item is null");
return;
@ -624,7 +783,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
values.put(NoteColumns.LOCAL_MODIFIED, 1);
mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID
+ "=?", new String[] {
String.valueOf(mFocusNoteDataItem.getId())
String.valueOf(mFocusNoteDataItem.getId())
});
}
} else if (!TextUtils.isEmpty(name)) {
@ -700,7 +859,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
appWidgetId
appWidgetId
});
sendBroadcast(intent);
@ -710,10 +869,16 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if (mFocusNoteDataItem != null) {
menu.setHeaderTitle(mFocusNoteDataItem.getSnippet());
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(mFocusNoteDataItem.getParentId()==Notes.ID_TRASH_FOLER){
menu.setHeaderTitle(mFocusNoteDataItem.getSnippet());
menu.add(0, MENU_FOLDER_MOVE_OUT, 0, R.string.menu_folder_move_out);
menu.add(0, MENU_FOLDER_DELETE, 0, R.string.menu_folder_delete);
}else {
menu.setHeaderTitle(mFocusNoteDataItem.getSnippet());
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);
}
}
}
};
@ -732,31 +897,56 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
Log.e(TAG, "The long click data item is null");
return false;
}
switch (item.getItemId()) {
case MENU_FOLDER_VIEW:
openFolder(mFocusNoteDataItem);
break;
case MENU_FOLDER_DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_folder));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteFolder(mFocusNoteDataItem.getId());
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case MENU_FOLDER_CHANGE_NAME:
showCreateOrModifyFolderDialog(false);
break;
default:
break;
if(mFocusNoteDataItem.getParentId()==Notes.ID_TRASH_FOLER){
switch (item.getItemId()) {
case MENU_FOLDER_MOVE_OUT:
HashSet<Long> ids = new HashSet<Long>();
ids.add(mFocusNoteDataItem.getId());
DataUtils.batchMoveToFolder(mContentResolver, ids, Notes.ID_ROOT_FOLDER);
break;
case MENU_FOLDER_DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_folder));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteFolder(mFocusNoteDataItem.getId());
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
default:
break;
}
}else {
switch (item.getItemId()) {
case MENU_FOLDER_VIEW:
openFolder(mFocusNoteDataItem);
break;
case MENU_FOLDER_DELETE:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_folder));
builder.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
deleteFolder(mFocusNoteDataItem.getId());
}
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
case MENU_FOLDER_CHANGE_NAME:
showCreateOrModifyFolderDialog(false);
break;
default:
break;
}
}
return true;
}
@ -806,7 +996,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
break;
}
case R.id.menu_new_note: {
createNewNote();
// createNewNote();
break;
}
case R.id.menu_search:
@ -867,7 +1057,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
private boolean isSyncMode() {
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
return true;
}
private void startPreferenceActivity() {
@ -918,9 +1108,9 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
private void startQueryDestinationFolders() {
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?";
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>? AND "+ NoteColumns.ID + "<>?";
selection = (mState == ListEditState.NOTE_LIST) ? selection:
"(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
"(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
mBackgroundQueryHandler.startQuery(FOLDER_LIST_QUERY_TOKEN,
null,
@ -930,7 +1120,8 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
new String[] {
String.valueOf(Notes.TYPE_FOLDER),
String.valueOf(Notes.ID_TRASH_FOLER),
String.valueOf(mCurrentFolderId)
String.valueOf(mCurrentFolderId),
String.valueOf(Notes.ID_TRASH_FOLER)
},
NoteColumns.MODIFIED_DATE + " DESC");
}
@ -951,4 +1142,68 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
}
return false;
}
public boolean supportFingerprint() {
if (Build.VERSION.SDK_INT < 23) {
Toast.makeText(this, "您的系统版本过低,不支持指纹功能", Toast.LENGTH_SHORT).show();
return false;
} else {
KeyguardManager keyguardManager = getSystemService(KeyguardManager.class);
FingerprintManager fingerprintManager = getSystemService(FingerprintManager.class);
if (!fingerprintManager.isHardwareDetected()) {
Toast.makeText(this, "您的手机不支持指纹功能", Toast.LENGTH_SHORT).show();
return false;
} else if (!keyguardManager.isKeyguardSecure()) {
Toast.makeText(this, "您还未设置锁屏,请先设置锁屏并添加一个指纹", Toast.LENGTH_SHORT).show();
return false;
} else if (!fingerprintManager.hasEnrolledFingerprints()) {
Toast.makeText(this, "您至少需要在系统设置中添加一个指纹", Toast.LENGTH_SHORT).show();
return false;
}
}
return true;
}
@TargetApi(23)
private void initKey() {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(DEFAULT_KEY_NAME,
KeyProperties.PURPOSE_ENCRYPT |
KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationRequired(true)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
keyGenerator.init(builder.build());
keyGenerator.generateKey();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@TargetApi(23)
private void initCipher() {
try {
SecretKey key = (SecretKey) keyStore.getKey(DEFAULT_KEY_NAME, null);
Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+ KeyProperties.BLOCK_MODE_CBC + "/"
+ KeyProperties.ENCRYPTION_PADDING_PKCS7);
cipher.init(Cipher.ENCRYPT_MODE, key);
showFingerPrintDialog(cipher);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void showFingerPrintDialog(Cipher cipher) {
FingerprintDialogFragment fragment = new FingerprintDialogFragment();
fragment.setCipher(cipher);
fragment.show(getFragmentManager(), "fingerprint");
}
}

@ -99,12 +99,33 @@ public class NotesListAdapter extends CursorAdapter {
} else {
itemSet.add(id);
}
}
}
return itemSet;
}
public HashSet<Long> getSelectedFolderIds() {
HashSet<Long> itemSet = new HashSet<Long>();
for (Integer position : mSelectedIndex.keySet()) {
if (mSelectedIndex.get(position) == true) {
Cursor c = (Cursor) getItem(position);
if (c != null) {
NoteItemData item = new NoteItemData(mContext, c);
itemSet.add(item.getFolderId());
/**
* Don't close cursor here, only the adapter could close it
*/
} else {
Log.e(TAG, "Invalid cursor");
return null;
}
}
}
return itemSet;
}
public HashSet<AppWidgetAttribute> getSelectedWidget() {
HashSet<AppWidgetAttribute> itemSet = new HashSet<AppWidgetAttribute>();
for (Integer position : mSelectedIndex.keySet()) {
@ -128,6 +149,28 @@ public class NotesListAdapter extends CursorAdapter {
return itemSet;
}
public boolean getHasLocked(){
HashSet<AppWidgetAttribute> itemSet = new HashSet<AppWidgetAttribute>();
for (Integer position : mSelectedIndex.keySet()) {
if (mSelectedIndex.get(position) == true) {
Cursor c = (Cursor) getItem(position);
if (c != null) {
NoteItemData item = new NoteItemData(mContext, c);
if(item.getIsLocked()){
return true;
}
/**
* Don't close cursor here, only the adapter could close it
*/
} else {
Log.e(TAG, "Invalid cursor");
return true;
}
}
}
return false;
}
public int getSelectedCount() {
Collection<Boolean> values = mSelectedIndex.values();
if (null == values) {

@ -82,7 +82,7 @@ public class NotesListItem extends LinearLayout {
if (data.getType() == Notes.TYPE_FOLDER) {
mTitle.setText(data.getSnippet()
+ context.getString(R.string.format_folder_files_count,
data.getNotesCount()));
data.getNotesCount()));
mAlert.setVisibility(View.GONE);
} else {
mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
@ -101,6 +101,11 @@ public class NotesListItem extends LinearLayout {
private void setBackground(NoteItemData data) {
int id = data.getBgColorId();
// setBackgroundResource(R.color.user_query_highlight);
// setBackgroundColor(0xFF888888);
// setX(500);
// setWeightSum((float)1);
// setw
if (data.getType() == Notes.TYPE_NOTE) {
if (data.isSingle() || data.isOneFollowingFolder()) {
setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id));

@ -144,7 +144,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
}
} else {
Toast.makeText(NotesPreferenceActivity.this,
R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT)
R.string.preferences_toast_cannot_change_account, Toast.LENGTH_SHORT)
.show();
}
return true;
@ -246,7 +246,7 @@ public class NotesPreferenceActivity extends PreferenceActivity {
mHasAddedAccount = true;
Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
intent.putExtra(AUTHORITIES_FILTER_KEY, new String[] {
"gmail-ls"
"gmail-ls"
});
startActivityForResult(intent, -1);
dialog.dismiss();

@ -34,9 +34,9 @@ import net.micode.notes.ui.NotesListActivity;
public abstract class NoteWidgetProvider extends AppWidgetProvider {
public static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
NoteColumns.ID,
NoteColumns.BG_COLOR_ID,
NoteColumns.SNIPPET
};
public static final int COLUMN_ID = 0;
@ -70,7 +70,7 @@ public abstract class NoteWidgetProvider extends AppWidgetProvider {
}
private void update(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds,
boolean privacyMode) {
boolean privacyMode) {
for (int i = 0; i < appWidgetIds.length; i++) {
if (appWidgetIds[i] != AppWidgetManager.INVALID_APPWIDGET_ID) {
int bgId = ResourceParser.getDefaultBgId(context);

@ -2,6 +2,7 @@
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
#
#Fri Feb 24 19:59:47 CST 2023
sdk.dir=D\:\\Environment\\Android\\Sdk
# For customization when using a Version Control System, please read the
# header note.
#Wed Mar 08 18:43:32 CST 2023
sdk.dir=D\:\\Environment\\Sdk

Loading…
Cancel
Save