From 11acb4565288578ec3071c958d4b708953f9e2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E5=BD=A6=E5=8D=9A?= <1139346339@qq.com> Date: Mon, 15 Jan 2024 15:14:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E5=9B=BE=E7=89=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/泛读分析和维护报告.docx | Bin 432108 -> 435386 bytes .../net/micode/notes/gtask/data/SqlData.java | 26 +-- .../net/micode/notes/gtask/data/SqlNote.java | 26 ++- .../net/micode/notes/gtask/data/Task.java | 28 +-- .../net/micode/notes/gtask/data/TaskList.java | 34 +-- .../net/micode/notes/ui/NoteEditActivity.java | 208 +++++++++++++++++- src/main/res/layout/note_edit.xml | 9 + 7 files changed, 274 insertions(+), 57 deletions(-) diff --git a/doc/泛读分析和维护报告.docx b/doc/泛读分析和维护报告.docx index 855973454c92d4a3e99bcf80e83d6d38f28b705c..ef788e553c89c71ef4d70971fd0d43bfb483385e 100644 GIT binary patch delta 23740 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 OK!JF`t6bnqxBmrVBii)< delta 20478 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%0AJd>RL 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 jNUE6Fg-V7DiUD 0) { int result = 0; - if (!validateVersion) { + if (!validateVersion) { // 不验证版本的情况下,直接使用ContentResolver更新指定ID的数据 result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); - } else { + } else { // 需要验证版本的情况下,使用ContentResolver进行条件更新操作 result = mContentResolver.update(ContentUris.withAppendedId( - Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE + " WHERE " + NoteColumns.VERSION + "=?)", new String[] { String.valueOf(noteId), String.valueOf(version) diff --git a/src/main/java/net/micode/notes/gtask/data/SqlNote.java b/src/main/java/net/micode/notes/gtask/data/SqlNote.java index 79a4095..48891a6 100644 --- a/src/main/java/net/micode/notes/gtask/data/SqlNote.java +++ b/src/main/java/net/micode/notes/gtask/data/SqlNote.java @@ -122,7 +122,7 @@ public class SqlNote { private ArrayList mDataList; - public SqlNote(Context context) { + public SqlNote(Context context) {//定义数据单元存储数据 mContext = context; mContentResolver = context.getContentResolver(); mIsCreate = true; @@ -135,7 +135,7 @@ public class SqlNote { mParentId = 0; mSnippet = ""; mType = Notes.TYPE_NOTE; - mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; + mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;//直接从设置的属性中获取值 mWidgetType = Notes.TYPE_WIDGET_INVALIDE; mOriginParent = 0; mVersion = 0; @@ -147,14 +147,14 @@ public class SqlNote { mContext = context; mContentResolver = context.getContentResolver(); mIsCreate = false; - loadFromCursor(c); + loadFromCursor(c);//从cursor中直接获取变量值 mDataList = new ArrayList(); if (mType == Notes.TYPE_NOTE) loadDataContent(); mDiffNoteValues = new ContentValues(); } - public SqlNote(Context context, long id) { + public SqlNote(Context context, long id) {//根据id初始化数据单元 mContext = context; mContentResolver = context.getContentResolver(); mIsCreate = false; @@ -175,7 +175,7 @@ public class SqlNote { }, null); if (c != null) { c.moveToNext(); - loadFromCursor(c); + loadFromCursor(c);//通过调用减少重复代码编写 } else { Log.w(TAG, "loadFromCursor: cursor = null"); } @@ -185,7 +185,7 @@ public class SqlNote { } } - private void loadFromCursor(Cursor c) { + private void loadFromCursor(Cursor c) {//直接使用get获得变量值 mId = c.getLong(ID_COLUMN); mAlertDate = c.getLong(ALERTED_DATE_COLUMN); mBgColorId = c.getInt(BG_COLOR_ID_COLUMN); @@ -200,7 +200,7 @@ public class SqlNote { mVersion = c.getLong(VERSION_COLUMN); } - private void loadDataContent() { + private void loadDataContent() {//这个函数判别查询的数据是否存在,并且读取到数据列表中存储 Cursor c = null; mDataList.clear(); try { @@ -210,12 +210,12 @@ public class SqlNote { }, null); if (c != null) { if (c.getCount() == 0) { - Log.w(TAG, "it seems that the note has not data"); + Log.w(TAG, "it seems that the note has not data");//遇到文件为空抛出对应的异常 return; } while (c.moveToNext()) { SqlData data = new SqlData(mContext, c); - mDataList.add(data); + mDataList.add(data);//向Datalist中加入读取到的数据 } } else { Log.w(TAG, "loadDataContent: cursor = null"); @@ -226,7 +226,8 @@ public class SqlNote { } } - public boolean setContent(JSONObject js) { + public boolean setContent(JSONObject js) {//设置数据单元中变量的值 + //如果所需的值存在,直接赋值使用,否则再先进行一步读取 try { JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { @@ -359,7 +360,7 @@ public class SqlNote { return true; } - public JSONObject getContent() { + public JSONObject getContent() {//直接读取的方式将所需的数据读到对应变量 try { JSONObject js = new JSONObject(); @@ -412,6 +413,7 @@ public class SqlNote { mDiffNoteValues.put(NoteColumns.PARENT_ID, id); } + //定义一些简单的获取取值的方法 public void setGtaskId(String gid) { mDiffNoteValues.put(NoteColumns.GTASK_ID, gid); } @@ -440,7 +442,7 @@ public class SqlNote { return mType == Notes.TYPE_NOTE; } - public void commit(boolean validateVersion) { + public void commit(boolean validateVersion) {//将数据做一定修改提交 if (mIsCreate) { if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) { mDiffNoteValues.remove(NoteColumns.ID); diff --git a/src/main/java/net/micode/notes/gtask/data/Task.java b/src/main/java/net/micode/notes/gtask/data/Task.java index 6a19454..4d68293 100644 --- a/src/main/java/net/micode/notes/gtask/data/Task.java +++ b/src/main/java/net/micode/notes/gtask/data/Task.java @@ -32,7 +32,7 @@ import org.json.JSONException; import org.json.JSONObject; -public class Task extends Node { +public class Task extends Node {//继承Node类的属性 private static final String TAG = Task.class.getSimpleName(); private boolean mCompleted; @@ -54,7 +54,7 @@ public class Task extends Node { mMetaInfo = null; } - public JSONObject getCreateAction(int actionId) { + public JSONObject getCreateAction(int actionId) {//创建一个初始的任务对象,并对它赋初值 JSONObject js = new JSONObject(); try { @@ -103,7 +103,7 @@ public class Task extends Node { return js; } - public JSONObject getUpdateAction(int actionId) { + public JSONObject getUpdateAction(int actionId) {//更新任务 JSONObject js = new JSONObject(); try { @@ -120,7 +120,7 @@ public class Task extends Node { // entity_delta JSONObject entity = new JSONObject(); entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); - if (getNotes() != null) { + if (getNotes() != null) {//如果笔记不为空,更新笔记 entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); } entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); @@ -135,11 +135,11 @@ public class Task extends Node { return js; } - public void setContentByRemoteJSON(JSONObject js) { + public void setContentByRemoteJSON(JSONObject js) {//通过远端的json设置内容的值 if (js != null) { try { // id - if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { + if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {//如果值已经被json对象所具备,则直接进行设置 setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); } @@ -175,7 +175,7 @@ public class Task extends Node { } } - public void setContentByLocalJSON(JSONObject js) { + public void setContentByLocalJSON(JSONObject js) {//通过本地的json文件来设置内容 if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE) || !js.has(GTaskStringUtils.META_HEAD_DATA)) { Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); @@ -204,7 +204,7 @@ public class Task extends Node { } } - public JSONObject getLocalJSONFromContent() { + public JSONObject getLocalJSONFromContent() {//通过本地的内容,生成json文件 String name = getName(); try { if (mMetaInfo == null) { @@ -216,7 +216,7 @@ public class Task extends Node { JSONObject js = new JSONObject(); JSONObject note = new JSONObject(); - JSONArray dataArray = new JSONArray(); + JSONArray dataArray = new JSONArray();//声明所有所要用到的变量 JSONObject data = new JSONObject(); data.put(DataColumns.CONTENT, name); dataArray.put(data); @@ -227,7 +227,7 @@ public class Task extends Node { } else { // synced task JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); - JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA); + JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);//提取出所有的信息 for (int i = 0; i < dataArray.length(); i++) { JSONObject data = dataArray.getJSONObject(i); @@ -258,11 +258,11 @@ public class Task extends Node { } } - public int getSyncAction(Cursor c) { + public int getSyncAction(Cursor c) {//同步缓存 try { JSONObject noteInfo = null; if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) { - noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);//更新到最新的笔记信息 } if (noteInfo == null) { @@ -311,14 +311,14 @@ public class Task extends Node { return SYNC_ACTION_ERROR; } - public boolean isWorthSaving() { + public boolean isWorthSaving() {//只要有信息就认为是值得保存的,返回true return mMetaInfo != null || (getName() != null && getName().trim().length() > 0) || (getNotes() != null && getNotes().trim().length() > 0); } public void setCompleted(boolean completed) { this.mCompleted = completed; - } + }//进行前面使用过的调用函数返回值的对应 public void setNotes(String notes) { this.mNotes = notes; diff --git a/src/main/java/net/micode/notes/gtask/data/TaskList.java b/src/main/java/net/micode/notes/gtask/data/TaskList.java index 4ea21c5..95d6bf5 100644 --- a/src/main/java/net/micode/notes/gtask/data/TaskList.java +++ b/src/main/java/net/micode/notes/gtask/data/TaskList.java @@ -30,17 +30,17 @@ import org.json.JSONObject; import java.util.ArrayList; -public class TaskList extends Node { +public class TaskList extends Node {//同Task一样,继承了Node private static final String TAG = TaskList.class.getSimpleName(); private int mIndex; - private ArrayList mChildren; + private ArrayList mChildren;//内部含有一个Task的列,是任务的序列 public TaskList() { super(); mChildren = new ArrayList(); - mIndex = 1; + mIndex = 1;//初始化 } public JSONObject getCreateAction(int actionId) { @@ -74,7 +74,7 @@ public class TaskList extends Node { return js; } - public JSONObject getUpdateAction(int actionId) { + public JSONObject getUpdateAction(int actionId) {//更新行动与Task中定义的基本一样 JSONObject js = new JSONObject(); try { @@ -104,7 +104,7 @@ public class TaskList extends Node { } public void setContentByRemoteJSON(JSONObject js) { - if (js != null) { + if (js != null) {//类似的通过远端更新内容 try { // id if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { @@ -129,7 +129,7 @@ public class TaskList extends Node { } } - public void setContentByLocalJSON(JSONObject js) { + public void setContentByLocalJSON(JSONObject js) {//通过本地文件更新内容 if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); } @@ -215,26 +215,26 @@ public class TaskList extends Node { return SYNC_ACTION_ERROR; } - +//以上都与task定义类似 public int getChildTaskCount() { return mChildren.size(); } public boolean addChildTask(Task task) { boolean ret = false; - if (task != null && !mChildren.contains(task)) { + if (task != null && !mChildren.contains(task)) {//任务不为空,并且还不在列表中,则将其加入 ret = mChildren.add(task); - if (ret) { + if (ret) {//成功加入以后继续设置关系 // need to set prior sibling and parent task.setPriorSibling(mChildren.isEmpty() ? null : mChildren .get(mChildren.size() - 1)); - task.setParent(this); + task.setParent(this);//设置任务的父子关系 } } return ret; } - public boolean addChildTask(Task task, int index) { + public boolean addChildTask(Task task, int index) {//更进一步的实现在指定索引位置插入任务 if (index < 0 || index > mChildren.size()) { Log.e(TAG, "add child task: invalid index"); return false; @@ -260,9 +260,9 @@ public class TaskList extends Node { return true; } - public boolean removeChildTask(Task task) { + public boolean removeChildTask(Task task) {//移除子任务 boolean ret = false; - int index = mChildren.indexOf(task); + int index = mChildren.indexOf(task);//查找其索引 if (index != -1) { ret = mChildren.remove(task); @@ -281,7 +281,7 @@ public class TaskList extends Node { return ret; } - public boolean moveChildTask(Task task, int index) { + public boolean moveChildTask(Task task, int index) {//定向移除对应位置的任务 if (index < 0 || index >= mChildren.size()) { Log.e(TAG, "move child task: invalid index"); @@ -299,7 +299,7 @@ public class TaskList extends Node { return (removeChildTask(task) && addChildTask(task, index)); } - public Task findChildTaskByGid(String gid) { + public Task findChildTaskByGid(String gid) {//通过Gid查找任务 for (int i = 0; i < mChildren.size(); i++) { Task t = mChildren.get(i); if (t.getGid().equals(gid)) { @@ -309,7 +309,7 @@ public class TaskList extends Node { return null; } - public int getChildTaskIndex(Task task) { + public int getChildTaskIndex(Task task) {//获取任务对应的索引 return mChildren.indexOf(task); } @@ -323,7 +323,7 @@ public class TaskList extends Node { public Task getChilTaskByGid(String gid) { for (Task task : mChildren) { - if (task.getGid().equals(gid)) + if (task.getGid().equals(gid))//找到一个gid相符的即为所要的任务 return task; } return null; diff --git a/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 9738ffd..20d6f41 100644 --- a/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -22,19 +22,34 @@ 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.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 +58,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 +82,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; @@ -159,6 +177,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, private String mUserQuery; // 用户输入的查询字符串 private Pattern mPattern; // 用于匹配用户查询的正则表达式模式对象 + private final int PHOTO_REQUEST = 1;//请求码 /** * @classname: NoteEditActivity @@ -178,8 +197,22 @@ 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 add image button"); + //允许用户插入特殊类型的数据 + Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT); + 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 @@ -331,6 +364,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker * is not ready */ + //插入之后初始化 + convertToImage(); showAlertHeader(); } /** @@ -961,6 +996,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery)); mEditTextList.setVisibility(View.GONE); mNoteEditor.setVisibility(View.VISIBLE); + convertToImage(); } } /** @@ -1059,4 +1095,174 @@ public class NoteEditActivity extends Activity implements OnClickListener, private void showToast(int resId, int duration) { Toast.makeText(this, resId, duration).show(); } + //路径字符串格式 转换为 图片image格式 + private void convertToImage() { + NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view); //获取当前的edit + Editable editable = noteEditText.getText();//1.获取text + String noteText = editable.toString(); //2.将note内容转换为字符串 + int length = editable.length(); //内容的长度 + //3.截取img片段 [local]+uri+[local],提取uri + for(int i = 0; i < length; i++) { + for(int j = i; j < length; j++) { + String img_fragment = noteText.substring(i, j+1); //img_fragment:关于图片路径的片段 + 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; + Log.d(TAG, "图片的路径是:"+path); + try { + bitmap = BitmapFactory.decodeFile(path);//将图片路径解码为图片格式 + } catch (Exception e) { + e.printStackTrace(); + } + if(bitmap!=null){ //若图片存在 + Log.d(TAG, "图片不为null"); + ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap); + //4.创建一个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); //6.删掉图片路径的文字 + edit_text.insert(i, spannableString); //7.在路径的起始位置插入图片 + } + } + } + } + } + + //重写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(); //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; + } + } + + //获取文件的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 isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + } diff --git a/src/main/res/layout/note_edit.xml b/src/main/res/layout/note_edit.xml index 10b2aa7..eca025e 100644 --- a/src/main/res/layout/note_edit.xml +++ b/src/main/res/layout/note_edit.xml @@ -395,6 +395,15 @@ android:layout_marginRight="6dip" android:layout_marginBottom="-7dip" android:src="@drawable/selected" /> + +