Android记事本程序开发

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android记事本程序开发
《移动智能终端程序设计》课程结业作品Android记事本程序





班级:信息管理与信息系统
姓名:王成科
学号:2013404020106
荆楚理工学院计算机工程学院
目录
一、需求分析 (5)
二、可行性分析 (5)
三、设计目标 (6)
3.1、项目功能模块划分 (6)
3.2、UI设计 (6)
3.3、图形设计 (6)
四、系统设计-功能结构设计 (7)
4.1、新建笔记 (7)
4.2、修改笔记 (8)
4.3、删除笔记 (8)
五、数据库设计 (8)
5.1、笔记表-notes (8)
5.2、多媒体信息表-media (9)
六、架构设计 (9)
七、代码开发及工作分配 (9)
7.1、主页面/笔记列表显示页面的布局代
码: (9)
7.2、编辑笔记页面的布局代码: (10)
7.3、显示多媒体列表的条目布局: (11)
7.4、显示笔记列表的条目布局: (12)
7.5、主页面/笔记列表显示页面的java代
码 (12)
7.6、编辑笔记页面的java代码: (15)
7.7、显示图片的页面: (22)
7.8、显示视频的页面: (23)
7.9、操作数据库的类: (24)
7.10、manifest文件代码: (25)
八、测试 (26)
8.1、测试功能和操作方式: (26)
8.2、测试结果 (27)
参考文献 (28)
一、需求分析
一个记事本,能够输入标题和内容,创建日期、最新修改日期等信息。

如果没有输入标题则使用内容的第一句话作为标题,创建日期和修改日期均由系统自动生成,无需用户干预。

提供笔记列表,列表中笔记展示位标题、创建日期/修改日期
高级的可以给笔记添加照片或视频,这既可以自己拍摄也可以添加手机中已有的视频。

二、可行性分析
技术可行,安卓记事本在技术上已经非常成熟,所以在这方面有很多地方可以参考别人的。

经济可行,安卓记事本开发成本低,使用效率高,同事这个作品是作为练习使用,提高自己开发能力。

技术方面主要用到Java,SQLite,listview、
Intent等知识点。

三、设计目标
3.1、项目功能模块划分
打开应用的第一个页面用于展示已有的笔记列表,列表中的每一个笔记条目都可以点击,点击之后呈现此笔记的完整内容/编辑页面,列表下方有一个添加笔记的按钮,还有拍照笔记,摄像笔记,能够增加、保存、更改、删除笔记。

3.2、UI设计
测试用户界面(如菜单、对话框、窗口和其它可规控件)布局、风格是否满足客户要求、文字是否正确、页面是否美观、文字、图片组合是否完美、操作是否友好等。

UI测试的目标是确保用户界面会通过测试对象的功能来为用户提供相应的访问或浏觅功能。

确保用户界面符合公司或行业的标准。

包括用户友好性、人性化、易操作性测试
3.3、图形设计
输入框说明文字的内容与系统功能是否一
致,文字长度是否加以限制,文字内容是否表意不明,是否有错别字,信息是否为中文显示,是否有敏感性词汇、关键词,是否有敏感性图片,如:涉及版权、专利、隐私等图片。

四、系统设计-功能结构设计
uml建模工具的使用:
4.1、新建笔记
点击添加笔记按钮→打开编辑笔记页面→
用户分别在标题栏和内容栏输入内容;
点击添加视频时,打开系统录像拍摄视频并保存,然后在多媒体列表中显示视频图片、文件名称、路径;
点击添加图像时,打开照相机拍摄图片并保存,然后在多媒体列表中显示图像图片、文件名称、路径;
→点击保存按钮,将笔记和多媒体信息保存到数据库;
→点击取消按钮,关闭当前页面,返回主页面/笔记列表页面。

4.2、修改笔记
点击笔记列表中的笔记时,打开编辑笔记页面,并传入当前笔记的信息,在编辑页面有用户对笔记操作,跟新建笔记的操作相同
4.3、删除笔记
选择已有笔记,进行数据库删除操作。

4.4、保存笔记
将编辑页面里的笔记信息存入到笔记数据库表中,多媒体信息存入到多媒体数据库表中
五、数据库设计
5.1、笔记表-notes
id- Integer型、主键、自动增加 INTEGER PRIMARY KEY AUTOINCREMENT,
name- text型,不为空,默认为“” TEXT NOT NULL DEFAULT \"\",
content,text型,不为空,默认为“” TEXT NOT NULL DEFAULT \"\",
date,text型,不为空,默认为“” TEXT NOT NULL DEFAULT \"\",
5.2、多媒体信息表-media
id-Integer型、主键、自动增加INTEGER PRIMARY KEY AUTOINCREMENT,
path- text型,不为空,默认为“” TEXT NOT NULL DEFAULT \"\",
note_id- Integer型,不为空,默认为0 INTEGER NOT NULL DEFAULT 0
六、架构设计
模块与模块之间的通信机制,MVC、
分层都是三层:视图层(Presentation Layer)、控制层(Domain Layer)、数据流层(Data Layer)。

视图层,使用LinearLayout,列表使用ListView
七、代码开发及工作分配
7.1、主页面/笔记列表显示页面的布局代码:
/Notes/res/layout/activity_main.xml
<LinearLayout xmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ListView>
<Button
android:id="@+id/btnAddNote"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="添加日志" />
</LinearLayout>
7.2、编辑笔记页面的布局代码:
/Notes/res/layout/aty_eidt_note.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:singleLine="true" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/etContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="top" />
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="2" >
</ListView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/btnSave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="保存" />
<Button
android:id="@+id/btnCancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="取消" />
<Button
android:id="@+id/btnAddPhoto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="拍照" />
<Button
android:id="@+id/btnAddVideo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="录像"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
7.3、显示多媒体列表的条目布局:
/Notes/res/layout/media_list_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/ivIcon"
android:layout_width="80dp"
android:layout_height="80dp" />
<TextView
android:id="@+id/tvPath"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
7.4、显示笔记列表的条目布局:
/Notes/res/layout/notes_list_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/tvDate"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
7.5、主页面/笔记列表显示页面的java代码
/Notes/src/com/tops/notes/MainActivity.java
package com.tops.notes;
import com.tops.notes.db.NotesDB;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
/**
* 继承ListActivity的Activity,呈现已经存在的日志和添加日志按钮
*
* @author TOPS
*
*/
public class MainActivity extends ListActivity {
private SimpleCursorAdapter adapter = null;
private NotesDB db;
private SQLiteDatabase dbRead;
public static final int REQUEST_CODE_ADD_NOTE = 1;
public static final int REQUEST_CODE_EDIT_NOTE = 2;
/**
* 实现OnClickListener接口,添加日志按钮的监听
*/
private OnClickListener btnAddNote_clickHandler = new OnClickListener() { @Override
public void onClick(View v) {
// 有返回结果的开启编辑日志的Activity,
// requestCode If >= 0, this code will be returned
// in onActivityResult() when the activity exits.
startActivityForResult(new Intent(MainActivity.this,
AtyEditNote.class), REQUEST_CODE_ADD_NOTE);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.activity_main);
// 操作数据库
db = new NotesDB(this);
dbRead = db.getReadableDatabase();
// 查询数据库并将数据显示在ListView上。

// 建议使用CursorLoader,这个操作因为在UI线程,容易引起无响应错误
adapter = new SimpleCursorAdapter(this, yout.notes_list_cell, null, new String[] { NotesDB.COLUMN_NAME_NOTE_NAME,
NotesDB.COLUMN_NAME_NOTE_DATE }, new int[] {
Name, Date });
setListAdapter(adapter);
refreshNotesListView();
findViewById(R.id.btnAddNote).setOnClickListener(
btnAddNote_clickHandler);
}
/**
* 复写方法,笔记列表中的笔记条目被点击时被调用,打开编辑笔记页面,同事传入当前笔记的信息
*/
@Override
protected void onListItemClick(ListView l, View v, int position, long id) { // 获取当前笔记条目的Cursor对象
Cursor c = adapter.getCursor();
c.moveToPosition(position);
// 显式Intent开启编辑笔记页面
Intent i = new Intent(MainActivity.this, AtyEditNote.class);
// 传入笔记id,name,content
i.putExtra(AtyEditNote.EXTRA_NOTE_ID,
c.getInt(c.getColumnIndex(NotesDB.COLUMN_NAME_ID)));
i.putExtra(AtyEditNote.EXTRA_NOTE_NAME,
c.getString(c.getColumnIndex(NotesDB.COLUMN_NAME_NOTE_NAME)));
i.putExtra(AtyEditNote.EXTRA_NOTE_CONTENT,
c.getString(c.getColumnIndex(NotesDB.COLUMN_NAME_NOTE_CONTENT)));
// 有返回的开启Activity
startActivityForResult(i, REQUEST_CODE_EDIT_NOTE);
super.onListItemClick(l, v, position, id);
}
/**
* Called when an activity you launched exits, giving you the requestCode
* you started it with 当被开启的Activity存在并返回结果时调用的方法
*
* 当从编辑笔记页面返回时调用,刷新笔记列表
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) {
case REQUEST_CODE_ADD_NOTE:
case REQUEST_CODE_EDIT_NOTE:
if (resultCode == Activity.RESULT_OK) {
refreshNotesListView();
}
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 刷新笔记列表,内容从数据库中查询
*/
public void refreshNotesListView() {
/**
* Change the underlying cursor to a new cursor. If there is an existing
* cursor it will be closed.
*
* Parameters: cursor The new cursor to be used
*/
adapter.changeCursor(dbRead.query(NotesDB.TABLE_NAME_NOTES, null, null, null, null, null, null));
}
}
7.6、编辑笔记页面的java代码:
/Notes/src/com/tops/notes/AtyEditNote.java
package com.tops.notes;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.app.ListActivity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import .Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import youtInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.tops.notes.db.NotesDB;
public class AtyEditNote extends ListActivity {
private int noteId = -1;
private EditText etName, etContent;
private MediaAdapter adapter;
private NotesDB db;
private SQLiteDatabase dbRead, dbWrite;
private String currentPath = null;
public static final int REQUEST_CODE_GET_PHOTO = 1;
public static final int REQUEST_CODE_GET_VIDEO = 2;
public static final String EXTRA_NOTE_ID = "noteId";
public static final String EXTRA_NOTE_NAME = "noteName";
public static final String EXTRA_NOTE_CONTENT = "noteContent";
/**
* 按钮点击的监听器,实现OnClickListener接口
*/
private OnClickListener btnClickHandler = new OnClickListener() {
Intent i;
File f;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnAddPhoto:// 添加照片按钮
// 使用Intent调用系统照相机,传入图像保存路径和名称
i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
f = new File(getMediaDir(), System.currentTimeMillis() + ".jpg");
if (!f.exists()) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
currentPath = f.getAbsolutePath();
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(i, REQUEST_CODE_GET_PHOTO);
break;
case R.id.btnAddVideo:// 添加视频按钮
// 使用Intent调用系统录像器,传入视频保存路径和名称
i = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
f = new File(getMediaDir(), System.currentTimeMillis() + ".mp4");
if (!f.exists()) {
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
currentPath = f.getAbsolutePath();
i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(i, REQUEST_CODE_GET_VIDEO);
break;
case R.id.btnSave:// 保存按钮
// 保存多媒体信息和笔记信息到数据库,然后关闭当前页面,返回到笔记列表页面/主页面
saveMedia(saveNote());
setResult(RESULT_OK);
finish();
break;
case R.id.btnCancel:// 取消按钮
// 关闭当前页面,返回到笔记列表页面/主页面
setResult(RESULT_CANCELED);
finish();
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(yout.aty_eidt_note);
db = new NotesDB(this);
dbRead = db.getReadableDatabase();
dbWrite = db.getWritableDatabase();
// 显示多媒体列表
adapter = new MediaAdapter(this);
setListAdapter(adapter);
etName = (EditText) findViewById(R.id.etName);
etContent = (EditText) findViewById(R.id.etContent);
// 获取Activity传递过来的noteId
noteId = getIntent().getIntExtra(EXTRA_NOTE_ID, -1);
if (noteId > -1) {
etName.setText(getIntent().getStringExtra(EXTRA_NOTE_NAME));
etContent.setText(getIntent().getStringExtra(EXTRA_NOTE_CONTENT));
// 查询本笔记的noteId并且检查是否有对应的多媒体,有则遍历显示在MediaList中
Cursor c = dbRead.query(NotesDB.TABLE_NAME_MEDIA, null,
NotesDB.COLUMN_NAME_MEDIA_OWNER_NOTE_ID + "=?",
new String[] { noteId + "" }, null, null, null);
while (c.moveToNext()) {
adapter.add(new MediaListCellData(c.getString(c
.getColumnIndex(NotesDB.COLUMN_NAME_MEDIA_PATH)), c
.getInt(c.getColumnIndex(NotesDB.COLUMN_NAME_ID))));
}
/**
* Notifies the attached observers that the underlying data has been
* changed and any View reflecting the data set should refresh
* itself.
*/
adapter.notifyDataSetChanged();
}
findViewById(R.id.btnSave).setOnClickListener(btnClickHandler);
findViewById(R.id.btnCancel).setOnClickListener(btnClickHandler);
findViewById(R.id.btnAddPhoto).setOnClickListener(btnClickHandler);
findViewById(R.id.btnAddVideo).setOnClickListener(btnClickHandler);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) { MediaListCellData data = adapter.getItem(position);
Intent i;
switch (data.type) {
case MediaType.PHOTO:
i = new Intent(this, AtyPhotoViewer.class);
i.putExtra(AtyPhotoViewer.EXTRA_PATH, data.path);
startActivity(i);
break;
case MediaType.VIDEO:
i = new Intent(this, AtyVideoViewer.class);
i.putExtra(AtyVideoViewer.EXTRA_PATH, data.path);
startActivity(i);
break;
}
super.onListItemClick(l, v, position, id);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { System.out.println(data);
switch (requestCode) {
case REQUEST_CODE_GET_PHOTO:
case REQUEST_CODE_GET_VIDEO:
if (resultCode == RESULT_OK) {
adapter.add(new MediaListCellData(currentPath));
adapter.notifyDataSetChanged();
}
break;
default:
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 获取存储Media的目录路径
*
* @return File类型的目录路径
*/
public File getMediaDir() {
File dir = new File(Environment.getExternalStorageDirectory(),
"NotesMedia");
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
/**
* 保存Media信息到数据库
*
* @param noteId
*/
public void saveMedia(int noteId) {
MediaListCellData data;
ContentValues cv;
for (int i = 0; i < adapter.getCount(); i++) {
data = adapter.getItem(i);
if (data.id <= -1) {
cv = new ContentValues();
cv.put(NotesDB.COLUMN_NAME_MEDIA_PATH, data.path);
cv.put(NotesDB.COLUMN_NAME_MEDIA_OWNER_NOTE_ID, noteId);
dbWrite.insert(NotesDB.TABLE_NAME_MEDIA, null, cv);
}
}
}
/**
* 保存日志到数据库
*
* @return
*/
public int saveNote() {
ContentValues cv = new ContentValues();
cv.put(NotesDB.COLUMN_NAME_NOTE_NAME, etName.getText().toString());
cv.put(NotesDB.COLUMN_NAME_NOTE_CONTENT, etContent.getText().toString());
cv.put(NotesDB.COLUMN_NAME_NOTE_DATE, new SimpleDateFormat(
"yyyy-MM-dd hh:mm:ss").format(new Date()));
if (noteId > -1) {
dbWrite.update(NotesDB.TABLE_NAME_NOTES, cv, NotesDB.COLUMN_NAME_ID
+ "=?", new String[] { noteId + "" });
return noteId;
} else {
return (int) dbWrite.insert(NotesDB.TABLE_NAME_NOTES, null, cv);
}
}
/**
* 复写Activity的生命周期方法,用于关闭读写数据库的操作
*/
@Override
protected void onDestroy() {
dbRead.close();
dbWrite.close();
super.onDestroy();
}
/**
* 继承BaseAdapter类的MediaAdapter类,用于显示媒体信息
*
* @author TOPS
*
*/
static class MediaAdapter extends BaseAdapter {
private Context context;
private List<MediaListCellData> list = new ArrayList<AtyEditNote.MediaListCellData>();
public MediaAdapter(Context context) {
this.context = context;
}
public void add(MediaListCellData data) {
list.add(data);
}
@Override
public int getCount() {
return list.size();
}
@Override
public MediaListCellData getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
yout.media_list_cell, null);
}
MediaListCellData data = getItem(position);
ImageView ivIcon = (ImageView) convertView
.findViewById(R.id.ivIcon);
TextView tvPath = (TextView) convertView.findViewById(Path);
ivIcon.setImageResource(data.iconId);
tvPath.setText(data.path);
return convertView;
}
}
/**
* 显示多媒体的条目类
*
* @author TOPS
*
*/
static class MediaListCellData {
int type = 0;
int id = -1;
String path = "";
int iconId = R.drawable.ic_launcher;
public MediaListCellData(String path, int id) { this(path);
this.id = id;
}
public MediaListCellData(String path) {
this.path = path;
if (path.endsWith(".jpg")) {
iconId = R.drawable.icon_photo;
type = MediaType.PHOTO;
} else if (path.endsWith(".mp4")) {
iconId = R.drawable.icon_video;
type = MediaType.VIDEO;
}
}
}
/**
* 多媒体的种类
*
* @author TOPS
*
*/
static class MediaType {
static final int PHOTO = 1;
static final int VIDEO = 2;
}
}
7.7、显示图片的页面:
/Notes/src/com/tops/notes/AtyPhotoViewer.java
package com.tops.notes;
import java.io.File;
import android.app.Activity;
import .Uri;
import android.os.Bundle;
import android.widget.ImageView;
/**
* 显示照片的Activity
*
* @author TOPS
*
*/
public class AtyPhotoViewer extends Activity {
private ImageView iv;
public static final String EXTRA_PATH = "path";
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
iv = new ImageView(this);
setContentView(iv);
String path = getIntent().getStringExtra(EXTRA_PATH);
if (path != null) {
iv.setImageURI(Uri.fromFile(new File(path)));
} else {
finish();
}
}
}
7.8、显示视频的页面:
/Notes/src/com/tops/notes/AtyVideoViewer.java
package com.tops.notes;
import android.app.Activity;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;
/**
* 显示视频的Activity
*
* @author TOPS
*
*/
public class AtyVideoViewer extends Activity {
private VideoView vv;
public static final String EXTRA_PATH = "path";
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
vv = new VideoView(this);
vv.setMediaController(new MediaController(this));
setContentView(vv);
String path = getIntent().getStringExtra(EXTRA_PATH);
if (path != null) {
vv.setVideoPath(path);
} else {
finish();
}
}
}
7.9、操作数据库的类:
/Notes/src/com/tops/notes/db/NotesDB.java
package com.tops.notes.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* 实现SQLiteOpenHelper接口的NotesDB类,用于创建数据库表
*
* @author TOPS
*
*/
public class NotesDB extends SQLiteOpenHelper {
public static final String TABLE_NAME_NOTES = "notes";
public static final String TABLE_NAME_MEDIA = "media";
public static final String COLUMN_NAME_ID = "_id";
public static final String COLUMN_NAME_NOTE_NAME = "name";
public static final String COLUMN_NAME_NOTE_CONTENT = "content";
public static final String COLUMN_NAME_NOTE_DATE = "date";
public static final String COLUMN_NAME_MEDIA_PATH = "path";
public static final String COLUMN_NAME_MEDIA_OWNER_NOTE_ID = "note_id";
public NotesDB(Context context) {
super(context, "notes", null, 1);
}
/**
* 当第一次打开数据库,表不存在时调用,以创建表
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + TABLE_NAME_NOTES + "(" + COLUMN_NAME_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT," + COLUMN_NAME_NOTE_NAME
+ " TEXT NOT NULL DEFAULT \"\"," + COLUMN_NAME_NOTE_CONTENT
+ " TEXT NOT NULL DEFAULT \"\"," + COLUMN_NAME_NOTE_DATE
+ " TEXT NOT NULL DEFAULT \"\"" + ")");
db.execSQL("CREATE TABLE " + TABLE_NAME_MEDIA + "(" + COLUMN_NAME_ID
+ " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_NAME_MEDIA_PATH + " TEXT NOT NULL DEFAULT \"\","
+ COLUMN_NAME_MEDIA_OWNER_NOTE_ID
+ " INTEGER NOT NULL DEFAULT 0" + ")");
}
/**
* 当表存在且是旧版本时调用,删除旧表,创建新表
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub
}
}
7.10、manifest文件代码:
/Notes/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="/apk/res/android"
package="com.tops.notes"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="UNCHER" />
</intent-filter>
</activity>
<activity
android:name="AtyEditNote"
android:configChanges="keyboardHidden|orientation" >
</activity>
<activity
android:name="AtyPhotoViewer"
android:configChanges="keyboardHidden|orientation" >
</activity>
<activity
android:name="AtyVideoViewer"
android:configChanges="keyboardHidden|orientation" >
</activity>
</application>
</manifest>
八、测试
列出要测试的功能、记录测试时间及操作方式、记录造成BUG出现的操作步骤
发布给提交给客户
8.1、测试功能和操作方式:
应用的功能是否达到需求,达到了。

数据库创建是否成功,成功了,两个理由:查看目录知道有数据库文件;关闭应用重新打开时笔记不会消失。

运行截图:
8.2、测试结果
测试结果显示程序能够正常安装,运行流畅,没有卡顿,运行等能够创建文件,保存文件,编辑和删除文件,但是打开拍照之后不能保存照片,保存程序崩溃停止,摄像也是一样的,不知道是什么原因造成的,可能是安卓版本不兼容所致。

参考文献
[1] 王向辉,张国印,沈洁.Android应用程序
开发(第3版)[M]. 北京:清华大学出版
社,2010.
[2] (美)Nicholas C. Zakas著,李松峰,曹力
译.JavaScript高级程序设计(第3版)[M].
北京:人民邮电出版社,2012.
[3] 软件开发联盟.Java Web开发实战[M].
北京:清华大学出版社,2012.
[4] 李兴华,王月清.Java Web开发实战经
典[M]. 北京:清华大学出版社,2010. [5] 施威铭.Android APP开发入门:使用
Android Studio环境[M]. 北京:机械工业
出版社,2015.。

相关文档
最新文档