diff --git a/src/main/java/net/micode/notes/tool/AIService.java b/src/main/java/net/micode/notes/tool/AIService.java
new file mode 100644
index 0000000..c2a0e93
--- /dev/null
+++ b/src/main/java/net/micode/notes/tool/AIService.java
@@ -0,0 +1,409 @@
+package net.micode.notes.tool;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.util.Base64;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * AIService - AI服务类
+ *
+ * 用于处理与AI相关的服务调用,如豆包API
+ *
+ */
+public class AIService {
+ private static final String TAG = "AIService";
+ private static final String DOUBAO_API_URL = "https://ark.cn-beijing.volces.com/api/v3/responses";
+ private static final String API_KEY = "ee5fb4c7-ea14-4481-ac23-4b0e82907850";
+ private static final String SECRET_ACCESS_KEY = "";
+
+ /**
+ * 提取图片内容
+ * @param bitmap 图片bitmap
+ * @param callback 回调接口
+ */
+ public static void extractImageContent(final Bitmap bitmap, final ExtractImageContentCallback callback) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Log.d(TAG, "Starting image content extraction...");
+
+ // 检查bitmap
+ if (bitmap == null) {
+ Log.e(TAG, "Bitmap is null");
+ callback.onFailure("Bitmap is null");
+ return;
+ }
+
+ Log.d(TAG, "Bitmap width: " + bitmap.getWidth() + ", height: " + bitmap.getHeight());
+
+ // 将bitmap转换为Base64
+ Log.d(TAG, "Converting bitmap to base64...");
+ String base64Image = bitmapToBase64(bitmap);
+ if (base64Image == null) {
+ Log.e(TAG, "Failed to convert bitmap to base64");
+ callback.onFailure("Failed to convert bitmap to base64");
+ return;
+ }
+ Log.d(TAG, "Base64 conversion successful, length: " + base64Image.length());
+
+ // 构建请求体
+ Log.d(TAG, "Building request body...");
+ JSONObject requestBody = new JSONObject();
+ requestBody.put("model", "ep-20260127214554-frsrr"); // 新的推理接入点ID
+
+ // 创建input数组
+ org.json.JSONArray input = new org.json.JSONArray();
+
+ // 创建user input
+ JSONObject userInput = new JSONObject();
+ userInput.put("role", "user");
+
+ // 创建content数组
+ org.json.JSONArray contentArray = new org.json.JSONArray();
+
+ // 添加图片部分
+ JSONObject imageContent = new JSONObject();
+ imageContent.put("type", "input_image");
+ imageContent.put("image_url", "data:image/jpeg;base64," + base64Image);
+ contentArray.put(imageContent);
+
+ // 添加文本部分
+ JSONObject textContent = new JSONObject();
+ textContent.put("type", "input_text");
+ textContent.put("text", "请提取这张图片中的所有文字和结构化数据,包括表格、列表等信息,清晰准确地格式化提取的内容。");
+ contentArray.put(textContent);
+
+ userInput.put("content", contentArray);
+ input.put(userInput);
+
+ requestBody.put("input", input);
+
+ // 发送请求
+ String requestBodyString = requestBody.toString();
+ Log.d(TAG, "Request body length: " + requestBodyString.length());
+ Log.d(TAG, "Request body (first 1000 chars): " + (requestBodyString.length() > 1000 ? requestBodyString.substring(0, 1000) + "..." : requestBodyString));
+
+ Log.d(TAG, "Sending POST request to: " + DOUBAO_API_URL);
+ String response = sendPostRequest(DOUBAO_API_URL, requestBodyString);
+
+ if (response == null) {
+ Log.e(TAG, "Failed to get response from Doubao API");
+ callback.onFailure("Failed to get response from Doubao API");
+ return;
+ }
+
+ Log.d(TAG, "Got response from Doubao API, length: " + response.length());
+ Log.d(TAG, "Response content: " + response);
+
+ // 解析响应
+ Log.d(TAG, "Parsing response...");
+ JSONObject responseJson = new JSONObject(response);
+
+ // 检查响应格式
+ if (responseJson.has("output")) {
+ Log.d(TAG, "Response has output field");
+ try {
+ // 尝试作为数组处理(新格式)
+ org.json.JSONArray outputArray = responseJson.getJSONArray("output");
+ Log.d(TAG, "Output is an array, length: " + outputArray.length());
+
+ // 遍历数组找到包含文本的message
+ String extractedText = "";
+ for (int i = 0; i < outputArray.length(); i++) {
+ JSONObject item = outputArray.getJSONObject(i);
+ Log.d(TAG, "Output item " + i + ": " + item.toString());
+
+ // 检查是否是message类型
+ if (item.has("type") && "message".equals(item.getString("type"))) {
+ Log.d(TAG, "Found message item");
+ if (item.has("content")) {
+ org.json.JSONArray messageContentArray = item.getJSONArray("content");
+ for (int j = 0; j < messageContentArray.length(); j++) {
+ JSONObject contentItem = messageContentArray.getJSONObject(j);
+ if (contentItem.has("type") && "output_text".equals(contentItem.getString("type"))) {
+ extractedText = contentItem.getString("text");
+ Log.d(TAG, "Got text from response: " + extractedText);
+ callback.onSuccess(extractedText);
+ return;
+ }
+ }
+ }
+ }
+ // 检查是否有role字段为assistant
+ else if (item.has("role") && "assistant".equals(item.getString("role"))) {
+ Log.d(TAG, "Found assistant item");
+ if (item.has("content")) {
+ org.json.JSONArray assistantContentArray = item.getJSONArray("content");
+ for (int j = 0; j < assistantContentArray.length(); j++) {
+ JSONObject contentItem = assistantContentArray.getJSONObject(j);
+ if (contentItem.has("type") && "output_text".equals(contentItem.getString("type"))) {
+ extractedText = contentItem.getString("text");
+ Log.d(TAG, "Got text from assistant response: " + extractedText);
+ callback.onSuccess(extractedText);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ // 如果没有找到文本,尝试其他方式
+ if (extractedText.isEmpty()) {
+ Log.e(TAG, "No text found in output array");
+ callback.onFailure("No text found in output array");
+ }
+ } catch (JSONException e) {
+ // 如果不是数组,尝试作为对象处理(旧格式)
+ Log.d(TAG, "Output is not an array, trying as object: " + e.getMessage());
+ try {
+ JSONObject outputObj = responseJson.getJSONObject("output");
+ if (outputObj.has("text")) {
+ String content = outputObj.getString("text");
+ Log.d(TAG, "Got text from response object: " + content);
+ callback.onSuccess(content);
+ } else if (outputObj.has("content")) {
+ String content = outputObj.getString("content");
+ Log.d(TAG, "Got content from response object: " + content);
+ callback.onSuccess(content);
+ } else {
+ Log.e(TAG, "No text or content in response object: " + outputObj.toString());
+ callback.onFailure("No text or content in response");
+ }
+ } catch (JSONException ex) {
+ Log.e(TAG, "Error parsing output: " + ex.getMessage());
+ callback.onFailure("Error parsing output: " + ex.getMessage());
+ }
+ }
+ } else if (responseJson.has("choices")) {
+ // 兼容旧格式
+ Log.d(TAG, "Response has choices field");
+ org.json.JSONArray choices = responseJson.getJSONArray("choices");
+ if (choices.length() > 0) {
+ JSONObject choice = choices.getJSONObject(0);
+ if (choice.has("message")) {
+ JSONObject message = choice.getJSONObject("message");
+ if (message.has("content")) {
+ String content = message.getString("content");
+ Log.d(TAG, "Got content from choices: " + content);
+ callback.onSuccess(content);
+ } else {
+ Log.e(TAG, "No content in message: " + message.toString());
+ callback.onFailure("No content in message");
+ }
+ } else {
+ Log.e(TAG, "No message in choice: " + choice.toString());
+ callback.onFailure("No message in choice");
+ }
+ } else {
+ Log.e(TAG, "No choices in response");
+ callback.onFailure("No choices in response");
+ }
+ } else if (responseJson.has("error")) {
+ // 处理错误响应
+ Log.e(TAG, "API returned error: " + responseJson.toString());
+ JSONObject error = responseJson.getJSONObject("error");
+ String errorMessage = error.getString("message");
+ callback.onFailure("API error: " + errorMessage);
+ } else {
+ Log.e(TAG, "Unexpected response format: " + responseJson.toString());
+ callback.onFailure("Unexpected response format: " + responseJson.toString());
+ }
+
+ } catch (JSONException e) {
+ Log.e(TAG, "JSONException: " + e.getMessage());
+ e.printStackTrace();
+ callback.onFailure("JSON error: " + e.getMessage());
+ } catch (Exception e) {
+ Log.e(TAG, "Exception: " + e.getMessage());
+ e.printStackTrace();
+ callback.onFailure("Error: " + e.getMessage());
+ }
+ }
+ }).start();
+ }
+
+ /**
+ * 将Bitmap转换为Base64字符串
+ * @param bitmap 图片bitmap
+ * @return Base64字符串
+ */
+ private static String bitmapToBase64(Bitmap bitmap) {
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream);
+ byte[] byteArray = byteArrayOutputStream.toByteArray();
+ try {
+ byteArrayOutputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return Base64.encodeToString(byteArray, Base64.NO_WRAP);
+ }
+
+ /**
+ * 发送POST请求
+ * @param urlString URL字符串
+ * @param requestBody 请求体
+ * @return 响应字符串
+ */
+ private static String sendPostRequest(String urlString, String requestBody) {
+ try {
+ Log.d(TAG, "Sending POST request to: " + urlString);
+ Log.d(TAG, "Request body length: " + requestBody.length());
+ Log.d(TAG, "Request body (first 500 chars): " + (requestBody.length() > 500 ? requestBody.substring(0, 500) + "..." : requestBody));
+
+ URL url = new URL(urlString);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ // 设置请求头
+ connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty("Authorization", "Bearer " + API_KEY);
+ connection.setRequestProperty("X-TT-LOGID", System.currentTimeMillis() + "");
+ connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
+ connection.setDoOutput(true);
+ connection.setConnectTimeout(30000); // 设置连接超时为30秒
+ connection.setReadTimeout(30000); // 设置读取超时为30秒
+
+ // 写入请求体
+ Log.d(TAG, "Writing request body...");
+ OutputStream outputStream = connection.getOutputStream();
+ outputStream.write(requestBody.getBytes(StandardCharsets.UTF_8));
+ outputStream.flush();
+ outputStream.close();
+ Log.d(TAG, "Request body written successfully");
+
+ // 读取响应
+ Log.d(TAG, "Reading response...");
+ int responseCode = connection.getResponseCode();
+ Log.d(TAG, "HTTP response code: " + responseCode);
+
+ // 读取所有响应头
+ Log.d(TAG, "Response headers:");
+ java.util.Map> headers = connection.getHeaderFields();
+ for (String key : headers.keySet()) {
+ if (key != null) {
+ Log.d(TAG, key + ": " + headers.get(key));
+ }
+ }
+
+ if (responseCode == HttpURLConnection.HTTP_OK) {
+ Log.d(TAG, "HTTP OK, reading response body...");
+ InputStream inputStream = connection.getInputStream();
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ ByteArrayOutputStream responseStream = new ByteArrayOutputStream();
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ responseStream.write(buffer, 0, bytesRead);
+ }
+ String responseString = responseStream.toString(StandardCharsets.UTF_8.name());
+ responseStream.close();
+ inputStream.close();
+ connection.disconnect();
+ Log.d(TAG, "API response length: " + responseString.length());
+ Log.d(TAG, "API response (first 500 chars): " + (responseString.length() > 500 ? responseString.substring(0, 500) + "..." : responseString));
+ return responseString;
+ } else {
+ // 读取错误响应
+ Log.e(TAG, "HTTP error, reading error response...");
+ InputStream errorStream = connection.getErrorStream();
+ if (errorStream != null) {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ ByteArrayOutputStream errorResponseStream = new ByteArrayOutputStream();
+ while ((bytesRead = errorStream.read(buffer)) != -1) {
+ errorResponseStream.write(buffer, 0, bytesRead);
+ }
+ String errorResponse = errorResponseStream.toString(StandardCharsets.UTF_8.name());
+ errorResponseStream.close();
+ errorStream.close();
+ Log.e(TAG, "HTTP error: " + responseCode + ", Error response: " + errorResponse);
+ } else {
+ Log.e(TAG, "HTTP error code: " + responseCode + ", No error stream available");
+ }
+ connection.disconnect();
+ return null;
+ }
+ } catch (java.net.SocketTimeoutException e) {
+ Log.e(TAG, "Socket timeout error: " + e.getMessage());
+ e.printStackTrace();
+ return null;
+ } catch (java.net.ConnectException e) {
+ Log.e(TAG, "Connection error: " + e.getMessage());
+ e.printStackTrace();
+ return null;
+ } catch (java.io.IOException e) {
+ Log.e(TAG, "IO error: " + e.getMessage());
+ e.printStackTrace();
+ return null;
+ } catch (Exception e) {
+ Log.e(TAG, "Error sending POST request: " + e.getMessage());
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * 提取图片内容回调接口
+ */
+ public interface ExtractImageContentCallback {
+ void onSuccess(String extractedContent);
+ void onFailure(String errorMessage);
+ }
+
+ /**
+ * 测试API连接
+ */
+ public static void testApiConnection(final ExtractImageContentCallback callback) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ // 构建测试请求体
+ JSONObject requestBody = new JSONObject();
+ requestBody.put("model", "ep-20260127214554-frsrr");
+
+ org.json.JSONArray input = new org.json.JSONArray();
+ JSONObject userInput = new JSONObject();
+ userInput.put("role", "user");
+
+ org.json.JSONArray contentArray = new org.json.JSONArray();
+ JSONObject textContent = new JSONObject();
+ textContent.put("type", "input_text");
+ textContent.put("text", "Hello, test connection");
+ contentArray.put(textContent);
+
+ userInput.put("content", contentArray);
+ input.put(userInput);
+
+ requestBody.put("input", input);
+
+ Log.d(TAG, "Testing API connection...");
+ String response = sendPostRequest(DOUBAO_API_URL, requestBody.toString());
+
+ if (response != null) {
+ Log.d(TAG, "API connection test successful: " + response);
+ callback.onSuccess("API connection test successful");
+ } else {
+ Log.e(TAG, "API connection test failed");
+ callback.onFailure("API connection test failed");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error testing API connection: " + e.getMessage());
+ callback.onFailure("Error testing API connection: " + e.getMessage());
+ }
+ }
+ }).start();
+ }
+}
diff --git a/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/main/java/net/micode/notes/ui/NoteEditActivity.java
index 013726d..bf69f19 100644
--- a/src/main/java/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/main/java/net/micode/notes/ui/NoteEditActivity.java
@@ -119,6 +119,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public ImageButton ibRedo; // 重做按钮
public ImageView ibSetBgColor; // 设置背景色按钮
public ImageButton ibInsertImage; // 插入图片按钮
+ public ImageButton ibExtractImage; // 提取图片内容按钮
public TextView tvTitleHint; // 标题提示文字
public EditText etTitle; // 标题输入框
public TextView tvTitleCount; // 字符数提示
@@ -594,6 +595,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);
mNoteHeaderHolder.ibInsertImage = (ImageButton) findViewById(R.id.add_img_btn);
mNoteHeaderHolder.ibInsertImage.setOnClickListener(this);
+ mNoteHeaderHolder.ibExtractImage = (ImageButton) findViewById(R.id.extract_img_btn);
+ mNoteHeaderHolder.ibExtractImage.setOnClickListener(this);
mNoteHeaderHolder.tvTitleHint = (TextView) findViewById(R.id.tv_title_hint);
mNoteHeaderHolder.etTitle = (EditText) findViewById(R.id.et_title);
mNoteHeaderHolder.etTitle.addTextChangedListener(new TextWatcher() {
@@ -795,6 +798,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mFontSizeSelector.setVisibility(View.GONE);
} else if (id == R.id.add_img_btn) {
insertImage();
+ } else if (id == R.id.extract_img_btn) {
+ extractImageContent();
} else if (id == R.id.btn_bold) {
// 处理加粗按钮点击
mNoteEditor.toggleBold();
@@ -1981,4 +1986,143 @@ public class NoteEditActivity extends Activity implements OnClickListener,
showToast(R.string.error_out_of_memory);
}
}
+
+ /**
+ * 提取图片内容
+ */
+ private void extractImageContent() {
+ // 检查当前笔记中是否有图片
+ String content = mNoteEditor.getText().toString();
+ if (!content.contains("[IMAGE:")) {
+ showToast(R.string.error_no_image_in_note);
+ return;
+ }
+
+ // 提取所有图片路径
+ final java.util.List imagePaths = new java.util.ArrayList<>();
+ int startIndex = 0;
+ while (true) {
+ int imageStart = content.indexOf("[IMAGE:", startIndex);
+ if (imageStart == -1) {
+ break;
+ }
+ int imageEnd = content.indexOf("]", imageStart);
+ if (imageEnd == -1) {
+ break;
+ }
+ String imagePath = content.substring(imageStart + 7, imageEnd);
+ imagePaths.add(imagePath);
+ startIndex = imageEnd + 1;
+ }
+
+ if (imagePaths.isEmpty()) {
+ showToast(R.string.error_no_image_in_note);
+ return;
+ }
+
+ // 如果只有一张图片,直接提取
+ if (imagePaths.size() == 1) {
+ extractImageContentFromPath(imagePaths.get(0));
+ return;
+ }
+
+ // 如果有多张图片,让用户选择
+ final String[] imageOptions = new String[imagePaths.size()];
+ for (int i = 0; i < imagePaths.size(); i++) {
+ imageOptions[i] = "Image " + (i + 1);
+ }
+
+ new android.app.AlertDialog.Builder(this)
+ .setTitle("Select Image")
+ .setItems(imageOptions, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String selectedImagePath = imagePaths.get(which);
+ extractImageContentFromPath(selectedImagePath);
+ }
+ })
+ .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ })
+ .show();
+ }
+
+ /**
+ * 从指定路径提取图片内容
+ */
+ private void extractImageContentFromPath(final String imagePath) {
+ // 显示加载提示
+ final android.app.AlertDialog loadingDialog = new android.app.AlertDialog.Builder(this)
+ .setTitle("Loading")
+ .setMessage("Extracting image content...")
+ .setCancelable(false)
+ .create();
+ loadingDialog.show();
+
+ // 加载图片
+ ImageHelper imageHelper = new ImageHelper(this);
+ final Bitmap bitmap = imageHelper.loadImage(imagePath);
+
+ if (bitmap == null) {
+ loadingDialog.dismiss();
+ showToast(R.string.error_failed_to_load_image);
+ return;
+ }
+
+ // 调用AI服务提取图片内容
+ net.micode.notes.tool.AIService.extractImageContent(bitmap, new net.micode.notes.tool.AIService.ExtractImageContentCallback() {
+ @Override
+ public void onSuccess(final String extractedContent) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ loadingDialog.dismiss();
+
+ // 显示提取结果对话框
+ new android.app.AlertDialog.Builder(NoteEditActivity.this)
+ .setTitle(R.string.dialog_title_extracted_content)
+ .setMessage(extractedContent)
+ .setPositiveButton(R.string.dialog_button_insert, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // 将提取的内容插入到笔记中
+ int cursorPosition = mNoteEditor.getSelectionStart();
+ Editable editable = mNoteEditor.getEditableText();
+ editable.insert(cursorPosition, "\n" + extractedContent + "\n");
+ mNoteEditor.setSelection(cursorPosition + extractedContent.length() + 2);
+
+ // 更新WorkingNote的内容
+ getWorkingText();
+ updateWordCount();
+
+ showToast(R.string.info_content_inserted);
+ }
+ })
+ .setNegativeButton(R.string.dialog_button_cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ })
+ .show();
+ }
+ });
+ }
+
+ @Override
+ public void onFailure(final String errorMessage) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ loadingDialog.dismiss();
+ showToast(R.string.error_extract_image_content_failed);
+ Log.e(TAG, "Extract image content failed: " + errorMessage);
+ }
+ });
+ }
+ });
+ }
}
diff --git a/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/main/java/net/micode/notes/ui/NotesListActivity.java
index 64dfc2f..b04a6fb 100644
--- a/src/main/java/net/micode/notes/ui/NotesListActivity.java
+++ b/src/main/java/net/micode/notes/ui/NotesListActivity.java
@@ -112,10 +112,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
// 背景选项
private static final String[] BACKGROUND_OPTIONS = {
- "高山流水", "风中树叶", "长河落日"
+ "高山流水", "风中树叶", "长河落日"
};
private static final int[] BACKGROUND_RESOURCES = {
- R.drawable.background_mountain, R.drawable.background_leaves, R.drawable.background_sunset
+ R.drawable.background_mountain, R.drawable.background_leaves, R.drawable.background_sunset
};
private ListEditState mState;
@@ -180,7 +180,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
-
+
// 获取隐私空间ID
Intent intent = getIntent();
if (intent != null) {
@@ -189,7 +189,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mCurrentPrivacySpaceId = "";
}
}
-
+
initResources();
initBackground();
@@ -394,7 +394,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
mState = ListEditState.NOTE_LIST;
mModeCallBack = new ModeCallback();
-
+
// 检查是否处于隐私空间中
updatePrivacySpaceUI();
@@ -1016,7 +1016,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
startAsyncNotesListQuery();
}
}
-
+
/**
* 更新隐私空间相关的UI元素
*/
@@ -1613,14 +1613,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
mCurrentBackgroundType = sp.getString(PREFERENCE_BACKGROUND + "_type", BACKGROUND_TYPE_DEFAULT);
mCurrentBackgroundPath = sp.getString(PREFERENCE_BACKGROUND + "_path", "");
-
+
if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) {
int backgroundIndex = sp.getInt(PREFERENCE_BACKGROUND + "_index", 0);
if (backgroundIndex >= 0 && backgroundIndex < BACKGROUND_RESOURCES.length) {
mCurrentBackgroundResource = BACKGROUND_RESOURCES[backgroundIndex];
}
}
-
+
// 更新背景
updateBackground();
}
@@ -1632,7 +1632,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
if (mBackgroundContainer == null) {
return;
}
-
+
try {
if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) {
// 使用默认背景
@@ -1648,16 +1648,16 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
-
+
// 缩放图片以适配屏幕
android.graphics.Bitmap scaledBitmap = android.graphics.Bitmap.createScaledBitmap(
bitmap, screenWidth, screenHeight, true);
-
+
android.graphics.drawable.BitmapDrawable drawable = new android.graphics.drawable.BitmapDrawable(getResources(), scaledBitmap);
// 设置背景图片的缩放方式
drawable.setTileModeXY(android.graphics.Shader.TileMode.CLAMP, android.graphics.Shader.TileMode.CLAMP);
mBackgroundContainer.setBackground(drawable);
-
+
// 释放原始 bitmap
if (bitmap != scaledBitmap) {
bitmap.recycle();
@@ -1685,7 +1685,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
SharedPreferences.Editor editor = sp.edit();
editor.putString(PREFERENCE_BACKGROUND + "_type", mCurrentBackgroundType);
editor.putString(PREFERENCE_BACKGROUND + "_path", mCurrentBackgroundPath);
-
+
if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) {
// 找到当前背景资源的索引
int index = 0;
@@ -1697,7 +1697,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
editor.putInt(PREFERENCE_BACKGROUND + "_index", index);
}
-
+
editor.apply();
}
@@ -1707,12 +1707,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private void showBackgroundSelectorDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("选择背景");
-
+
// 创建背景选项数组,添加从相册选择的选项
String[] options = new String[BACKGROUND_OPTIONS.length + 1];
System.arraycopy(BACKGROUND_OPTIONS, 0, options, 0, BACKGROUND_OPTIONS.length);
options[BACKGROUND_OPTIONS.length] = "从相册选择";
-
+
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
@@ -1733,7 +1733,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
});
-
+
builder.show();
}
diff --git a/src/main/res/layout/note_edit.xml b/src/main/res/layout/note_edit.xml
index b529e4d..849137d 100644
--- a/src/main/res/layout/note_edit.xml
+++ b/src/main/res/layout/note_edit.xml
@@ -94,6 +94,16 @@
android:background="@drawable/bg_btn_insert_image"
android:contentDescription="@string/menu_insert_image"
android:padding="12dp" />
+
Word count large
Word count too large
+
+ No image found in the note
+ Loading
+ Extracting image content...
+ Failed to load image
+ Extracted Content
+ Insert
+ Cancel
+ Content inserted successfully
+ Failed to extract image content
+