本文主要介绍在小米便签APP原有功能的基础上,设计并实现了便签添加图片的功能,从开发过程、运行界面、源代码三个方面进行详细介绍。
本文引用小米便签社区开源版代码:https://github.com/MiCode/Notes
小米便签APP维护开发完整源代码地址:https://download.csdn.net/download/weixin_47936614/85436044
开发工具:Android Studio
开发环境:操作系统win10、jdk1.8.0
目录
- 一、开发过程
- 二、运行界面
- 三、源代码
一、开发过程
- 首先在note_edit.xml文件中添加add_img_btn按钮;
- 在NoteEditActivity.java文件的onCreate()方法中,为这个“添加图片”按钮设置监听器,点击添加图片按钮时,会触发点击事件;
- 重写onActivityResult()来处理返回的数据,并将图片的路径也写入到数据库;
- 点击一个note后,会初始化note的内容,并通过convertToImage()将路径转化为图片;
- 在退出清单模式之后,仍应该将图片路径的位置替换为图片。
在编辑便签界面添加图片功能的程序流程图如图1所示。
二、运行界面
在便签编辑界面中,点击“添加图片”按钮,选择相应的图片,插入到便签中,插入图片过程如图2所示。
在插入图片后可以继续编辑便签,输入相应的文字或图片,保存便签后退出。当用户再次查看便签时,图片和文字在相应的位置展示出来,如图3所示。
用户在编辑便签界面选择“进入清单模式”,便签进入清单模式,图片以路径方式显示,当用户选择“退出清单模式”后,图片将在相应位置显示出来。如图4所示。
三、源代码
- 添加图片按钮的xml代码(FilePath: MiNotes\app\src\main\res\layout\note_edit.xml)
<ImageButtonandroid:id="@+id/add_img_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="7dp"android:layout_marginTop="600dp"android:layout_marginBottom="7dp"android:src="@android:drawable/ic_menu_gallery" />
- onCreate()方法(FilePath: MiNotes\app\src\main\java\net\micode\notes\ui\NoteEditActivity.java)
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.note_edit);if (savedInstanceState == null && !initActivityState(getIntent())) {finish();return;}initResources();//根据id获取添加图片按钮final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);//为点击图片按钮设置监听器add_img_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Log.d(TAG, "onClick: click add image button");//ACTION_GET_CONTENT: 允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT);//Category属性用于指定当前动作(Action)被执行的环境.//CATEGORY_OPENABLE; 用来指示一个ACTION_GET_CONTENT的intentloadImage.addCategory(Intent.CATEGORY_OPENABLE);loadImage.setType("image/*");startActivityForResult(loadImage, PHOTO_REQUEST);}});
}
- convertToImage()方法(FilePath: MiNotes\app\src\main\java\net\micode\notes\ui\NoteEditActivity.java)
//路径字符串格式 转换为 图片image格式
private void convertToImage() {NoteEditText noteEditText = (NoteEditText) findViewById(R.id.note_edit_view); //获取当前的editEditable editable = noteEditText.getText();//1.获取textString noteText = editable.toString(); //2.将note内容转换为字符串int length = editable.length(); //内容的长度//3.截取img片段 [local]+uri+[local],提取urifor(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个字符就是pathString 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()方法(FilePath: MiNotes\app\src\main\java\net\micode\notes\ui\NoteEditActivity.java)
//重写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;}
}
- getPath()方法(FilePath: MiNotes\app\src\main\java\net\micode\notes\ui\NoteEditActivity.java)
//获取文件的real path
public String getPath(final Context context, final Uri uri) {final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;// DocumentProviderif (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
// elseif (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);}}// Mediaelse if ("content".equalsIgnoreCase(uri.getScheme())) {return getDataColumn(context, uri, null, null);}// Fileelse if ("file".equalsIgnoreCase(uri.getScheme())) {return uri.getPath();}return null;
}
小米便签APP维护开发完整源代码地址:https://download.csdn.net/download/weixin_47936614/85436044