admin管理员组

文章数量:1540632

本文主要介绍在小米便签APP原有功能的基础上,设计并实现了便签添加图片的功能,从开发过程、运行界面、源代码三个方面进行详细介绍。
本文引用小米便签社区开源版代码:https://github/MiCode/Notes
小米便签APP维护开发完整源代码地址:https://download.csdn/download/weixin_47936614/85436044

开发工具:Android Studio
开发环境:操作系统win10、jdk1.8.0

目录

    • 一、开发过程
    • 二、运行界面
    • 三、源代码


一、开发过程

  1. 首先在note_edit.xml文件中添加add_img_btn按钮;
  2. 在NoteEditActivity.java文件的onCreate()方法中,为这个“添加图片”按钮设置监听器,点击添加图片按钮时,会触发点击事件;
  3. 重写onActivityResult()来处理返回的数据,并将图片的路径也写入到数据库;
  4. 点击一个note后,会初始化note的内容,并通过convertToImage()将路径转化为图片;
  5. 在退出清单模式之后,仍应该将图片路径的位置替换为图片。

在编辑便签界面添加图片功能的程序流程图如图1所示。

二、运行界面

在便签编辑界面中,点击“添加图片”按钮,选择相应的图片,插入到便签中,插入图片过程如图2所示。

在插入图片后可以继续编辑便签,输入相应的文字或图片,保存便签后退出。当用户再次查看便签时,图片和文字在相应的位置展示出来,如图3所示。

用户在编辑便签界面选择“进入清单模式”,便签进入清单模式,图片以路径方式显示,当用户选择“退出清单模式”后,图片将在相应位置显示出来。如图4所示。


三、源代码

  • 添加图片按钮的xml代码(FilePath: MiNotes\app\src\main\res\layout\note_edit.xml)
<ImageButton
        android: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() {
		@Override
		public 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的intent
			loadImage.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); //获取当前的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()方法(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;

    // 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;
}

小米便签APP维护开发完整源代码地址:https://download.csdn/download/weixin_47936614/85436044

本文标签: 便签小米软件app