安卓记事本系统设计和模块实现

安卓记事本系统设计和模块实现

友情提示

记事本是我学习安卓后编写的第一个软件,也是我的毕业设计。它存在着许多不完善的地方,如果你有想法可以进一步去完善它。

我当时看的是郭霖《第一行代码》第2版入门的,现在已经出到第3版了,编程语言由Java改成了Kotlin,如果你有时间,也可以把我的项目从Java改成Kotlin编写。目前这两本书都可以在微信读书上面找到。

软件演示视频

代码地址

用到的关键技术

语音识别技术和语音合成技术

多功能记事本APP采用讯飞的语音识别引擎,相当于给软件加上了“耳朵”,让记事本能“听懂”用户的讲话。讯飞公司作为语音识别行业的佼佼者,它的输入法已经可以做到一分钟输入400字了,这极大地提升了用户的输入效率。此外,记事本还会采用安卓官方TextToSpeech类来实现语音合成,它使用的合成引擎取决于手机品牌,比如小米手机默认使用的是小爱语音引擎,谷歌的原生系统一般使用Pico TTS,但不支持中文,坚果手机采用的是讯飞合成引擎。

图片压缩和加载技术

云存储技术

随着移动互联 的发展,几乎所有的手机都提供了云服务,可以同步用户的图片、联系人等数据,其中涉及到的一项重要技术就是云存储技术,它将大量不同类型的存储设备通过软件集合起来协同工作,共同对外提供数据存储服务。本软件采用的服务商是坚果云,安卓客户端通过WebDav协议与其进行通讯,这个协议是基于HTTP的扩展,有利于用户对服务器端的文件进行读写操作。

Material Design

安卓刚刚发展的那几年,UI设计并不美观,远远不如当时的iOS系统美观。而且,由于安卓是一个开源系统,各个手机厂商在UI设计的规范并不相同,所以很多开发者干脆就把iOS上的设计搬到安卓上面来。后来,谷歌意识到了这个问题并在2014年的开发者大会上发布了一套全新的UI设计语言:Material Design,它是由Google的设计工程师们基于传统优秀的设计原则,结合丰富的创意和科学技术所开发的一套全新的界面设计语言,包含了视觉、运动、互动效果等特性。这种结合卡片化设计风格的语言,给用户带来了良好、美观和一致性的体验,从而统一了谷歌在UI设计上面的表达。目前,Material Design的支持库非常完善了,多功能记事本APP也将采用这一设计语言。

富文本技术

富文本技术的实现可以让记事本的内容不仅仅是一种单调的样式,还可以有其他丰富的样式,比如可以突出标题的显示,可以让重点的文字内容变红,可以显示图片等等。所以,富文本技术对多功能记事本APP至关重要。目前有几种方法来实现富文本:

  • 通过使用Html.fromHtml()来解析文本内容,然后显示在TextView中,但安卓原生的Html支持的样式较少,图片显示需要单独处理等等。

  • 通过ScrollView、多个EditText、多个ImageView等组件来拆分内容显示,由于是原生布局所以能实现的效果有很多,但是实现起来非常困难,需要处理输入焦点、组件之间的关系怎么安排等问题。

  • 通过使用安卓SpannableString类来实现,通过它的public void setSpan(Object what, int start, int end, int flags)方法可以设置多种样式,参数what代表所要设置的样式,参数start和end代表样式设置范围,参数flags是对新插入字符的处理方式。结合ClickableSpan类和ImageSpan类就可以实现点击事件和图片显示,使用非常方便,基本满足了多功能记事本APP对富文本的要求。

持久化技术

数据持久化技术作为软件的压舱石,是非常重要的,它可以在用户退出软件后保存用户所需要的数据。文件存储、数据库存储和SharedPreferences存储是安卓系统提供的三种数据持久化方法。文件存储可以直接把数据完全保存到文件里面去,适合存储一些简单的文本数据和二进制数据。所以,在多功能记事本APP中主要用来保存图片和语音资源。数据库存储在安卓系统中使用的主要是SQLite数据库,它作为平台系统的关系型数据库,具有占用内存、资源小等方面的优势,在平台APP开发中能够发挥重大作用。它完全内置于安卓操作系统,对存储结构性复杂的数据非常友好,运行速度也非常快。虽然安卓提供了SQLiteOpenHelper帮助类来实现数据库的增删改查各种操作,但是用起来还是没有那么方便。所以在记事本工程里引入LitePal这个开源的数据库框架,它采用的对象关系映射模式可以让创建数据表变得异常简单,并且封装了很多常用的数据库功能接口,让开发流程变得更加便捷和快速。SQLite数据库主要用来保存笔记和待办事项相关内容。SharedPreferences存储采用的是key-value的方式来存储数据,适合保存一些简单数据,操作起来非常方便。此外,SharedPreferences对象与SQLite数据库相比,免去了创建数据库、创建表、写SQL语句等诸多操作,相对而言更加方便,简洁。因此,在APP中主要用来保存用户偏好数据和账 密码。

系统设计

系统总体设计

系统层次结构

多功能记事本APP基于安卓手机操作系统开发,系统总体架构按照APP客户端-服务器端模式设计,架构设计如图所示。

控制层的主要职责就是处理各种逻辑业务,即接收并解析用户层的操作指令然后到模型层请求数据,得到数据后可以送到视图层进行显示。例如,当用户层请求语音输入时,控制层会负责调用讯飞相关接口,获取到语音数据后,通过 络连接到讯飞语音识别服务器,那边数据处理完成后,模型层就会把数据送到视图层进行展示。

系统各功能模块组成

多功能记事本APP主要分为九大模块:用户界面、输入模块、提醒模块等等。

提醒模块

提醒模块包括日历提醒和应用内语音提醒。日历提醒直接从应用打开日历设置提醒时间就行,并传递相关信息,这个由系统来保证时效性,一般不会有耽搁。应用内语音提醒采用AlarmManager组件来设置,到点之后采用TextToSpeech组件来进行语音播 ,同时通知栏会弹出具体消息。设置日历事件和应用内语音提醒过程如图所示。

数据同步

数据同步的云端服务器采用支持WebDav协议的坚果云。安卓客户端采用sardine-android开源框架,使多功能记事本APP支持WebDav协议,让本地客户端可以和支持WebDav协议的坚果云通信,从而支持同步数据。这样的好处就是开发者不必再另外开发服务器端程序,用户只需要到坚果云注册账 就行,数据由坚果云进行保管。具体数据同步过程如图所示。

管理模块

笔记和待办事项的管理,主要就是对数据库的增删改查,这里会用到开源框架LitePal来对数据库进行操作。对于笔记的分组功能,会在笔记的数据表里增加一个字段,用来判断当前笔记位于哪一个组。这里,主要分成未分组、生活、工作和回收站四个组,方便用户自主选择笔记的分类,同时还可以在笔记查看界面更改分组。由于待办事项是比较简单的文字记录,不提供任何分组。笔记的回收、恢复和更改分组过程如图所示。

权限申请模块

普通权限需要在AndroidManifest.xml添加权限声明,对于危险权限,除了添加声明外,还需要经过用户授权处理。具体授权过程如图所示。

侧边栏:依托用户主界面的DrawerLayout根布局,引入NavigationView组件,里面有两个重要参数app:headerLayoutapp:menu,前者引入的布局包含了用于显示坚果云品牌图片的开源组件CircleImageView、用于输入用户名和密码的两个EditText组件和用于登录坚果云的Button。后者引入的菜单包含了笔记的分组选项。侧边栏界面如图所示。

笔记的浏览界面:以CoordinatorLayout为根布局,主要包含了ToolbarFloatingActionButtonLinearLayout布局。FloatingActionButton提供更改笔记的入口,LinearLayout布局又包含了三方面内容,第一就是包含了用于显示笔记更改时间和提醒时间的两个TextViewLinearLayout布局,第二就是ContentLoadingProgressBar组件,显示笔记加载过程,第三就是包含了TextViewScrollView滚动组件。右上角是菜单选项,通过工程menu的文件夹新建菜单文件note_show_menu.xml来实现。笔记浏览界面如图所示。

输入模块

输入模块主要分为三个部分:语音输入、图片插入和文字输入。

语音输入:如图所示,当输入框获得焦点后,会显示输入选项,选择语音输入图标后会弹出语音录入界面,语音数据会实时上传到讯飞服务器进行识别,识别结果会显示在输入界面,用户说完话后,语音录入界面关闭并在输入框添加小喇叭图标。

软件上的实现过程:首先,使用讯飞识别引擎之前要在库文件中引入讯飞识别库,然后调用SpeechUtility.createUtility() 验证密钥。接下来通过自定义的XunFeiEngine类完成识别过程,提供的方法主要有设置语音识别参数的setParam(),打印结果方法printResult() 和构造函数XunFeiEngine()。先实例化XunFeiEngine类完成讯飞语音识别引擎的初始化,然后调用setParam() 方法完成参数设置,比如讯飞的听写引擎、语言区域、音频保存路径等等。接下来调用SpeechRecognizer类的startListening() 方法完成监听器设置,在监听器里面通过onVolumeChanged() 方法改变语音输入界面的动画效果;通过onBeginOfSpeech() 方法知道讯飞语音识别引擎已经准备好了,用户可以开始语音输入;通过onEndOfSpeech() 方法知道检测到了语音的尾端点,已经进入识别过程,不再接受语音输入;通过onResult() 方法获取识别结果并显示在输入界面;通过onError() 方法了解出错问题。

文字输入:文字的输入选项有三个:文字标题、文字标红和文字加粗,如果什么都不选,就会以正常文字输入。有两种用法:第一种就是先选择输入选项然后再输入文字,如第一张图所示。第二种就是以正常样式输入文字后再通过光标选择文字的样式,如图2所示。

软件实现:第一种用法实现方式,通过给Edittext设置TextWatcher监听器,在TextWatcherafterTextChanged() 方法里面根据输入选项通过setSpan() 方法完成样式设置。第二种用法实现方式,根据对应的输入选项,通过EditTextgetSelectionEnd()getSelectionStart() 方法获取文字光标范围,最后通过setSpan() 方法完成样式设置。其中 setSpan() 方法主要是给 Editable 设置不同的TextAppearanceSpan样式来达到富文本效果。

待办事项的数据直接把原始String内容送到Edittext显示即可。

提醒模块

应用内提醒:通过AlarmManager创建定时任务来实现。首先,系统要获取提醒时间,这里通过Android-PickerView开源库来实现。如图1所示,选择好提醒时间后点击确定,然后TimePickerView类的监听器就会执行onTimeSelect() 方法,在这个方法里面,首先要判断设置的提醒时间是否早于现在,如果是,则抛出提示:“设置的提醒时间不能早于现在”。如果不是,则打开一个服务AlarmService去创建定时任务,在打开服务之前,要传递三个重要意图,第一个是提醒时间,第二个是数据的唯一标识,第三个是种类,区分笔记和待办事项。打开AlarmService后,首先初始化TextToSpeech,为之后的语音提醒作准备。然后,实例化AlarmManager类,配置好定时到点后的触发任务AlarmIntentService,并传递数据唯一标识和种类。设置定时时间要用到PendingIntent类,并按照笔记和待办事项设置好唯一标识符,这个标识符对于取消提醒至关重要。最后调用AlarmManagersetExactAndAllowWhileIdle () 方法,设置好定时任务。当提醒时间到了,AlarmIntentService服务会被系统唤醒,在这里面的功能就是在通知栏显示通知并且语音播 提醒内容。通知显示后,可以通过通知栏进入笔记页面或者关闭语音播 。特别注意的是,当软件重新启动时,会开启一个线程重新设置没有过期的笔记定时任务。

日历提醒:通过系统提供的Calendar日历服务类打开日历,并传递提醒内容和时间,其他设置由系统的日历来提供。如图2所示。

搜索模块

无论是笔记界面还是待办事项界面都有搜索框。如图所示,当用户输入查找字符时,SearchView组件的监听器就会接收到指令,开始激活onQueryTextChange() 方法,然后在里面调用编写好的search() 方法,这个方法适用于查找笔记,即会从对应的组别中筛选出包含查找字符的笔记,然后把结果返回,最后刷新RecycleView显示。当点击搜索框的交叉符 时,代表退出查找,监听器会重新运行RecycleView刷新方法,继续显示组内笔记。

分享模块

发送文本内容:创建一个Intent并将其操作行为设置成Intent.ACTION_SEND,然后设置分享的数据类型为text/plain,调用putExtra() 方法把名为Intent.EXTRA_TEXT 的笔记内容放到Intent对象里面去,接着调用Intent.createChooser() 创建一个分享Intent,并向其传递前面那个Intent对象,最后调用**startActivity() **方法完成分享动作,如图1所示。

发送图片:在浏览图片框架MNImageBrowser里面设置图片的单击事件,之后的步骤基本和发送文本内容相同,但有两个地方不同,发送图片要设置分享的数据类型为image/jpeg,通过putExtra() 方法放到Intent里面去的是名字为Intent.EXTRA_STREAM的图片Uri数据,如图2所示。

数据库实现

数据库采用的是安卓原生支持的SQLite数据库,用LitePal开源框架对其进行操作。多功能记事本APP会维护两个数据库,一个是存储在内部存储器的note.db数据库文件,用于本地数据的保存,另外一个是存储在外部存储器的noteBackup.db数据库文件,用于坚果云同步。具体步骤如下所示:

(1) 包含库:首先在build.gradle文件添加LitePal的依赖项,这样LitePal开源框架就导入软件工程了。

(2) 配置litepal.xml:在项目的assets文件夹中创建一个文件litepal.xml, 在文件里面定义好数据库名字和版本 。

(3) 配置LitePal的上下文参数:在MyApplication类的onCreate() 函数里面调用LitePal.initialize(this) 完成初始化。

(4) 创建数据表:根据数据表字段建好NoteTodoMediaForNote数据类并在litepal.xml文件添加数据表的声明后,当程序操作数据库时,数据表在数据库中就会自动生成。到这里,数据库的建表操作就完成了。程序可以通过LitePal提供的接口完成数据库的增删改查。

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91537 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年5月17日
下一篇 2021年5月17日

相关推荐