diff --git a/src/Notes-master/mainfests/AndroidManifest.xml b/src/Notes-master/mainfests/AndroidManifest.xml
index a85867b..e099d24 100644
--- a/src/Notes-master/mainfests/AndroidManifest.xml
+++ b/src/Notes-master/mainfests/AndroidManifest.xml
@@ -17,6 +17,7 @@
+
diff --git a/src/Notes-master/res/layout/note_edit.xml b/src/Notes-master/res/layout/note_edit.xml
index 503fcb1..c9015cc 100644
--- a/src/Notes-master/res/layout/note_edit.xml
+++ b/src/Notes-master/res/layout/note_edit.xml
@@ -56,15 +56,6 @@
android:layout_marginRight="8dip"
android:textAppearance="@style/TextAppearanceSecondaryItem" />
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -273,9 +317,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
+ android:layout_marginRight="2dip"
android:focusable="false"
android:visibility="gone"
- android:layout_marginRight="2dip"
android:src="@drawable/selected" />
diff --git a/src/Notes-master/res/values/strings.xml b/src/Notes-master/res/values/strings.xml
index 170e4f0..79e9545 100644
--- a/src/Notes-master/res/values/strings.xml
+++ b/src/Notes-master/res/values/strings.xml
@@ -88,6 +88,8 @@
The note is not exist
Sorry, can not set clock on empty note
Sorry, can not send and empty note to home
+ Permission denied, cannot access images
+ Failed to insert image, please try again
Export successful
Export fail
Export text file (%1$s) to SD (%2$s) directory
diff --git a/src/Notes-master/src/net/micode/notes/tool/DataUtils.java b/src/Notes-master/src/net/micode/notes/tool/DataUtils.java
index 717c14a..1f1b2b8 100644
--- a/src/Notes-master/src/net/micode/notes/tool/DataUtils.java
+++ b/src/Notes-master/src/net/micode/notes/tool/DataUtils.java
@@ -81,11 +81,11 @@ public class DataUtils {
// Query the note from note table
cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id),
null, null, null, null);
-
+
if (cursor != null && cursor.moveToFirst()) {
// Read all columns from the note
ContentValues trashValues = new ContentValues();
-
+
// Copy all columns from note to trash
for (String column : cursor.getColumnNames()) {
int columnIndex = cursor.getColumnIndex(column);
@@ -109,13 +109,13 @@ public class DataUtils {
}
}
}
-
+
// Set deleted_date to current time
trashValues.put("deleted_date", System.currentTimeMillis());
-
+
// Insert into trash table
resolver.insert(Notes.CONTENT_TRASH_URI, trashValues);
-
+
// 在删除note之前,先备份DATA表的数据
if (db != null) {
// 查询该note的所有DATA数据
@@ -163,7 +163,7 @@ public class DataUtils {
// Delete from note table (this will trigger deletion of DATA table via trigger)
resolver.delete(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, id), null, null);
}
-
+
if (cursor != null) {
cursor.close();
cursor = null;
@@ -202,7 +202,7 @@ public class DataUtils {
}
public static boolean batchMoveToFolder(ContentResolver resolver, HashSet ids,
- long folderId) {
+ long folderId) {
if (ids == null) {
Log.d(TAG, "the ids is null");
return true;
@@ -305,8 +305,8 @@ public class DataUtils {
public static boolean checkVisibleFolderName(ContentResolver resolver, String name) {
Cursor cursor = resolver.query(Notes.CONTENT_NOTE_URI, null,
NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER +
- " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER +
- " AND " + NoteColumns.SNIPPET + "=?",
+ " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER +
+ " AND " + NoteColumns.SNIPPET + "=?",
new String[] { name }, null);
boolean exist = false;
if(cursor != null) {
@@ -391,7 +391,7 @@ public class DataUtils {
// Query the note from trash table
cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_TRASH_URI, trashId),
null, null, null, null);
-
+
if (cursor != null && cursor.moveToFirst()) {
// Read all columns from the trash note
ContentValues noteValues = new ContentValues();
@@ -428,14 +428,14 @@ public class DataUtils {
}
}
}
-
+
// Insert back to note table
Uri restoredUri = resolver.insert(Notes.CONTENT_NOTE_URI, noteValues);
if (restoredUri == null) {
Log.e(TAG, "Failed to restore note to note table");
return false;
}
-
+
// 获取恢复后的note ID(可能是新的ID)
long restoredNoteId = ContentUris.parseId(restoredUri);
if (restoredNoteId <= 0) {
@@ -500,7 +500,7 @@ public class DataUtils {
// Delete from trash table
resolver.delete(ContentUris.withAppendedId(Notes.CONTENT_TRASH_URI, trashId), null, null);
-
+
return true;
}
return false;
@@ -582,7 +582,7 @@ public class DataUtils {
Cursor cursor = resolver.query(Notes.CONTENT_DATA_URI,
new String [] { CallNote.NOTE_ID },
CallNote.CALL_DATE + "=? AND " + CallNote.MIME_TYPE + "=? AND PHONE_NUMBERS_EQUAL("
- + CallNote.PHONE_NUMBER + ",?)",
+ + CallNote.PHONE_NUMBER + ",?)",
new String [] { String.valueOf(callDate), CallNote.CONTENT_ITEM_TYPE, phoneNumber },
null);
@@ -620,6 +620,8 @@ public class DataUtils {
public static String getFormattedSnippet(String snippet) {
if (snippet != null) {
snippet = snippet.trim();
+ // 替换[IMAGE]标签为友好的占位符
+ snippet = snippet.replaceAll("\\[IMAGE\\].*?\\[/IMAGE\\]", "[图片]");
int index = snippet.indexOf('\n');
if (index != -1) {
snippet = snippet.substring(0, index);
diff --git a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
index 7cfd52d..c8c4be5 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
@@ -27,11 +27,16 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
import android.graphics.Paint;
+import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
+import android.provider.MediaStore;
import android.text.Spannable;
import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.BackgroundColorSpan;
@@ -47,23 +52,19 @@ import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
+import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
-import android.widget.ImageButton;
-import android.provider.MediaStore;
-import android.net.Uri;
-import java.io.File;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.Editable;
-import android.text.style.ImageSpan;
+import android.graphics.Typeface;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.content.ContentResolver;
import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
+// import android.support.annotation.NonNull;
+import android.Manifest;
import android.graphics.Color;
import java.io.InputStream;
import java.io.FileOutputStream;
@@ -443,6 +444,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return new SpannableString("");
}
+ Log.d(TAG, "Converting text to Spannable with images: " + text);
+
// 创建一个新的SpannableStringBuilder
SpannableStringBuilder builder = new SpannableStringBuilder();
@@ -451,6 +454,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
int imageStart = text.indexOf("[IMAGE]", startIndex);
while (imageStart != -1) {
+ Log.d(TAG, "Found [IMAGE] tag at position: " + imageStart);
+
// 添加[IMAGE]标签之前的文本
builder.append(text.substring(startIndex, imageStart));
@@ -462,43 +467,97 @@ public class NoteEditActivity extends Activity implements OnClickListener,
break;
}
+ Log.d(TAG, "Found [/IMAGE] tag at position: " + imageEnd);
+
// 提取图片URI
String imageUri = text.substring(imageStart + "[IMAGE]".length(), imageEnd);
- Log.d(TAG, "Found image URI: " + imageUri);
+ Log.d(TAG, "Extracted image URI: " + imageUri);
- // 创建一个占位符字符串,用于插入ImageSpan
- String placeholder = " ";
- int placeholderStart = builder.length();
- builder.append(placeholder);
+ // 保留原始的[IMAGE]uri[/IMAGE]标签,直接在上面添加ImageSpan
+ String fullImageTag = "[IMAGE]" + imageUri + "[/IMAGE]";
+ int tagStart = builder.length();
+ builder.append(fullImageTag);
// 尝试将图片URI转换为Drawable并创建ImageSpan
try {
+ // 确保URI是有效的
+ Uri uri = Uri.parse(imageUri);
+ if (uri == null) {
+ Log.e(TAG, "Invalid URI: " + imageUri);
+ // 更新索引,继续处理下一个标签
+ startIndex = imageEnd + "[/IMAGE]".length();
+ imageStart = text.indexOf("[IMAGE]", startIndex);
+ continue;
+ }
+
+ Log.d(TAG, "Attempting to load image from URI: " + uri.toString());
+
+ // 使用BitmapFactory直接加载图片,这是最可靠的方式
ContentResolver resolver = getContentResolver();
- InputStream inputStream = resolver.openInputStream(Uri.parse(imageUri));
- Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
- inputStream.close();
-
- // 计算图片的合适大小,确保它能适应EditText的宽度
- int screenWidth = getResources().getDisplayMetrics().widthPixels;
- int imageWidth = bitmap.getWidth();
- int imageHeight = bitmap.getHeight();
- float scale = (float) screenWidth / (float) imageWidth;
- int scaledHeight = (int) (imageHeight * scale);
-
- // 缩放图片
- Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, screenWidth, scaledHeight, true);
- Drawable drawable = new android.graphics.drawable.BitmapDrawable(getResources(), scaledBitmap);
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
-
- // 创建ImageSpan并添加到SpannableStringBuilder中
- ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
- builder.setSpan(imageSpan, placeholderStart, placeholderStart + placeholder.length(), SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
+ InputStream inputStream = null;
+ try {
+ inputStream = resolver.openInputStream(uri);
+ if (inputStream == null) {
+ Log.e(TAG, "Failed to open input stream for URI: " + uri.toString());
+ // 更新索引,继续处理下一个标签
+ startIndex = imageEnd + "[/IMAGE]".length();
+ imageStart = text.indexOf("[IMAGE]", startIndex);
+ continue;
+ }
+
+ // 解码图片
+ Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
+ if (bitmap == null) {
+ Log.e(TAG, "Failed to decode bitmap from URI: " + uri.toString());
+ // 更新索引,继续处理下一个标签
+ startIndex = imageEnd + "[/IMAGE]".length();
+ imageStart = text.indexOf("[IMAGE]", startIndex);
+ continue;
+ }
+
+ Log.d(TAG, "Successfully decoded bitmap with dimensions: " + bitmap.getWidth() + "x" + bitmap.getHeight());
+
+ // 计算图片的合适大小,确保它能适应EditText的宽度
+ int screenWidth = getResources().getDisplayMetrics().widthPixels;
+ // 减去左右边距,确保图片能完整显示
+ int maxWidth = screenWidth - 40;
+ int imageWidth = bitmap.getWidth();
+ int imageHeight = bitmap.getHeight();
+
+ // 计算缩放比例
+ float scale = 1.0f;
+ if (imageWidth > maxWidth) {
+ scale = (float) maxWidth / (float) imageWidth;
+ }
+ Log.d(TAG, "Calculated scale: " + scale);
+
+ // 缩放图片(如果需要)
+ if (scale < 1.0f) {
+ bitmap = Bitmap.createScaledBitmap(bitmap, (int)(imageWidth * scale), (int)(imageHeight * scale), true);
+ Log.d(TAG, "Scaled bitmap to: " + bitmap.getWidth() + "x" + bitmap.getHeight());
+ }
+
+ // 创建Drawable并设置边界
+ Drawable drawable = new android.graphics.drawable.BitmapDrawable(getResources(), bitmap);
+ drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
+
+ // 创建ImageSpan并添加到SpannableStringBuilder中
+ ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
+ builder.setSpan(imageSpan, tagStart, tagStart + fullImageTag.length(), SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
+ Log.d(TAG, "Successfully added ImageSpan for URI: " + imageUri);
+ } finally {
+ // 确保InputStream被正确关闭
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (Exception e) {
+ Log.e(TAG, "Error closing input stream: " + e.toString());
+ }
+ }
+ }
} catch (Exception e) {
Log.e(TAG, "Error loading image: " + e.toString());
- // 如果加载图片失败,直接显示图片URI
- builder.append("[IMAGE]");
- builder.append(imageUri);
- builder.append("[/IMAGE]");
+ e.printStackTrace();
}
// 更新索引,继续查找下一个[IMAGE]标签
@@ -509,6 +568,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
// 添加剩余的文本
builder.append(text.substring(startIndex));
+ Log.d(TAG, "Final SpannableStringBuilder content: " + builder.toString());
return new SpannableString(builder);
}
@@ -679,7 +739,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (mBtnInsertImage != null) {
mBtnInsertImage.setOnClickListener(this);
}
-
+
// 初始化富文本功能按钮
initRichEditorButtons();
}
@@ -1368,6 +1428,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
/**
* 从相册选择图片 OMO
*/
+ private static final int REQUEST_CODE_PERMISSION_STORAGE = 101;
+
private void pickImageFromGallery() {
try {
// 意图:打开系统相册选择图片
@@ -1387,6 +1449,21 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
+ // 处理权限请求结果
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == REQUEST_CODE_PERMISSION_STORAGE) {
+ if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ // 权限被授予,执行图片选择
+ pickImageFromGallery();
+ } else {
+ // 权限被拒绝,显示提示
+ showToast(R.string.error_permission_denied);
+ }
+ }
+ }
+
/**
* 处理图片选择结果 OMO
*/