Compare commits

..

18 Commits

Author SHA1 Message Date
WangYucheng 80f66c1c17 Merge branch 'wangyucheng_branch' of https://bdgit.educoder.net/p59o8bajr/Notes_master into wangyucheng_branch
10 months ago
WangYucheng 3d4e6fcc30 20250511文件更新
10 months ago
WangYucheng 90b9f1414c 20250511
10 months ago
WangYucheng 1df4cba3f3 20250420文件更新
10 months ago
WangYucheng f9cf9221d1 Resolve misc.xml conflict by keeping local/remote version
10 months ago
WangYucheng f5aee0eefe 20250420文件更新3
10 months ago
WangYucheng 1dad7c39f5 20250420文件更新2
10 months ago
WangYucheng a8897e5017 20250420文件更新
10 months ago
WangYucheng 7e6db0c1ce Merge remote changes
10 months ago
WangYucheng 96c09cad58 提交1
10 months ago
WangYucheng 619aea0f28 20250406做了一些小修改,适配我本地环境
11 months ago
郭佳豪 c7ac309ebc v0.0
12 months ago
郭佳豪 171407e67c v0.0
12 months ago
郭佳豪 8db84126d1 v0.0
12 months ago
郭佳豪 c26c1b8223 v0.0
12 months ago
郭佳豪 ff8be72aa8 v0.0
12 months ago
郭佳豪 952ed747bd v0.0
12 months ago
郭佳豪 bb9fe2a1ab v0.0
12 months ago

@ -4,6 +4,7 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="corretto-18" />
<option name="modules">

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_18" default="true" project-jdk-name="corretto-18" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_18_PREVIEW" project-jdk-name="corretto-18" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

@ -2,5 +2,6 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -1,2 +0,0 @@
# Notes_master

@ -32,7 +32,6 @@ android {
}
dependencies {
implementation 'commons-logging:commons-logging:1.2'
implementation 'androidx.core:core:1.8.0' // 使
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'

@ -15,7 +15,6 @@
<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.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"

@ -38,7 +38,7 @@ public class WorkingNote {
// Note Id
private long mNoteId;
// Note content
public String mContent;
private String mContent;
// Note mode
private int mMode;

@ -16,32 +16,25 @@
package net.micode.notes.ui;
import android.Manifest;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.SearchManager;
import android.appwidget.AppWidgetManager;
import android.content.*;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
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;
@ -50,10 +43,15 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.*;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.content.ContextCompat;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.TextNote;
@ -66,9 +64,7 @@ import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener;
import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import org.apache.commons.logging.LogFactory;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@ -78,8 +74,6 @@ import java.util.regex.Pattern;
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
private static final org.apache.commons.logging.Log log = LogFactory.getLog(NoteEditActivity.class);
private class HeadViewHolder {
public TextView tvModified;
@ -155,21 +149,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private String mUserQuery;
private Pattern mPattern;
// @Override
// protected void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// this.setContentView(R.layout.note_edit);
// if (savedInstanceState == null && !initActivityState(getIntent())) {
// finish();
// return;
// }
// initResources();
// }
private final int PHOTO_REQUEST=1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit);
@ -179,23 +159,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return;
}
initResources();
//根据id获取添加图片按钮
final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);
//为点击图片按钮设置监听器
add_img_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: click add image button");
//ACTION_GET_CONTENT: 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT);
//Category属性用于指定当前动作Action被执行的环境.
//CATEGORY_OPENABLE; 用来指示一个ACTION_GET_CONTENT的intent
loadImage.addCategory(Intent.CATEGORY_OPENABLE);
loadImage.setType("image/*");
startActivityForResult(loadImage, PHOTO_REQUEST);
}
});
}
/**
@ -312,7 +275,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
switchToListMode(mWorkingNote.getContent());
} else {
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
convertToImage();
mNoteEditor.setSelection(mNoteEditor.getText().length());
}
for (Integer id : sBgSelectorSelectionMap.keySet()) {
@ -331,7 +293,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* is not ready
*/
showAlertHeader();
convertToImage(); // 确保每次进入页面都执行图片转换
}
private void showAlertHeader() {
@ -351,71 +312,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
};
}
private void convertToImage() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "缺少读取外部存储权限,无法解码图片");
return;
}
NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view);
Editable editable = noteEditText.getText();
String noteText = editable.toString();
// 使用正则表达式匹配图片路径
Pattern pattern = Pattern.compile("\\[local\\](.*?)\\[/local\\]");
Matcher matcher = pattern.matcher(noteText);
// 存储匹配到的图片路径及其位置
java.util.List<java.util.Map<String, Object>> matches = new java.util.ArrayList<>();
while (matcher.find()) {
String path = matcher.group(1);
java.util.Map<String, Object> matchInfo = new java.util.HashMap<>();
matchInfo.put("path", path);
matchInfo.put("start", matcher.start());
matchInfo.put("end", matcher.end());
matches.add(matchInfo);
}
for (int i = matches.size() - 1; i >= 0; i--) {
java.util.Map<String, Object> matchInfo = matches.get(i);
String path = (String) matchInfo.get("path");
int start = (int) matchInfo.get("start");
int end = (int) matchInfo.get("end");
Bitmap bitmap = null;
Log.d(TAG, "尝试解码图片,路径:" + path);
java.io.File file = new java.io.File(path);
if (!file.exists()) {
Log.e(TAG, "图片文件不存在,路径:" + path);
continue;
}
try {
bitmap = BitmapFactory.decodeFile(path);
if (bitmap != null) {
Log.d(TAG, "图片解码成功,路径:" + path);
} else {
Log.e(TAG, "图片解码失败,路径:" + path);
}
} catch (Exception e) {
Log.e(TAG, "图片解码异常,路径:" + path, e);
}
if (bitmap != null) {
ImageSpan imageSpan = new ImageSpan(this, bitmap);
String imgTag = "[local]" + path + "[/local]";
SpannableString spannableString = new SpannableString(imgTag);
spannableString.setSpan(imageSpan, 0, imgTag.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 替换原始文本
editable.replace(start, end, spannableString);
}
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@ -774,7 +670,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (mWorkingNote.getNoteId() > 0) {
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
showAlertHeader();
if(!set) {
@ -941,7 +837,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mEditTextList.setVisibility(View.GONE);
mNoteEditor.setVisibility(View.VISIBLE);
convertToImage();
}
}
@ -970,8 +865,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private boolean saveNote() {
getWorkingText();
// 确保在保存前转换所有图片路径为可显示的格式
convertToImage();
boolean saved = mWorkingNote.saveNote();
if (saved) {
/**
@ -1035,145 +928,4 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
//获取文件的real path
public String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
// if (isExternalStorageDocument(uri)) {
// final String docId = DocumentsContract.getDocumentId(uri);
// final String[] split = docId.split(":");
// final String type = split[0];
//
// if ("primary".equalsIgnoreCase(type)) {
// return Environment.getExternalStorageDirectory() + "/" + split[1];
// }
// }
// // DownloadsProvider
// else if (isDownloadsDocument(uri)) {
// final String id = DocumentsContract.getDocumentId(uri);
// final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
// return getDataColumn(context, contentUri, null, null);
// }
// MediaProvider
// else
if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// Media
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
//获取数据列_获取此 Uri 的数据列的值。这对MediaStore Uris 和其他基于文件的 ContentProvider。
public String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
//是否为外部存储文件
// public boolean isExternalStorageDocument(Uri uri) {
// return "com.android.externalstorage.documents".equals(uri.getAuthority());
// }
//
// //是否为下载文件
// public boolean isDownloadsDocument(Uri uri) {
// return "com.android.providers.downloads.documents".equals(uri.getAuthority());
// }
//是否为媒体文件
public boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
ContentResolver resolver = getContentResolver();
switch (requestCode) {
case PHOTO_REQUEST:
Uri originalUri = intent.getData(); //1.获得图片的真实路径
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));//2.解码图片
} catch (FileNotFoundException e) {
Log.d(TAG, "onActivityResult: get file_exception");
e.printStackTrace();
}
if (bitmap != null) {
//3.根据Bitmap对象创建ImageSpan对象
Log.d(TAG, "onActivityResult: bitmap is not null");
ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
String path = getPath(this, originalUri);
//4.使用[local][/local]将path括起来用于之后方便识别图片路径在note中的位置
String img_fragment = "[local]" + path + "[/local]";
//创建一个SpannableString对象以便插入用ImageSpan对象封装的图像
SpannableString spannableString = new SpannableString(img_fragment);
spannableString.setSpan(imageSpan, 0, img_fragment.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//5.将选择的图片追加到EditText中光标所在位置
NoteEditText e = (NoteEditText) findViewById(R.id.note_edit_view);
int index = e.getSelectionStart(); //获取光标所在位置
Log.d(TAG, "Index是: " + index);
Editable edit_text = e.getEditableText();
edit_text.insert(index, spannableString); //将图片插入到光标所在位置
mWorkingNote.mContent = e.getText().toString();
//6.把改动提交到数据库中,两个数据库表都要改的
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
final long id = mWorkingNote.getNoteId();
contentValues.put("snippet", mWorkingNote.mContent);
contentResolver.update(Uri.parse("content://micode_notes/note"), contentValues, "_id=?", new String[]{"" + id});
ContentValues contentValues1 = new ContentValues();
contentValues1.put("content", mWorkingNote.mContent);
contentResolver.update(Uri.parse("content://micode_notes/data"), contentValues1, "mime_type=? and note_id=?", new String[]{"vnd.android.cursor.item/text_note", "" + id});
} else {
Toast.makeText(NoteEditActivity.this, "获取图片失败", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
//
}

@ -79,7 +79,6 @@ import java.io.InputStreamReader;
import java.util.HashSet;
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
public static int secret_mode = 0;
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
private static final int FOLDER_LIST_QUERY_TOKEN = 1;
@ -412,35 +411,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
if(secret_mode == 0) {
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
else{
String str1 = "123";
String [] PROJECTION = new String [] { //定义一个新的PROJECTION数组只换掉SNIPPET
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,
str1,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
};
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
private final class BackgroundQueryHandler extends AsyncQueryHandler {
@ -794,17 +768,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
// set sync or sync_cancel
menu.findItem(R.id.menu_sync).setTitle(
GTaskSyncService.isSyncing() ? R.string.menu_sync_cancel : R.string.menu_sync);
// 修复:先查找菜单项再设置可见性
MenuItem secretItem = menu.findItem(R.id.menu_secret);
MenuItem quitSecretItem = menu.findItem(R.id.menu_quit_secret);
if (secretItem != null && quitSecretItem != null) {
if(secret_mode == 1) {
secretItem.setVisible(false);
} else {
quitSecretItem.setVisible(false);
}
}
} else if (mState == ListEditState.SUB_FOLDER) {
getMenuInflater().inflate(R.menu.sub_folder, menu);
} else if (mState == ListEditState.CALL_RECORD_FOLDER) {
@ -818,52 +781,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_quit_secret: {
secret_mode = 0;
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认退出私密模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 确保在主线程执行数据加载
runOnUiThread(new Runnable() {
@Override
public void run() {
startAsyncNotesListQuery();
Toast.makeText(NotesListActivity.this,"您已退出私密模式",Toast.LENGTH_SHORT).show();
}
});
}
});
dialog.setNegativeButton("取消", null);
dialog.show();
break;
}
case R.id.menu_secret: {
secret_mode = 1;
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认进入私密模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 确保在主线程执行数据加载
runOnUiThread(new Runnable() {
@Override
public void run() {
startAsyncNotesListQuery();
Toast.makeText(NotesListActivity.this,"您已进入私密模式",Toast.LENGTH_SHORT).show();
}
});
}
});
dialog.setNegativeButton("取消", null);
dialog.show();
break;
}
case R.id.menu_new_folder: {
showCreateOrModifyFolderDialog(true);
break;

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

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

Loading…
Cancel
Save