diff --git a/src/app/build.gradle b/src/app/build.gradle index fa32ae9..79dd756 100644 --- a/src/app/build.gradle +++ b/src/app/build.gradle @@ -32,6 +32,7 @@ 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' diff --git a/src/app/src/main/AndroidManifest.xml b/src/app/src/main/AndroidManifest.xml index 5574e2a..9956ed2 100644 --- a/src/app/src/main/AndroidManifest.xml +++ b/src/app/src/main/AndroidManifest.xml @@ -15,6 +15,7 @@ + > matches = new java.util.ArrayList<>(); + while (matcher.find()) { + String path = matcher.group(1); + java.util.Map 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 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); @@ -837,6 +941,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); mEditTextList.setVisibility(View.GONE); mNoteEditor.setVisibility(View.VISIBLE); + convertToImage(); } } @@ -865,6 +970,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, private boolean saveNote() { getWorkingText(); + // 确保在保存前转换所有图片路径为可显示的格式 + convertToImage(); boolean saved = mWorkingNote.saveNote(); if (saved) { /** @@ -928,4 +1035,145 @@ 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; + } + } + // } diff --git a/src/app/src/main/res/layout/note_edit.xml b/src/app/src/main/res/layout/note_edit.xml index 10b2aa7..86915ba 100644 --- a/src/app/src/main/res/layout/note_edit.xml +++ b/src/app/src/main/res/layout/note_edit.xml @@ -116,6 +116,15 @@ + +