【软件应用开发】小米便签APP维护开发

这篇具有很好参考价值的文章主要介绍了【软件应用开发】小米便签APP维护开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍在小米便签APP原有功能的基础上,设计并实现了便签添加图片的功能,从开发过程、运行界面、源代码三个方面进行详细介绍。
本文引用小米便签社区开源版代码:https://github.com/MiCode/Notes
小米便签APP维护开发完整源代码地址:https://download.csdn.net/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所示。
【软件应用开发】小米便签APP维护开发

二、运行界面

在便签编辑界面中,点击“添加图片”按钮,选择相应的图片,插入到便签中,插入图片过程如图2所示。
【软件应用开发】小米便签APP维护开发【软件应用开发】小米便签APP维护开发【软件应用开发】小米便签APP维护开发
在插入图片后可以继续编辑便签,输入相应的文字或图片,保存便签后退出。当用户再次查看便签时,图片和文字在相应的位置展示出来,如图3所示。
【软件应用开发】小米便签APP维护开发【软件应用开发】小米便签APP维护开发
用户在编辑便签界面选择“进入清单模式”,便签进入清单模式,图片以路径方式显示,当用户选择“退出清单模式”后,图片将在相应位置显示出来。如图4所示。
【软件应用开发】小米便签APP维护开发
【软件应用开发】小米便签APP维护开发
【软件应用开发】小米便签APP维护开发

三、源代码

  • 添加图片按钮的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.net/download/weixin_47936614/85436044文章来源地址https://www.toymoban.com/news/detail-431913.html

到了这里,关于【软件应用开发】小米便签APP维护开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 平台应用软件开发(学习中)

    1,LinearLayout(线性布局),RelativeLayout(相对布局),FrameLayout(帧布局),AbsoluteLayout(绝对布局),TableLayout(表格布局)。 2,线性布局中的控件属性说明 ①android:background,设置UI控件的背景,其值可以是资源文件夹中的图片或者是颜色的十六进制值。 ②android:orientation,该属性是线性布局

    2024年02月04日
    浏览(31)
  • 系统分析师---论软件开发模型及应用

    论题:论软件开发模型及应用 软件开发模型(Software Development Model)是指软件开发全部过程、活动和任务的结构框架。软件开发过程包括需求、设计、编码和测试等阶段,有时也包括维护阶段。软件开发模型能清晰、直观地表达软件开发全过程,明确规定了要完成的主要任务

    2024年02月04日
    浏览(31)
  • 如何应用项目管理软件进行敏捷开发管理

    敏捷开发(Agile Development)是一种软件开发方法论,强调在不断变化的需求和环境下,通过迭代、协作和自适应的方式来开发软件。敏捷方法的目标是提供更快、更灵活、更高质量的软件交付,以满足客户需求并实现项目成功。 在技术研发团队使用敏捷开发来完成一个迭代时

    2024年02月12日
    浏览(35)
  • 区块链技术在软件开发中的应用

    如果你是一名软件开发者或者IT从业者,你一定已经听说过区块链技术。区块链是一种基于密码学的分布式账本技术,被广泛应用于数字货币、金融、物联网等领域。但是,除了这些领域之外,区块链技术还可以在软件开发中发挥重要作用。本文将介绍区块链技术在软件开发

    2023年04月27日
    浏览(53)
  • 中文编程工具开发语言开发的实际案例:触摸屏点餐软件应用场景实例

    中文编程工具开发语言开发的实际案例:触摸屏点餐软件应用场景实例 软件特色: 1、功能实用,操作简单,不会电脑也会操作,软件免安装,已内置数据库。软件在关闭的时候,可以设置会员数据备份到U盘,数据本机备份一份,U盘备份一份,双重备份数据安全。 2、软件既

    2024年02月08日
    浏览(32)
  • 麦芯(MachCore)应用开发教程1 --- 设备软件中间件

    黄国强 2024/1/10 acloud@163.com         对任何公司来说,在短时间内开发一款高质量设备专用软件,是一件不太容易做到的事情。麦芯是笔者发明的一款设备软件中间件产品。麦芯致力于给设备厂商提供一个开发工具和平台,让客户快速高效的开发自己的设备专用软件。麦芯

    2024年01月25日
    浏览(31)
  • 【Android 逆向】程序员高危开发方向 ( 违法软件类型 | 赌博游戏 | 色情类应用 | 涉及金融类软件 | 爬虫类软件 | 区块链货币 | 甄别是否合法 )

    棋牌类 游戏开发 , 写这类游戏的程序员 很容易被抓 , 只要 涉及到了 充值 以及 提现 , 就是涉嫌赌博 ; 常见的 就是 麻将类游戏 , 纸牌类游戏 , 具体的地方麻将或扑克玩法 , 德州扑克 , 21 点 , 老虎机 等 类型的 游戏 ; 抽卡类的游戏 , 充值 然后 赌概率 , 比如原神这种 , 只充值

    2024年01月19日
    浏览(35)
  • 微服务:解放软件开发的神器,引领企业级应用的未来

    目录 1、什么是微服务? 1.1 微服务的定义 1.2 微服务架构的特点 2、微服务的优势 2.1 灵活性和可扩展性 2.2 模块化开发和部署 2.3 高可用性和容错性 2.4 技术栈的多样性 3、微服务的挑战 3.1 分布式系统的复杂性 3.2 服务之间的通信和协调 3.3 数据一致性和事务管理 3.4 性能监控

    2024年02月22日
    浏览(36)
  • 破局之作:首部开源 AIGC 软件工程应用电子书《构筑大语言模型应用:应用开发与架构设计》...

    TL;DR 版; 在线:https://aigc.phodal.com 下载 1:https://github.com/phodal/aigc/releases 下载 2:https://pan.baidu.com/s/1wGc75vVHaZwvZyHeltyt8w?pwd=phod 2023 年的上半年里,我(@phodal)和 Thoughtworks 的同事们(如:@tianweiliu、@teobler、@mutoe 等)、 开源社区的同伴们(如:卷王@CGQAQ、@genffy、 @liruifengv 等

    2024年02月15日
    浏览(35)
  • 基于ubuntu的STM32嵌入式软件开发(四)——应用软件工程的修改、Makefile及编译脚本的编写

            本文主要介绍基于标准库函数移植的STM32的应用软件工程的修改,主要涉及到文件内容修改、Makefile文件编写、编译脚本编写等内容,其中编译脚本是基于arm-none-eabi-gcc的交叉编译器撰写的。程序亲测可以正常编译,生成.bin和.hex的可烧录镜像文件。 1.首先修改 pr

    2023年04月15日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包