安卓应用程序开发
课程设计报告
(2019—2020学年 第一学期)
基于Android的记事本系统
系 别 信息与控制工程
专 业 计算机科学与技术
班 级 1702
姓 名 曲路平
指导教师 郭 丹
目录
1.设计目的
2.设计内容
3.可行性分析
4.系统设计与实现
4.1系统需求分析
4.2用例分析
4.3逻辑模型
4.4系统整体设计
4.5系统数据库设计
4.6系统测试
4.7系统实现
5.总结
1.设计目的
随着IT技术的成熟和智能手机的不断普及,移动应用的需求与日俱增,移动应用开发成为当下最热门的技术之一。而通过调查显示,大部分消费者都会使用手机记事本功能。随着手机记事本功能的不断加强与完善,手机记事本对于人们的意义,已不仅仅像一般记事簿一样简单记录,而是向着更个性化人性化的方向发展。记事本在生活和工作也日益凸显出它的重要性,它能更好的帮助人们更好的管理自己的工作和生活,极大的方便了人们的生活。因其开源,我们可以在之上开发安卓记事本软件,同时这也符合广大的市场需求。
2.设计内容
本设计的基本内容是在Android平台下,设计与实现记事本软件。具体实现的功能是:
(1) 设计实现添加“文字”,等功能模块。
(2) 进入后,有“保存”“退出”选择。
(3) 主页面显示记事列表,点击可查看及时内容,并有“删除”,“返回”等选择。
3.可行性分析
(1) 技术可行性——这个项目仅需要一台装有Eclipse及配置好Android开发环境的计算机即可,但是对计算机本身有要求.
(2) 经济可行性——由于本软件开发只有单个人,一台电脑就行,基本不需要太大的成本,在经济上完全可行。
(3) 操作可行性——界面设计时充分考虑用户的习惯以及手机方面的局限性,程序必须要很简单;本程序没有太大的难度,所以项目完全有可操作性。
4.系统设计与实现
4.1系统需求分析
该记事本软件是一种主要用来记录笔记的基于安卓平台的软件,可以运行在安卓平台模拟器或运行在安卓平台的手持设备上。
(1).用户触发事件
记事本与外部环境的交互。在这个系统中,通过对系统的分析,可以识别出参与者:用户。对于用户而言,记事本上按钮是用户向系统输入的操作请求的输入设备,设备显示器是用于向用户输出信息的输出设备。
(2).系统的功能性需求
设计实现“添加文本”,“编辑内容/标题”和“删除记事”等功能。
事件类别的管理(包括增加、删除、修改);
事件的管理(包括增加、删除、修改),关键信息包括:事件标题、事件内容、信息。
(3).软件环境需求
软件平台:Android2.0以上
4.2用例分析
系统用例图描述的是用户眼中的系统,即用户希望系统有哪些功能。一个用例代表用户与系统交互的一种方式。而识别用例最好方法是从参与者的角度分析系统。在Android记事本中,首先的参与者是用户。如图,它从用户角度描述了该系统应该具有何种功能。
4.3逻辑模型
常规的Android手机记事本软件主要功能模块包括;记事,查看,编辑修改,删除记事。如图:
Android记事本软件:
这次课题的目的是在Android系统的手机平台之上,研究与开发一个记事本软件,提供适应手机的记事本功能服务,其中包括以下几个功能:
(1)可以实现基本的文本功能,如新建文本,删除修改文本,查看已有文件等。
(2)界面设计力求简洁,整个软件要尽量占用较少内存。
(3)可以进行日历查看。
4.4系统总体设计
进入程序,显示“精灵记事本”登录后,点击上面的新建按钮开始记录吧!
(1)界面设计
(2)处理流程设计
业务流程图:
用户进入手机记事本后,会看到所有记事列表页面。列表页面主菜单中包括添加、删除菜单项。点击添加,则进入添加页面,添加成功后返回列表页面,如图:
数据增加流程图:
添加记事时,数据由用户输入,点击确定按钮。如图:
数据修改流程图:
删除数据:
(3)系统概述
本记事本软件主要用于记录生活点滴的基于Android平台的软件,可以运行于基于Android平台的手持设备。
(4)系统总体结构
本作品实现的功能模块主要包括:添加、删除、修改事件,增加、删除.
4.5系统数据库设计
在记事本中软件中,记事作为主要操作对象。
4.6系统测试
为了提高本应用程序的质量,使应用程序的使用更加人性化,友好化,一个完整的软件测试是必不可少的。通过软件测试我们能够发现其中的一些错误和不合理的地方,这对于系统的完善是极有好处的。
(1)测试方案及测试用例
软件测试是对软件质量保证的关键步骤,它是在软件投入运行前,对软件的需求分析、软件规格说明和编码实现的最终审查。通过对软件的定义有俩种描述,第一软件测试是为了发现错误而必须执行的程序的过程;第二软件测试是根据软件设计开发各阶段的需求说明和程序的内部构造而精心设计的一些测试用例,并利用这些测试用例运行程序和及时发现错误的过程,即执行测试步骤。
按照软件测试用例的设计方法而论,软件测试可以分为白盒测试和黑盒测试法。按照软件测试的策略和过程分类,软件测试可分为单元测试、集成测试、系统测试、验证测试和确认测试。
(2)系统测试计划
在系统的开发和设计过程中,对系统做了如下几个方面的测试:
功能及正确性测试:对后台记录信息的增删改查等操作的测试。
及时正确的处理系统各种错误的异常。
(3)系统测试及测试结果
添加记录测试用例:
功能描述:验证添加记录信息功能。
用例目的:验证添加记录信息功能的实现。
前提条件:已经进入到添加记录信息的页面。
序号 |
输入 |
输出 |
实际情况 |
测试结果 |
1 |
输入标题和内容 |
记录成功在页面中显示 |
添加成功 |
正确 |
修改记录测试用例:
功能描述:验证修改记录信息功能。
用例目的:验证修改记录信息功能的实现。
前提条件:已经进入到修改记录信息的页面。
序号 |
输入 |
输出 |
实际情况 |
测试结果 |
1 |
输入标题和内容 |
记录成功在页面中显示 |
添加成功 |
正确 |
删除记录测试用例:
功能描述:验证删除记录信息功能。
用例目的:验证删除记录信息功能的实现。
前提条件:已经进入到删除记录信息的页面。
序号 |
输入 |
输出 |
实际情况 |
测试结果 |
1 |
点击“删除”按钮 |
记录信息在页面中消失 |
删除成功 |
正确 |
查看记录测试用例:
功能描述:验证查看记录信息功能。
用例目的:验证查看记录信息功能的实现。
前提条件:已经进入到查看记录信息的页面。
序号 |
输入 |
输出 |
实际情况 |
测试结果 |
1 |
点击“查看”按钮 |
记录信息在页面中显示 |
查看成功 |
正确 |
4.7系统实现
关键代码:
(1)package com.example.jlnote2;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class AdapterDate extends BaseAdapter {
private Context context;
private List<Integer> days = new ArrayList<>();
//日历数据
private List<Boolean> status = new ArrayList<>();
//签到状态,实际应用中初始化签到状态可通过该字段传递
private OnSignedSuccess onSignedSuccess;
//签到成功的回调方法,相应的可自行添加签到失败时的回调方法
public AdapterDate(Context context) {
this.context = context;
int maxDay = DateUtil.getCurrentMonthLastDay();//获取当月天数
for (int i = 0; i < DateUtil.getFirstDayOfMonth() - 1; i++) {
//DateUtil.getFirstDayOfMonth()获取当月第一天是星期几,星期日是第一天,依次类推
days.add(0);
//0代表需要隐藏的item
status.add(false);
//false代表为签到状态
}
for (int i = 0; i < maxDay; i++) {
days.add(i+1);
//初始化日历数据
status.add(false);
//初始化日历签到状态
}
}
@Override
public int getCount() {
return days.size();
}
@Override
public Object getItem(int i) {
return days.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(final int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
if(view==null){
view = LayoutInflater.from(context).inflate(R.layout.item_gv,null);
viewHolder = new ViewHolder();
view.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.tv = view.findViewById(R.id.tvWeek);
viewHolder.rlItem = view.findViewById(R.id.rlItem);
viewHolder.ivStatus = view.findViewById(R.id.ivStatus);
viewHolder.tv.setText(days.get(i)+"");
if(days.get(i)==0){
viewHolder.rlItem.setVisibility(View.GONE);
}
if(status.get(i)){
viewHolder.tv.setTextColor(Color.parseColor("#FD0000"));
viewHolder.ivStatus.setVisibility(View.VISIBLE);
}else{
viewHolder.tv.setTextColor(Color.parseColor("#666666"));
viewHolder.ivStatus.setVisibility(View.GONE);
}
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(status.get(i)){
Toast.makeText(context,"已经被标记!",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"标记成功!",Toast.LENGTH_SHORT).show();
status.set(i,true);
notifyDataSetChanged();
if(onSignedSuccess!=null){
onSignedSuccess.OnSignedSuccess();
}
}
}
});
return view;
}
class ViewHolder{
RelativeLayout rlItem;
TextView tv;
ImageView ivStatus;
}
public void setOnSignedSuccess(OnSignedSuccess onSignedSuccess){
this.onSignedSuccess = onSignedSuccess;
}
}
(2)package com.example.jlnote2;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends AppCompatActivity {
public Button btnlogin;
public EditText etname;
public EditText etpwd;
private CheckBox checkpwd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
btnlogin = (Button) findViewById(R.id.btnLogin);
etname = (EditText) findViewById(R.id.txtUserName);
etpwd = (EditText) findViewById(R.id.txtPassword);
checkpwd = (CheckBox) findViewById(R.id.ckRememberPassword);
//登录-判断输入内容是否为空
btnlogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = etname.getText().toString().trim();
String pwd = etpwd.getText().toString().trim();
if (TextUtils.isEmpty(pwd) || TextUtils.isEmpty(name)) {
Toast.makeText(LoginActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show();
return;
} else {
//登录成功后跳转到主界面MainActivity
Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
startActivity(new Intent(LoginActivity.this, MainActivity.class));
}
}}
);}
}
(3)package com.example.mynote;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
//主界面
public class MainActivity extends AppCompatActivity {
ListView listview;
LayoutInflater inflater;
ArrayList<Notepad> array;
MyDB_operate mdb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview=(ListView) findViewById(R.id.listView1);
inflater=getLayoutInflater();
mdb=new MyDB_operate(this);
array=mdb.getArray();
MyAdapter adapter=new MyAdapter(inflater,array);
listview.setAdapter(adapter);
//listview点击事件
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent intent=new Intent(getApplicationContext(),SecondAtivity.class);
intent.putExtra("ids",array.get(position).getId() );
startActivity(intent);
MainActivity.this.finish();
}
});
//listview长按删除功能
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
final int position, long id) {
new AlertDialog.Builder(MainActivity.this)
.setMessage("确定删除该记事?")
.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
})
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mdb.toDelete(array.get(position).getId());
array=mdb.getArray();
MyAdapter adapter=new MyAdapter(inflater,array);
listview.setAdapter(adapter);
}
})
.create().show();
return true;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
//跳转
Intent intent=new Intent(getApplicationContext(),SecondAtivity.class);
startActivity(intent);
this.finish();
break;
case R.id.item2:
//结束
MainActivity.this.finish();
break;
case R.id.item3:
Intent intent1=new Intent(getApplicationContext(),RiLiActivity.class);
startActivity(intent1);
this.finish();
break;
default:
break;
}
return true;
}
}
(4)package com.example.mynote;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDB extends SQLiteOpenHelper{
//sqllite数据库
public MyDB(Context context) {
super(context, "mydate", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table mybook(ids integer PRIMARY KEY autoincrement,title text,content text,times text)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
(5)package com.example.mynote;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
public class MyDB_operate {
Context context;
MyDB mydb;
SQLiteDatabase myDatabase;
public MyDB_operate(Context context){
this.context=context;
mydb=new MyDB(context);
}
public ArrayList<Notepad> getArray(){
ArrayList<Notepad> array=new ArrayList<Notepad>();
ArrayList<Notepad> array1=new ArrayList<Notepad>();
myDatabase=mydb.getWritableDatabase();
Cursor cursor=myDatabase.rawQuery("select ids,title,times from mybook" , null);
cursor.moveToFirst();
while(!cursor.isAfterLast()){
int id=cursor.getInt(cursor.getColumnIndex("ids"));
String title=cursor.getString(cursor.getColumnIndex("title"));
String times=cursor.getString(cursor.getColumnIndex("times"));
Notepad note=new Notepad(id, title, times);
array.add(note);
cursor.moveToNext();
}
myDatabase.close();
for (int i = array.size(); i >0; i--) {
array1.add(array.get(i-1));
}
return array1;
}
public Notepad getTiandCon(int id){
myDatabase=mydb.getWritableDatabase();
Cursor cursor=myDatabase.rawQuery("select title,content from mybook where ids=‘"+id+"‘" , null);
cursor.moveToFirst();
String title=cursor.getString(cursor.getColumnIndex("title"));
String content=cursor.getString(cursor.getColumnIndex("content"));
Notepad cun=new Notepad(title,content);
myDatabase.close();
return cun;
}
//修改
public void toUpdate(Notepad note){
myDatabase=mydb.getWritableDatabase();
myDatabase.execSQL("update mybook set title=‘"+ note.getTitle()+"‘,times=‘"+note.getTimes()+"‘,content=‘"+note.getContent() +"‘ where ids=‘"+ note.getId()+"‘");
myDatabase.close();
}
//添加
public void toInsert(Notepad cun){
myDatabase=mydb.getWritableDatabase();
myDatabase.execSQL("insert into mybook(title,content,times)values(‘"+ cun.getTitle()+"‘,‘"+cun.getContent()+"‘,‘"+cun.getTimes()+"‘)");
myDatabase.close();
}
//删除
public void toDelete(int ids){
myDatabase=mydb.getWritableDatabase();
myDatabase.execSQL("delete from mybook where ids="+ids+"");
myDatabase.close();
}
}
5.总结
通过这个课程设计,我收获了一点小小的项目经验。在设计整个软件时,先明确要实现功能是非常重要的,要做什么?要用什么做?其次就是界面设计,界面是与用户交互的接口,如何设计好界面?如何设计界面才能让人看上去更协调?如何设计才能够更友好地操作?这些都是我们要考虑的,等到这些都准备好后,才是开始写代码,这样才不会慌乱,才能写出条理清楚的代码。
本记事本虽然是一个初级的入门小程序,但是涉及到的东西也很多,比如定位,这些平时在课本中都没有接触,就需要我们自己去查找资料,这让我们体会到自学能力的重要性。未来,我们相信我们在拥有一些基本的素质之后,一定能够在代码的路上越走越远。