From 4795df86e1c2d7dbf9acaf15de23decd57d08606 Mon Sep 17 00:00:00 2001 From: Zenglingyu <749043287@qq.com> Date: Thu, 8 Dec 2022 21:49:33 +0800 Subject: [PATCH] v --- app/build.gradle | 4 + app/src/main/AndroidManifest.xml | 4 +- .../net/micode/notes/model/WorkingNote.java | 2 +- .../net/micode/notes/ui/NoteEditActivity.java | 232 ++++++++++++++++-- .../micode/notes/ui/NotesListActivity.java | 3 +- app/src/main/res/layout/note_edit.xml | 8 + local.properties | 7 +- 7 files changed, 230 insertions(+), 30 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9790ab4..b037d8d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,3 +17,7 @@ android { } } } + +dependencies { + implementation 'com.android.support:appcompat-v7:28.0.0' +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e5c7d47..c9448ee 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -40,7 +40,7 @@ android:configChanges="keyboardHidden|orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTop" - android:theme="@style/NoteTheme" + android:theme="@style/Theme.AppCompat.Light.DarkActionBar" android:uiOptions="splitActionBarWhenNarrow" android:windowSoftInputMode="adjustPan" > @@ -54,7 +54,7 @@ android:name=".ui.NoteEditActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:launchMode="singleTop" - android:theme="@style/NoteTheme" > + android:theme="@style/Theme.AppCompat.Light.DarkActionBar" > diff --git a/app/src/main/java/net/micode/notes/model/WorkingNote.java b/app/src/main/java/net/micode/notes/model/WorkingNote.java index a92fd01..ef7f278 100644 --- a/app/src/main/java/net/micode/notes/model/WorkingNote.java +++ b/app/src/main/java/net/micode/notes/model/WorkingNote.java @@ -39,7 +39,7 @@ public class WorkingNote { // Note的Id private long mNoteId; // Note的目录 - private String mContent; + public String mContent; // Note的模式 private int mMode; //警告日期 diff --git a/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 96a9ff8..231c486 100644 --- a/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -22,19 +22,35 @@ import android.app.AlertDialog; import android.app.PendingIntent; import android.app.SearchManager; import android.appwidget.AppWidgetManager; +import android.content.ContentResolver; import android.content.ContentUris; +import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.preference.PreferenceManager; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.support.v7.app.AppCompatActivity; +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; @@ -43,10 +59,12 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; +import android.widget.Button; 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; @@ -65,6 +83,7 @@ import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener; import net.micode.notes.widget.NoteWidgetProvider_2x; import net.micode.notes.widget.NoteWidgetProvider_4x; +import java.io.FileNotFoundException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -72,7 +91,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; @@ -149,6 +168,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, private String mUserQuery; private Pattern mPattern; + private final int PHOTO_REQUEST = 1;//请求码 + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -159,12 +180,115 @@ public class NoteEditActivity extends Activity implements OnClickListener, return; } initResources(); + + //声明一个图片按钮, 并将布局中的图片加载到图片按钮中 + 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) { + //声明一个请求对象,设置参数ACTION_GET_CONTENT: 允许用户选择特殊种类的数据(照片),并返回 + Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT); + //Category属性用于指定一个用途,用于过滤 + loadImage.addCategory(Intent.CATEGORY_OPENABLE); + //指定获取的是图片 + loadImage.setType("image/*"); + //打开相册 + startActivityForResult(loadImage, PHOTO_REQUEST); + } + }); } - /** - * Current activity may be killed when the memory is low. Once it is killed, for another time - * user load this activity, we should restore the former state - */ + + @Override + //重写onActivityResult()来处理返回的数据, 并将图片插入便签中 + 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(); //获得图片的真实路径 + Bitmap bitmap = null; + try { + bitmap = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));//解码图片 + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + if(bitmap != null){ + //根据Bitmap对象创建ImageSpan对象 + ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap); + String path = getPath(this,originalUri); + Log.d(TAG, path); + //使用[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); + //将选择的图片追加到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(); + //修改数据库 + 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; + } + } + + + public String getPath(final Context context, final Uri uri) { + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // 媒体文件 + 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); + } + } + // 文本 + else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } + // 文件 + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + } + return null; + } + + @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); @@ -263,14 +387,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, } @Override - protected void onResume() { + protected void onResume() {//能获得用户焦点:可以操作 super.onResume(); - initNoteScreen(); + initNoteScreen();//初始化便签屏幕 } private void initNoteScreen() { - mNoteEditor.setTextAppearance(this, TextAppearanceResources - .getTexAppearanceResource(mFontSizeId)); + mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId)); if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { switchToListMode(mWorkingNote.getContent()); } else { @@ -288,13 +411,54 @@ public class NoteEditActivity extends Activity implements OnClickListener, | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)); - /** - * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker - * is not ready - */ showAlertHeader(); + //将有图片路径的位置转换为图片 + convertToImage(); } + //路径字符串格式 转换为 图片image格式 + private void convertToImage() { + NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view); //获取当前的编辑框 + Editable editable = noteEditText.getText();//获取便签中的全部文本 + String noteText = editable.toString(); //将获取的文本转换为字符串 + int length = editable.length(); //内容的长度 + // 获取文本路径(去掉最前面的[local]和最后面的[/local] + // 暴力搜索 + for(int i = 0; i < length; i++) { + for(int j = i; j < length; j++) { + String img_fragment = noteText.substring(i, j+1); //切割要检查的字符串 + //[local]/storage/emulated/0/Pictures/IMG_20221202_015334.jpg[/local] + 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;// 声明位图对象,获取图片路径所对应的图片 + try { + bitmap = BitmapFactory.decodeFile(path); + } catch (Exception e) { + e.printStackTrace(); + } + if(bitmap!=null){ + // 用ImageSpan实现图文并排的效果 + ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap); + // 用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); //删掉便签里面图片的路径文本 + edit_text.insert(i, spannableString); //插入文本 + } + } + } + } + } + + private void showAlertHeader() { if (mWorkingNote.hasClockAlert()) { long time = System.currentTimeMillis(); @@ -358,8 +522,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; } @@ -418,7 +582,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { - mWorkingNote.getWidgetId() + mWorkingNote.getWidgetId() }); sendBroadcast(intent); @@ -430,7 +594,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, if (id == R.id.btn_set_bg_color) { mNoteBgColorSelector.setVisibility(View.VISIBLE); findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( - - View.VISIBLE); + View.VISIBLE); } else if (sBgSelectorBtnsMap.containsKey(id)) { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.GONE); @@ -563,10 +727,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, d.show(); } - /** - * Share note to apps that support {@link Intent#ACTION_SEND} action - * and {@text/plain} type - */ private void sendTo(Context context, String info) { Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_TEXT, info); @@ -773,12 +933,12 @@ public class NoteEditActivity extends Activity implements OnClickListener, switchToListMode(mNoteEditor.getText().toString()); } else { if (!getWorkingText()) { - mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", - "")); + mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ", "")); } mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); mEditTextList.setVisibility(View.GONE); mNoteEditor.setVisibility(View.VISIBLE); + convertToImage(); //退出清单模式,应该将有图片的地方显示出来 } } @@ -870,4 +1030,30 @@ public class NoteEditActivity extends Activity implements OnClickListener, private void showToast(int resId, int duration) { Toast.makeText(this, resId, duration).show(); } + + + + //获取数据列_获取此 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 isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } } diff --git a/app/src/main/java/net/micode/notes/ui/NotesListActivity.java b/app/src/main/java/net/micode/notes/ui/NotesListActivity.java index e843aec..a7b9347 100644 --- a/app/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/app/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -59,6 +59,7 @@ import android.widget.ListView; import android.widget.PopupMenu; import android.widget.TextView; import android.widget.Toast; +import android.support.v7.app.AppCompatActivity; import net.micode.notes.R; import net.micode.notes.data.Notes; @@ -78,7 +79,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashSet; -public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { +public class NotesListActivity extends AppCompatActivity implements OnClickListener, OnItemLongClickListener { private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; private static final int FOLDER_LIST_QUERY_TOKEN = 1; diff --git a/app/src/main/res/layout/note_edit.xml b/app/src/main/res/layout/note_edit.xml index 10b2aa7..36f883a 100644 --- a/app/src/main/res/layout/note_edit.xml +++ b/app/src/main/res/layout/note_edit.xml @@ -397,4 +397,12 @@ android:src="@drawable/selected" /> + diff --git a/local.properties b/local.properties index 08295dc..ce81d26 100644 --- a/local.properties +++ b/local.properties @@ -2,6 +2,7 @@ # as it contains information specific to your local configuration. # # Location of the SDK. This is only used by Gradle. -# -#Tue Oct 04 16:23:14 CST 2022 -sdk.dir=D\:\\SDK +# For customization when using a Version Control System, please read the +# header note. +#Wed Nov 30 20:26:11 CST 2022 +sdk.dir=D\:\\Program Files\\Android\\Sdk