1.引言
1.1课设要求
1.1.1要求描述
随着智能手机的普及,基于Android平台的应用软件需求也越来越多。宁波东蓝数码有限公司是一家规模较大的软件公司,随着公司规模的不断扩大,目前新增了大量基于Android智能手机方面的业务,但由于业务量较大,公司内部开发人员一时无法满足要求,现需要外包一些智能手机应用软件。现假设你所在的公司承接了该公司智能手机外包项目的开发工作,并明确了外包的项目范围如下:
(1)带共享功能的文件管理、多媒体技术制作类项目;
(2)带共享功能的地图处理类项目;
(3)带有数据存储、处理的移动端APP。
1.2摘要
随着移动设备制造技术和移动通信网络的迅猛发展,全球手机用户日益增加,手机成为了很多人日常生活中必不可少的一部分,手机业在日益发展的同时,人们对手机的功能需求和体验需求也越来越高,因此各种智能手机相继而出,当前市场上最流行的智能手机的操作系统非Android莫属。Android是一种以Linux为基础的开源代码操作系统,主要应用于手机,因为其良好的人机交互能力和能够安装使用众多功能各异的应用软件而深受人们喜爱,本文报告就介绍其基于Android开发的一个“便捷式通讯录”。根据当下人们的使用习惯和实际需求,本文对通讯录做出了相应的构想和设计。在实现通讯录基本功能添加,查找,修改,删除等的基础上,还实现了与本机拨号功能以及本机短信发送功能的链接,在所学基础之上进行更多学习,从而使其功能合理化。
2.系统概述
2.1需求分析
2.1.1基本功能需求
(1) 用户通过联系人功能可以增加联系人的详细信息。
(2) 用户通过联系人功能可以对已增加联系人的详细信息进行删除,修改,以及查询。
(3) 本通讯录可实现本机拨号功能,以及短信发送功能。
2.1.2系统用例分析
图1-1显示了联系人功能模块的用例。包括了查看联系人详细信息,编辑联系人信息,新建联系人,对选中的联系人,可以对其进行删除、拨打电话、发送短信的操作。用户还可以进行联系人搜索,这样方便用户快速找到想找的联系人信息。
2.2总体设计方案
2.2.1系统模块关系与划分
一个好的系统设计的步骤决定了程序是否能按照设计者的目的按时完成,是否能在规定的时间内按照设计者的要求高质量的完成程序必要的功能。并且按照标准的设计步骤对程序进行调试,测试,以及后期的优化完善,使程序更加具有健壮性和可用性。通过对通讯录功能、系统模块、用户需求方面进行全方位的分析制定开发流程。
采用标准的开发流程确定系统具有用户管理功能,联系人增删改功能,通讯功能,查找功能,备份等功能。
通过对系统的功能结构的分析,设计后系统运行流程是系统运行后用户将进入通讯录主界面,可以看到联系人,增加联系人,。通过点击MENU界面的增加功能选项可以新增联系人,通过查找按钮可以对联系人进行姓名、号码的操作,通过选择联系人并点击删除键可以对联系人进行删除操作,通过菜单功能可以显示所有联系人、删除所有联系人、并备份SD卡功能。在联系人详细信息界面点击MENU键弹出通讯功能框选择拨打电话按钮或者发信息发邮件按键,系统的运行流程图如1-3所示。
图1-3 系统运行流程
2.2.2 Android开发组件
Android开发分为四大组件,分别是:活动(Activity):用于表现功能。服务(Service):用于后台运行服务,不提供界面呈现。广播接收器(BroadcastReceiver ):用于接收广播。内容提供商(Content Provider):支持在多个应用中存储和读取数据,相当于数据库。
①Activity组件
Android中,Activity是所有程序的根本,所有程序的流程都是运行在Activity中,Activity是Android当中最基本的模块之一。在Android的程序当中,Activity代表手机屏幕的一屏。如果把手机当作浏览器,那么Activity相当于一个网页。在Activity当中可以添加一些Button、Check box等控件。可以看到Activity概念和网页的概念相当类。
一般一个Android应用由多个Activity组成的。这多个Activity之间可以进行互相跳转,和网页跳转稍微不一样,Activity之间的跳转有可能返回值,例如,从Activity A 跳转到Activity B,那么当Activity B 运行结束的时候,有可能会给Activity A 一个返回值。这样做在很多时候是相当方便的。
当打开一个新的屏幕时,原来的屏幕会成为暂停,并且进入历史堆栈中。用户可以选择性的移除一些没有必要的屏幕,因为Android会把每个应用的开始到当前的每个屏幕保存在堆栈中。 Activity在运行是会受到一些突然事件的影响,例如:你正在使用一个Activity ,突然来电话了,这时你的应用就要具备处理这些突然事件的能力,这就需要用Activity 生命周期。
② Service组件
Service是Android系统中的一种组件,它不能自己运行,只能在后台运行,并且可以和其他组件进行交互。Service是一种程序,它可以运行很长时间,但是它却没有用户界面。例如:打开一个音乐播放器的程序,这个时候若想上网,就打开Android浏览器,这个时候虽然已经进入了浏览器这个程序,但是,歌曲播放并没有停止,而是在后台继续一首接着一首的播放。本系统客户端扩展功能就是采用Service来进行设计和开发的。
③Broadcast Receiver组件
在Android中,Broadcast是一种广泛运用在应用程序之间传输信息的机制。BroadcastReceiver是对发出来的Broadcast进行过滤接受并响应的组件。这个组件除了接受和响应广播通知之外,什么都不做。很多广播由系统代码产生,比如时区变化,电磁量变低,拍摄照片,或是用户改变语言首选项,都会产生广播。应用程序本身也可以启动一个广播,比如,让其他应用程序知道,某些数据已经完成下载,可以被这些应用程序使用了。
注册BroadcastReceiver有两种方式。方式一:在AndroidManifest.xml进行注册。这种方法有一个特点是即使应用程序已经关闭了,但这个BroadcastReceiver依然会接受广播出来的对象。方式二:在代码中注册广播,第一种俗称静态注册,第二种俗称动态注册。动态注册比静态注册较灵活。静态注册一个BroadcastReceiver时,无论应用程序是否启动。都可以接受对应的广播。动态注册的时候,如果不执行unregister Receiver();方法被取消。但如果执行这个方法,就不能接受广播。
④ Content Provider组件
Content Provider是Android提供的第三方应用数据的访问方案。
在Android中,对数据的保护是很严的,除了放在SD卡中的数据,一个应用的数据库、文件等内容,都不允许直接访问。Content Provider屏蔽了内部数据的存储细节,向外提供了上述统一的接口模型,这样的抽象层次,大大简化了上层应用的书写,也对数据的整合提供了更方便的途径。在各大组件中,Service和Content Provider都是那种需要持续访问的。Service如果是一个耗时的场景,往往会提供异步访问的接口,而Content Provider不论效率如何,都提供的是约定的同步访问接口。使用Content Provider能够灵活的替换底层使用的存储设备,不用考虑底层存储设备的细节,从而使应用系统具有良好的数据。
3.系统详细设计
3.1通讯录需求分析
根据手机功能调查显示,近十成消费者都会使用手机通讯录功能,随着手机通讯录功能的不断加强与完善,手机通讯录的意义,已不仅仅像电话薄一样显示电话号码,而是向着个性化、人性化的方向发展。通讯录从无到有,从英文到中文,经历了十几年的发展历程,今后的发展趋势就是从通讯录发展为名片夹,也就是在一个联系人之下有手机号码、固话号码、公司、住址、邮箱、备注等内容。手机通讯录扮演着与用户直接交互并且提供服务的重要角色,它需要提供良好的用户体验,方便用户操作,接收用户的操作并把这些操作转换成相应的命令,采用用户活动的方式完成各个服务的逻辑流程。其功能主要包括增加、删除、编辑联系人,查找联系人,通讯功能,菜单功能,导入导出功能。
3.1.1增加、删除、编辑联系人
点击通信录界面中的增加按钮,进入增加联系人界面。输入联系人的基本信息,并可根据用户需求增加编号、姓名、手机号、E-mail、地址、性别、关系、备注这些信息,单击上方击保存按钮后,点击返回,可返回主界面。点击通信录中一个已增加联系人,对其进行拨打电话,查看,或发送短信等操作。点击查看后,可对已增加联系人的信息资料进行删除修改等操作,完成后点击返回,退回至主界面。也可在本页面对拨号或发送短信功能进行选择。
3.1.2查找联系人
回到通讯录主界面,在搜索框内输入相应信息如姓名,从而进行查找目标联系人。查找到相应联系人后,可对所查找联系人进行点击,从而进行拨打电话,查找以及发送短信等操作,进而实现以上所提到过的删除,修改,拨号,发送短信等功能。
3.1.3通讯功能
用户在通讯录选择联系人进入联系人详细信息界面,这时点击联系人出现功能框,选择打电话、发信息,查看的功能进行操作。
3.2数据库设计
3.2.1Android数据库概述
Android自带了SQLite数据库,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。
关于Sqlite的数据类型,你会惊讶:Typelessness(无类型). 对! SQLite是无类型的. 这意味着你可以保存任何类型的数据到你所想要保存的任何表的任何列中, 无论这列声明的数据类型是什么. 对于SQLite来说对字段不指定类型是完全有效的。
SQLite有五个特点,分别是独立性、非服务式、零配置、元处理、开放性。
独立性:sqlite使用标准C语言实现,它只需要很少的系统支持,这使得它很容易移植进嵌入式设备,因此,它能够应用于更广泛的软件环境。Sqlite使用一个虚拟文件系统完成和磁盘的交互,在不同的系统中完成这个交互层是很简单的。
非服务式:极大多数的数据库都是以服务的方式实现,这要求客户必须通过某种中间接口来连接数据库。然而slqite可以直接访问数据库,不需要任何中间接口来完成。
零配置:因为sqlite不需要中间接口,所以我们不需要安装其他配置。
元处理:sqlite的数据库操作具有原子性、孤立性,程序或系统崩溃不会引发数据错误。
开放性:任何人可以*获得和使用sqlite的源码。
因为sqlite有这么多的优点,已经有非常多的网站和软件开始使用sqlite数据库,大大方便了开发人员进行开发。已知的有:Goolge、QQ、Iphone、Mac电脑等。
3.2.2数据库表详细设计
对系统所需功能需求分析通过了设计确定了系统数据库中表的设计,该系统有一张表电话薄表,下面为表的详细设计。
表user:
字段名 |
类型 |
是否可为空 |
是否为主键 |
描述 |
_id |
Int |
否 |
否 |
id |
Number’ |
Int |
是 |
否 |
编号 |
Name |
String |
否 |
是 |
姓名 |
Phone |
Int |
是 |
否 |
号码 |
|
Varchar |
是 |
否 |
邮箱 |
Address |
Varchar |
是 |
否 |
地址 |
Gender |
Char |
是 |
否 |
性别 |
3.3系统界面设计
3.3.1界面布局
Android的资源文件保存在/res的子目录中。其中/res/drawable/目录中保存的是图像文件,/res/values目录中保存的是用来自定义字符串和颜色的文件,/res/xml目录中保存的是XML格式的数据文件。所有在程序开发阶段可以被调用的资源都保存在这些目录中,在对界面进行绘制时要考虑到不同手机屏幕大小可能不一样,应尽量兼容大多数手机屏幕尺寸,使之显示无障碍。
3.3.2增加联系人功能
在通讯录中最主要的功能操作,也就是联系人的添加操作的功能,在联系人增加界面中点击保存按钮实现对联系人信息的保存。
图2-1 增加联系人界面
3.3.3删除联系人功能
通过光标选择删除的联系人,点击联系人然后选择删除可以删除联系人,并且在数据库中删除联系人,删除联系人功能
如图2-2所示
3.3.4查找联系人功能
在查找功能实现的过程中,在数据库中进行查找匹配,返回到list列表中,并统计查找到的条数展现给用户。
3.3.5修改联系人功能
选择一个联系人后,可进行三项操作,点击查看后,点击右上角的修改图标,可跳转至修改页面进行数据修改。
4.系统编码实现
4.1系统功能的实现部分代码
MainActivity:
package com.qwe.activity;
import com.qwe.model.Contact;
import com.qwe.service.Service;
import com.qwe.activity.R;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.ActionBarActivity;
import android.net.Uri;
import android.os.Bundle;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.SimpleAdapter;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
private ListView contact_list=null;
private EditText search=null;
private List contacts=null;
private Contact contact=null;
private Service service=null;
public static final int OPTION_DIALOG = 1;
private PopupWindow popupWindow;
private ListView menuListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle(R.string.title_main_activity);
service = new Service(this);
init();
getContent();
initPopupWindow();
}
private void init(){
contact_list = (ListView)findViewById(R.id.contact_list);
contact_list.setCacheColorHint(Color.TRANSPARENT);
contact_list.setOnItemClickListener(new ViewItemListener());
search = (EditText)findViewById(R.id.search);
search.addTextChangedListener(new SearchTextChangedListener());
}
private void getContent(){
List mylist = new ArrayList();
String queryName = search.getText().toString();
contacts = service.getByName(queryName);
if(contacts != null){
for(int i=0; i<contacts.size(); i++){
Contact contact = (Contact)contacts.get(i);
HashMap map = new HashMap();
if(contact.getGender().equals("男")){
map.put("tv_image", R.drawable.icon_boy);
}else{
map.put("tv_image", R.drawable.icon_girl);
}
map.put("tv_name", contact.getName());
map.put("tv_phone", contact.getPhone());
mylist.add(map);
}
}
SimpleAdapter adapter = new SimpleAdapter(this, mylist,R.layout.my_list_item,
new String[] {"tv_image","tv_name","tv_phone"},
new int[] {R.id.user_image,R.id.item_name,R.id.item_phone});
contact_list.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.add_contact) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
return true;
}
if(id == R.id.more) {
if(popupWindow.isShowing())
popupWindow.dismiss();
else
popUp();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onRestart() {
getContent();
super.onRestart();
}
protected Dialog onCreateDialog(int id){
Dialog dialog;
switch(id){
case OPTION_DIALOG:
dialog = createOptionDialog();
break;
default:
dialog = null;
}
return dialog;
}
private Dialog createOptionDialog(){
final Dialog optionDialog;
View optionDialogView = null;
LayoutInflater li = LayoutInflater.from(this);
optionDialogView = li.inflate(R.layout.option_dialog, null);
optionDialog = new AlertDialog.Builder(this).setView(optionDialogView).create();
ImageButton ibCall = (ImageButton)optionDialogView.findViewById(R.id.dialog_call);
ImageButton ibView = (ImageButton)optionDialogView.findViewById(R.id.dialog_view);
ImageButton ibSms = (ImageButton)optionDialogView.findViewById(R.id.dialog_sms);
ibCall.setOnClickListener(new ImageButtonListener());
ibView.setOnClickListener(new ImageButtonListener());
ibSms.setOnClickListener(new ImageButtonListener());
return optionDialog;
}
private void initPopupWindow(){
View view = getLayoutInflater().inflate(R.layout.popup_window, null);
menuListView = (ListView)view.findViewById(R.id.popup_list_view);
popupWindow = new PopupWindow(view, 160, WindowManager.LayoutParams.WRAP_CONTENT);
List<Map<String, Object>> data = new ArrayList<>();
Map<String, Object> map = new HashMap<>();
map.put("menu_about", "关于");
data.add(map);
SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.popup_list_item,
new String[]{"menu_about"}, new int[]{R.id.menu_about});
menuListView.setAdapter(adapter);
menuListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
Intent intent = new Intent(MainActivity.this,AboutActivity.class);
startActivity(intent);
popupWindow.dismiss();
break;
}
}
});
popupWindow.setFocusable(true);
popupWindow.setTouchable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
}
private void popUp(){
popupWindow.showAsDropDown(this.findViewById(R.id.more), 0, 2);
}
class SearchTextChangedListener implements TextWatcher{
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
getContent();
}
}
class ViewItemListener implements OnItemClickListener{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
contact = (Contact)contacts.get(position);
showDialog(OPTION_DIALOG);
}
}
class ImageButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.dialog_call:
if(contact.getPhone().equals("")){
Toast.makeText(MainActivity.this, "没有手机号码", Toast.LENGTH_LONG).show();
}else{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+contact.getPhone()));
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
dismissDialog(OPTION_DIALOG);
break;
case R.id.dialog_view:
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putExtra("id", contact.getId());
startActivity(intent);
dismissDialog(OPTION_DIALOG);
break;
case R.id.dialog_sms:
if(contact.getPhone().equals("")){
Toast.makeText(MainActivity.this, "没有手机号码", Toast.LENGTH_LONG).show();
}else{
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_SENDTO);
intent1.setData(Uri.parse("smsto:"+contact.getPhone()));
intent1.addCategory("android.intent.category.DEFAULT");
startActivity(intent1);
}
dismissDialog(OPTION_DIALOG);
break;
}
}
}
}
AddActivity:
package com.qwe.activity;
import com.qwe.model.Contact;
import com.qwe.service.Service;
import com.qwe.activity.R;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.Toast;
public class AddActivity extends ActionBarActivity {
private EditText number=null;
private EditText name=null;
private EditText phone=null;
private EditText email=null;
private EditText address=null;
private EditText remark=null;
private Spinner spinner=null;
private String[] relationship = {"同学","同事","家人","朋友"};
private RadioButton gender=null;
private RadioGroup group=null;
private ImageView image=null;
private Service service=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
service = new Service(this);
init();
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item,relationship);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
private void init(){
number = (EditText)findViewById(R.id.contact_number);
name = (EditText)findViewById(R.id.contact_name);
phone = (EditText)findViewById(R.id.contact_phone);
email = (EditText)findViewById(R.id.contact_email);
address = (EditText)findViewById(R.id.contact_address);
remark = (EditText)findViewById(R.id.contact_remark);
spinner = (Spinner)findViewById(R.id.spinner);
group = (RadioGroup)findViewById(R.id.group);
group.setOnCheckedChangeListener(new GroupListener());
image = (ImageView)findViewById(R.id.image_view);
}
private Contact getContent(){
gender = (RadioButton)findViewById(group.getCheckedRadioButtonId()); // get the selected RadioButton
Contact contact = new Contact();
contact.setNumber(number.getText().toString());
contact.setName(name.getText().toString());
contact.setPhone(phone.getText().toString());
contact.setEmail(email.getText().toString());
contact.setAddress(address.getText().toString());
contact.setRemark(remark.getText().toString());
contact.setGender(gender.getText().toString());
contact.setRelationship(spinner.getSelectedItem().toString());
return contact;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_add, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_save) {
if(number.getText().toString().equals(""))
Toast.makeText(this, "编号不能为空", Toast.LENGTH_LONG).show();
else if(name.getText().toString().equals(""))
Toast.makeText(this, "姓名不能为空", Toast.LENGTH_LONG).show();
else if(phone.getText().toString().equals(""))
Toast.makeText(this, "电话号码不能为空", Toast.LENGTH_LONG).show();
else {
boolean flag = service.save(getContent());
if(flag)
Toast.makeText(this, "联系人添加成功", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "联系人添加失败", Toast.LENGTH_LONG).show();
}
return true;
}
if (id == android.R.id.home)
{
finish();
}
return super.onOptionsItemSelected(item);
}
class GroupListener implements OnCheckedChangeListener{
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(group.getCheckedRadioButtonId() == R.id.male)
image.setImageResource(R.drawable.icon_boy);
else
image.setImageResource(R.drawable.icon_girl);
}
}
}
DetailActivity:
package com.qwe.activity;
import com.qwe.model.Contact;
import com.qwe.service.Service;
import com.qwe.activity.R;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.net.Uri;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
public class DetailActivity extends ActionBarActivity {
private EditText number=null;
private EditText name=null;
private EditText phone=null;
private EditText email=null;
private EditText address=null;
private EditText remark=null;
private EditText gender=null;
private EditText relationship=null;
private ImageView image=null;
private Button call=null;
private Button sms=null;
private Contact contact=null;
private Service service=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
contact = new Contact();
init();
Intent intent = getIntent();
int id = intent.getIntExtra("id", -1);
if(id == -1){
finish();
}else{
service = new Service(this);
contact = service.getById(id);
number.setText(contact.getNumber());
name.setText(contact.getName());
phone.setText(contact.getPhone());
email.setText(contact.getEmail());
address.setText(contact.getAddress());
remark.setText(contact.getRemark());
gender.setText(contact.getGender());
if(contact.getGender().equals("男")){
image.setImageResource(R.drawable.icon_boy);
}else{
image.setImageResource(R.drawable.icon_girl);
}
relationship.setText(contact.getRelationship());
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void init(){
number = (EditText)findViewById(R.id.contact_number);
name = (EditText)findViewById(R.id.contact_name);
phone = (EditText)findViewById(R.id.contact_phone);
email = (EditText)findViewById(R.id.contact_email);
address = (EditText)findViewById(R.id.contact_address);
remark = (EditText)findViewById(R.id.contact_remark);
gender = (EditText)findViewById(R.id.contact_gender);
relationship = (EditText)findViewById(R.id.contact_relationship);
image = (ImageView)findViewById(R.id.image_button);
call = (Button)findViewById(R.id.call);
call.setOnClickListener(new ButtonCallListener());
sms = (Button)findViewById(R.id.sms);
sms.setOnClickListener(new ButtonSmsListener());
}
private void dialog(){
AlertDialog.Builder builder = new Builder(DetailActivity.this);
builder.setMessage("确定删除吗?");
builder.setTitle("提示");
builder.setPositiveButton("确定", new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
service.delete(contact.getId());
finish();
}
});
builder.setNegativeButton("取消", new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_detail, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_modify) {
Intent intent = new Intent(DetailActivity.this, ModifyActivity.class);
intent.putExtra("id", contact.getId());
startActivity(intent);
return true;
}
if (id == R.id.action_delete) {
dialog();
return true;
}
if (id == android.R.id.home)
{
finish();
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onRestart() {
Intent intent = getIntent();
int id = intent.getIntExtra("id", -1);
if(id == -1){
finish();
}else{
service = new Service(this);
contact = service.getById(id);
number.setText(contact.getNumber());
name.setText(contact.getName());
phone.setText(contact.getPhone());
email.setText(contact.getEmail());
address.setText(contact.getAddress());
remark.setText(contact.getRemark());
gender.setText(contact.getGender());
if(contact.getGender().equals("男")){
image.setImageResource(R.drawable.icon_boy);
}else{
image.setImageResource(R.drawable.icon_girl);
}
relationship.setText(contact.getRelationship());
}
super.onRestart();
}
class ButtonCallListener implements android.view.View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+contact.getPhone()));
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
}
class ButtonSmsListener implements android.view.View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:"+contact.getPhone()));
intent.addCategory("android.intent.category.DEFAULT");
startActivity(intent);
}
}
}
DBContact:
package com.qwe.dataaccess;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBContact extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "contact.db";
private static final int DATABASE_VERSION = 1;
private static String sql = "create table contact (" + "_id integer primary key autoincrement, "
+ "number text, " + "name text, " + "phone text, " + "email text, "
+ "address text, " + "gender text, " + "relationship text, "
+ "remark text)";
public DBContact(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
DBOperation:
package com.qwe.dataaccess;
import java.util.ArrayList;
import java.util.List;
import com.qwe.model.Contact;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class DBOperation{
private DBContact database = null;
public DBOperation(Context context){
database = new DBContact(context);
}
public boolean save(Contact contact){
SQLiteDatabase db = database.getWritableDatabase();
if(contact != null){
ContentValues value = new ContentValues();
value.put("number", contact.getNumber());
value.put("name", contact.getName());
value.put("phone", contact.getPhone());
value.put("email", contact.getEmail());
value.put("address", contact.getAddress());
value.put("gender", contact.getGender());
value.put("relationship", contact.getRelationship());
value.put("remark", contact.getRemark());
db.insertOrThrow("contact", null, value);
db.close();
return true;
}
else{
return false;
}
}
public List getByName(String queryName){
if(queryName == null || queryName.equals("")){
return getAll();
}
List list = null;
SQLiteDatabase db = database.getReadableDatabase();
String sql = "select * from contact where name like ? or phone like ?";
String[] params = new String[]{"%"+queryName+"%", "%"+queryName+"%"};
Cursor cursor = db.rawQuery(sql, params);
list = new ArrayList();
while(cursor.moveToNext()){
Contact contact = new Contact();
contact.setId(cursor.getInt(0));
contact.setNumber(cursor.getString(1));
contact.setName(cursor.getString(2));
contact.setPhone(cursor.getString(3));
contact.setEmail(cursor.getString(4));
contact.setAddress(cursor.getString(5));
contact.setGender(cursor.getString(6));
contact.setRelationship(cursor.getString(7));
contact.setRemark(cursor.getString(8));
list.add(contact);
}
cursor.close();
db.close();
return list;
}
public List getAll(){
List list = null;
SQLiteDatabase db = database.getReadableDatabase();
String sql = "select * from contact";
Cursor cursor = db.rawQuery(sql, null);
list = new ArrayList();
while(cursor.moveToNext()){
Contact contact = new Contact();
contact.setId(cursor.getInt(0));
contact.setNumber(cursor.getString(1));
contact.setName(cursor.getString(2));
contact.setPhone(cursor.getString(3));
contact.setEmail(cursor.getString(4));
contact.setAddress(cursor.getString(5));
contact.setGender(cursor.getString(6));
contact.setRelationship(cursor.getString(7));
contact.setRemark(cursor.getString(8));
list.add(contact);
}
cursor.close();
db.close();
return list;
}
public Contact getById(int id){
Contact contact = null;
if(id > 0){
SQLiteDatabase db = database.getReadableDatabase();
String sql = "select * from contact where _id=?";
String[] params = new String[] {String.valueOf(id)};
Cursor cursor = db.rawQuery(sql, params);
if(cursor.moveToNext()){
contact = new Contact();
contact.setId(cursor.getInt(0));
contact.setNumber(cursor.getString(1));
contact.setName(cursor.getString(2));
contact.setPhone(cursor.getString(3));
contact.setEmail(cursor.getString(4));
contact.setAddress(cursor.getString(5));
contact.setGender(cursor.getString(6));
contact.setRelationship(cursor.getString(7));
contact.setRemark(cursor.getString(8));
}
cursor.close();
db.close();
}
return contact;
}
public boolean update(Contact contact){
if(contact != null){
SQLiteDatabase db = database.getWritableDatabase();
ContentValues value = new ContentValues();
value.put("number", contact.getNumber());
value.put("name", contact.getName());
value.put("phone", contact.getPhone());
value.put("email", contact.getEmail());
value.put("address", contact.getAddress());
value.put("gender", contact.getGender());
value.put("relationship", contact.getRelationship());
value.put("remark", contact.getRemark());
db.update("contact", value, "_id=?", new String[]{String.valueOf(contact.getId())});
db.close();
return true;
}
else{
return false;
}
}
public void delete(int id){
if(id > 0){
SQLiteDatabase db = database.getWritableDatabase();
String sql = "delete from contact where _id = ?";
Object[] params = new Object[]{String.valueOf(id)};
db.execSQL(sql, params);
db.close();
}
}
}
Contact:
package com.qwe.model;
public class Contact {
private int id;
private String number=null;
private String name=null;
private String phone=null;
private String email=null;
private String address=null;
private String gender=null;
private String relationship=null;
private String remark=null;
public Contact(){
id=0;
number="";
name="";
phone="";
email="";
address="";
gender="";
relationship="";
remark="";
}
public void setId(int id){
this.id = id;
}
public int getId(){
return id;
}
public void setNumber(String number){
this.number = number;
}
public String getNumber(){
return number;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setPhone(String phone){
this.phone = phone;
}
public String getPhone(){
return phone;
}
public void setEmail(String email){
this.email = email;
}
public String getEmail(){
return email;
}
public void setAddress(String address){
this.address = address;
}
public String getAddress(){
return address;
}
public void setGender(String gender){
this.gender = gender;
}
public String getGender(){
return gender;
}
public void setRelationship(String relationship){
this.relationship = relationship;
}
public String getRelationship(){
return relationship;
}
public void setRemark(String remark){
this.remark = remark;
}
public String getRemark(){
return remark;
}
}
Service:
package com.qwe.service;
import java.util.List;
import com.qwe.dataaccess.DBOperation;
import com.qwe.model.Contact;
import android.content.Context;
public class Service {
private DBOperation dao=null;
public Service(Context context){
dao = new DBOperation(context);
}
public boolean save(Contact contact){
boolean flag = dao.save(contact);
return flag;
}
public List getByName(String queryName){
List list = dao.getByName(queryName);
return list;
}
public Contact getById(int id){
Contact contact = dao.getById(id);
return contact;
}
public boolean update(Contact contact){
boolean flag = dao.update(contact);
return flag;
}
public void delete(int id){
dao.delete(id);
}
}
4.2界面主要功能代码
activity_add:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:background="@color/white"
tools:context=".AddActivity" >
<ImageView
android:id="@+id/image_view"
android:layout_width="56dp"
android:layout_height="56dp"
android:scaleType="centerCrop"
android:src="@drawable/icon_boy"
android:contentDescription="@string/app_name" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/number"
android:textSize="20sp"/>
<EditText
android:id="@+id/contact_number"
android:inputType="number"
android:textColor="@color/grey_900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/number_hint"
android:textColorHint="@color/grey_300"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/name"
android:textSize="20sp"/>
<EditText
android:id="@+id/contact_name"
android:inputType="text"
android:textColor="@color/grey_900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/name_hint"
android:textColorHint="@color/grey_300" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phone"
android:textSize="20sp"/>
<EditText
android:id="@+id/contact_phone"
android:inputType="phone"
android:textColor="@color/grey_900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/phone_hint"
android:textColorHint="@color/grey_300" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/email"
android:textSize="20sp"/>
<EditText
android:id="@+id/contact_email"
android:inputType="textEmailAddress"
android:textColor="@color/grey_900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/email_hint"
android:textColorHint="@color/grey_300" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/address"
android:textSize="20sp"/>
<EditText
android:id="@+id/contact_address"
android:inputType="text"
android:textColor="@color/grey_900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/address_hint"
android:textColorHint="@color/grey_300" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/gender"
android:textSize="20sp"/>
<RadioGroup
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/male"/>
<RadioButton
android:id="@+id/female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/female"/>
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:layout_marginBottom="3dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/relationship"
android:textSize="20sp"/>
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/remark"
android:textSize="20sp"/>
<EditText
android:id="@+id/contact_remark"
android:inputType="text"
android:textColor="@color/grey_900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top"
android:hint="@string/remark_hint"
android:textColorHint="@color/grey_300" />
</LinearLayout>
</LinearLayout>
option_dialog:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:orientation="horizontal"
android:baselineAligned="false">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<ImageButton
android:id="@+id/dialog_call"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/yellow_700"
android:layout_centerHorizontal="true"
android:contentDescription="@string/call"
android:src="@drawable/ic_action_call" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/dialog_call"
android:text="@string/call_text"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<ImageButton
android:id="@+id/dialog_view"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@color/red_400"
android:layout_centerHorizontal="true"
android:contentDescription="@string/view_text"
android:src="@drawable/ic_action_person" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/dialog_view"
android:text="@string/view_text"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1" >
<ImageButton
android:id="@+id/dialog_sms"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#9bc703"
android:layout_centerHorizontal="true"
android:contentDescription="@string/sms"
android:src="@drawable/ic_action_chat" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/dialog_sms"
android:text="@string/sms_text"/>
</RelativeLayout>
</LinearLayout>
- 课设总结
通过本次课程设计,对于Android Studio的学习总结出以下几点心得;
独立思考,遇到问题首先学会分析Log打印error信息提示,比如:ClassNotFoundException,NullPointException,定位到类或xml报错的地方,重新检查代码的情况。
2.详细检查代码后,无法找到出错的地方(个人编程的思路或习惯),复制Error日志信息,打开百度搜索,查找资料,参考一下别人解决问题的方法。
3.参考资料,无法理解或独立思考后无法解决,这个时候询问一下“大神”,稍微指导一下,可能让你恍然大悟,TeachCourse可以帮忙解决遇到的问题。
在本次学习中,也学习到了很多书上并没有的内容,例如实现了应用程序域手机机能的连接实现,因而总结了以下内容:
①1.在AndroidManifest.xml 中申请权限:<uses-permission android:name="android.permission.CALL_PHONE" />
2.把电话号码转换成 Uri
String telstr = String.fromat("tel:%s", 手机号字符串);
Uri telUri = Uri.parse(telstr);
3. 在 Intent 中设置 ACTION_CALL 和 telUri
Intent intent = new Intent(Intent.ACTION_CALL, telUri);
4.拨号
context.startActivity(intent);
②Dao层:主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰,DAO层的数据源配置。
③service层:主要负责业务模块的逻辑应用设计,Service层的业务实现,具体要调用到已定义的DAO层的接口,封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。
参 考 文 献
[1]Android移动应用基础教程议长1.5等资源的管理与使用(界面)
[2]Android移动应用基础教程1.6.2LogCat(错误)
[3]Android移动应用基础教程4.2,4.3,4.4等内容(主跳转)
[4]Android移动应用基础教程5章内容(数据)
[5]以及参考csdn,百度文库及各种网站