资源描述
Android实训-无线点餐系统1需求分析传统的餐饮行业,点餐过程都是由餐厅服务员人工完成的。通常的过程是这样的,客人进入餐厅后,选择好桌位开始点餐,服务员等待客人点餐完成,将客人的点餐内容送到厨房,由厨师下厨做菜。这一过程对于一个很小的餐馆来说没有问题,但是如果餐馆比较大,客人比较多。客人的等待时间比较长。为了解决这个问题,出现的无线点餐系统,该系统一般有无线终端(一般是一个PDA)、无线路由器和后台服务器组成。这种技术架构很成熟,但是存在一个弊端就是PDA的价格较高,并且PDA只能作为点餐使用,这无形中增加的系统成本,也造成了资源的浪费。有了Android系统,我们就可以在Android系统中开发一套客户端软件来完成点餐功能,Android手机的其它功能(如:打电话、发短信)照常使用。这样首先系统的成本会降低,其次,Android系统功能强大,界面组件丰富,软件的功能自然会强大很多,用户操行更流畅,界面展现更完美。本项目主要面向具有一定规模,需要提高餐厅点餐效率,体现出现代化的气氛,改进客人就餐环境,并借此提高经济效益的餐厅和酒店。要求项目不会占用太大的预算,并能够尽量沿用原有的成熟的技术,能够与原有系统进行良好的整合。2项目架构2.1 系统物理架构系统的物理架构是这样的,客户端Android系统智能手机,通过无线网络访问后台服务器,如果需要数据访问,则访问后台数据库。系统物理结构图如图1.1所示。图1.1 无线点餐系统物理结构2.2 技术选型Android客户端应用使用Java技术,网络通信使用Apache HTTP 协议客户端。中间WEB服务器采用Servlet相应客户请求。后台数据库采用JDBC访问数据库,客户端的一部分数据存储我们采用SQLite数据库,这里要涉及到Android客户端的数据和服务器中的数据的同步问题。 图1.2 技术选型 3功能模块的设计3.1客户端客户端主要有以下几个模块构成:登陆、点餐、更新、结账等功能。机构图见2.1无线点餐系统登陆点菜更新结账查台转台并台开桌点菜更新菜谱更新桌号图2.1模块图3.2数据库 数据表及对应关系见图2.24任务分工负责部分:无线点餐系统的转台、并台模块的客户端与服务器端的实现部分。5功能介绍5.1转台功能转台功能是指顾客下单后,要求更换座位,这是需要更改已经提交的数据。更改的过程是根据订单号找到该订单对应的桌号,将该桌号更改为更换后的桌号。程序运行界面如下图所示5.2并台功能并台功能是将已经下单的两组顾客合并到一张桌子的过程,该过程也需要更换已经提交到数据库中的数据。更新内容包括人数的合并、订单的更新、订单详细的更新和桌位状态的更新。程序运行界面如下图所示6模块实现及代码6.1转台模块客户端实现转台模块要实现的功能是:当顾客开桌或下单后要求更换桌位的过程。这一过程需要更新保存在服务器数据库库中的数据,具体更新的是OrderTbl表中该订单对应的桌号以及更换桌位的状态。具体实现步骤如下 (1).定义一个名为“change_table.xml”的布局文件,该布局文件外层使用LinearLayout布局,内层嵌套TableLayout,TableLayout中有两行要求用户输入订单编号和更换桌号。该布局作为自定义视图添加到弹出对话框中提示用户输入信息。(2).在工程的“MainMenuActivity”类中定义一个changeTable()方法,该方法首先实例化定义的布局文件,将其添加到AlertDialog中,在对话框的确定方法中获得该订单编号和更换桌号,调用服务器Servlet,更新数据,并显示更新结果。转台模块Android客户端实现package com.xxu.amarker;import java.io.IOException;import java.io.InputStream;import .MalformedURLException;import .URL;import .URLConnection;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.os.Bundle;import android.view.LayoutInflater;import android.view.Menu;import android.view.View;import android.widget.EditText;import android.widget.GridView;import android.widget.SimpleAdapter;import android.widget.Spinner;import android.widget.SpinnerAdapter;import android.widget.TextView;import android.widget.Toast;import com.xxu.amarker.util.HttpUtil;public class MainMenuActivity extends Activity public void changeTable() LayoutInflater inflater = LayoutInflater.from(this);View v = inflater.inflate(R.layout.chang_table, null);final EditText et1 = (EditText) v.findViewById(R.id.change_table_order_number_EditText);final EditText et2 = (EditText) v.findViewById(R.id.change_table_to_EditText);AlertDialog.Builder build = new AlertDialog.Builder(this);build.setMessage(真的要换桌位吗?).setCancelable(false).setView(v).setPositiveButton(确定, new DialogInterface.OnClickListener() Overridepublic void onClick(DialogInterface dialog, int which) / TODO Auto-generated method stubString orderId = et1.getText().toString();String tableNo = et2.getText().toString();String queryString = orderId= + orderId + &tableNo=+ tableNo;String url = HttpUtil.BASE_URL+ servlet/ChangeTableServlet? + queryString;String result = HttpUtil.queryStringForPost(url);Toast.makeText(MainMenuActivity.this, result,Toast.LENGTH_LONG).show();).setNegativeButton(取消, new OnClickListener() Overridepublic void onClick(DialogInterface dialog, int which) / TODO Auto-generated method stubdialog.cancel(););AlertDialog alert = build.create();alert.show();public void unionTable() LayoutInflater inflater=LayoutInflater.from(this);View v=inflater.inflate(R.layout.union_table, null);final Spinner spinner1=(Spinner) v.findViewById(R.id.union_table_spinner1);final Spinner spinner2=(Spinner) v.findViewById(R.id.union_table_spinner2);String urlStr=HttpUtil.BASE_URL+servlet/UnionTableServletXml;try URL url=new URL(urlStr);URLConnection conn=url.openConnection();InputStream in=conn.getInputStream();DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();DocumentBuilder builder=factory.newDocumentBuilder();Document doc=builder.parse(in);NodeList nl=doc.getElementsByTagName(table);List items=new ArrayList();for (int i = 0; i nl.getLength(); i+) String id=doc.getElementsByTagName(id).item(i).getFirstChild().getNodeValue();Map data=new HashMap();data.put(id, id);items.add(data);SpinnerAdapter as =new SimpleAdapter(this, items, android.R.layout.simple_spinner_item, new Stringid, new intandroid.R.id.text1);spinner1.setAdapter(as);spinner2.setAdapter(as); catch (MalformedURLException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (ParserConfigurationException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (SAXException e) / TODO Auto-generated catch blocke.printStackTrace();AlertDialog.Builder builder =new AlertDialog.Builder(this);builder.setMessage(真的要并桌吗?).setCancelable(false).setView(v).setPositiveButton(确定, new OnClickListener() Overridepublic void onClick(DialogInterface dialog, int which) / TODO Auto-generated method stubTextView tv1=(TextView) spinner1.getSelectedView();TextView tv2=(TextView) spinner2.getSelectedView();String tableNum1=tv1.getText().toString();String tableNum2=tv2.getText().toString();String queryString = tableNum1= + tableNum1 + &tableNum2=+ tableNum2;String url = HttpUtil.BASE_URL+ servlet/UnionTableServlet? + queryString;String result = HttpUtil.queryStringForPost(url);).setNegativeButton(取消, new DialogInterface.OnClickListener() Overridepublic void onClick(DialogInterface dialog, int which) / TODO Auto-generated method stubdialog.cancel(););AlertDialog alert=builder.create();alert.show();Overridepublic void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState);setContentView(R.layout.activity_main_menu);GridView gridView = (GridView) findViewById(R.id.gridView1);/ 使用adapter 给gridView组件填充数据gridView.setAdapter(new ImageAdapter(this);Overridepublic boolean onCreateOptionsMenu(Menu menu) getMenuInflater().inflate(R.menu.activity_main_menu, menu);return true;6.2转台模式服务器端实现为了响应Android客户端的请求需要定义Servlet,为了更新数据库需要定义DAO接口来操作数据库。(1).在工程中定义一个ChangeTableDao接口,在该接口中定义一个转台方法changeTable().package com.amaker.dao;/ 转台DAO接口public interface ChangeTableDao / 转台方法public void changeTable(int orderId,int tableId);(2) 在工程的“com.amaker.dao”包中定义一个ChangeTableDaoImpl类实现上述接口,该类需要更新订单表以及更换桌位的状态,为此本代码的实现使用了事务控制。 package com.amaker.dao.impl;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;import com.amaker.dao.ChangeTableDao;import com.amaker.util.DBUtil;/* * author 郭宏志 * 完成转台功能 */public class ChangeTableDaoImpl implements ChangeTableDao public void changeTable(int orderId, int tableId) / 更新SQL语句String sql = update TableTbl set flag = 0 where id = + (select tableId from OrderTbl as ot where ot.id = ?);String sql2 = update OrderTbl set tableId = ? where id = ? ;String sql3 = update TableTbl set flag = 1 where id = ?;/ 数据库连接工具类DBUtil util = new DBUtil();/ 获得连接Connection conn = util.openConnection();try conn.setAutoCommit(false);/ 获得预定义语句PreparedStatement pstmt = conn.prepareStatement(sql);pstmt.setInt(1, orderId);/ 更新桌位状态pstmt.executeUpdate();pstmt = conn.prepareStatement(sql2);/ 设置参数pstmt.setInt(1, tableId);pstmt.setInt(2, orderId);/ 更新订单表pstmt.executeUpdate();pstmt = conn.prepareStatement(sql3);pstmt.setInt(1, tableId);/ 更新桌位状态pstmt.executeUpdate();mit(); catch (SQLException e) e.printStackTrace();try conn.rollback(); catch (SQLException e1) e1.printStackTrace(); finally util.closeConn(conn);(3).在工程的“com.amaker.servlet”包中定义一个名为“ChangeTableServlet”的Servlet类,该类响应客户端请求,调用DAO更新数据库数据,返回信息给客户端package com.amaker.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.amaker.dao.ChangeTableDao;import com.amaker.dao.impl.ChangeTableDaoImpl;/* * author 郭宏志 * 完成转台功能 */public class ChangeTableServlet extends HttpServlet / 构造方法public ChangeTableServlet() super();/ 销毁方法public void destroy() super.destroy(); / 响应Get请求public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException response.setContentType(text/html);PrintWriter out = response.getWriter();/ 获得请求参数String orderId = request.getParameter(orderId);String tableId = request.getParameter(tableId);/ 实例化ChangeTableDaoChangeTableDao dao = new ChangeTableDaoImpl();/ 调用转台方法dao.changeTable(Integer.parseInt(orderId), Integer.parseInt(tableId);/ 返回客户端信息out.println(更换成功!);out.flush();out.close();/ 响应Post请求public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException doGet(request,response);/ 初始化方法public void init() throws ServletException 6.3并台模块客户端实现(1).并台通过弹出对话框的方式来提示用户的,为此在对话框中添加自定义视图,提示永华选择要更换的桌位。在工程的reslayout目录下创建一个名为union_table.xml的布局文件,该布局文件外层使用LinearLayout布局,内层嵌套TableLayout,TableLayout中有两行,每行通过一个Spinner提示用户选择桌号。(2).在MainMenuActivity类中创建一个名为unionTable()的方法,该方法定义了一个对话框提示用户选择合并桌号,在对话框中添加了自定义视图,访问服务器获得桌位信息并绑定到Spinner,然后在确定方法中提交合并请求。接着创建一个并台监听器,调用unionTable方法private void unionTable()/ 实例化LayoutInflaterLayoutInflater inflater = LayoutInflater.from(this);/ 获得自定义视图View v =inflater.inflate(R.layout.union_table, null);/ 获得Spinnerfinal Spinner spinner1 = (Spinner) v.findViewById(R.id.union_table_Spinner1);final Spinner spinner2 = (Spinner) v.findViewById(R.id.union_table_Spinner2);/ 访问服务器的URLString urlStr = HttpUtil.BASE_URL + servlet/UnionTableServlet;try / 实例化URLURL url = new URL(urlStr);/ URLConnection 实例URLConnection conn = url.openConnection();/ 获得输入流InputStream in = conn.getInputStream();/ 获得DocumentBuilderFactory对象DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();/ 获得DocumentBuilder对象DocumentBuilder builder = factory.newDocumentBuilder();/ 获得Document对象Document doc = builder.parse(in);/ 获得节点列表NodeList nl = doc.getElementsByTagName(table);/ Spinner数据List items = new ArrayList();/ 获得XML数据for (int i = 0; i nl.getLength(); i+) / 桌位编号String id = doc.getElementsByTagName(id).item(i).getFirstChild().getNodeValue();/ 桌号int num = Integer.parseInt(doc.getElementsByTagName(num).item(i).getFirstChild().getNodeValue();Map data = new HashMap();data.put(id, id);items.add(data);/ 获得SpinnerAdapterSpinnerAdapter as = new SimpleAdapter(this, items, android.R.layout.simple_spinner_item,new String id , new int android.R.id.text1 );/ 绑定数据spinner1.setAdapter(as);spinner2.setAdapter(as); catch (Exception e) e.printStackTrace();AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage( 真的要并桌吗?) .setCancelable(false) .setView(v) .setPositiveButton(确定, new DialogInterface.OnClickListener() public void onClick(DialogInterface dialog, int id) TextView tv1 = (TextView) spinner1.getSelectedView(); TextView tv2 = (TextView) spinner2.getSelectedView(); String tableId1 = tv1.getText().toString(); String tableId2 = tv2.getText().toString(); / 查询参数 String queryString = tableId1=+tableId1+&tableId2=+tableId2; / url String url = HttpUtil.BASE_URL+servlet/UnionTableServlet2?+queryString; / 查询返回结果 String result = HttpUtil.queryStringForPost(url); ) .setNegativeButton(取消, new DialogInterface.OnClickListener() public void onClick(DialogInterface dialog, int id) dialog.cancel(); );AlertDialog alert = builder.create();alert.show();6.4并台模块服务器端实现1. 在工程“com.amaker.dao”包中创建一个UnionTableDao接口。该接口中有两个方法,分别用来获得桌位列表和更新合并后的数据。package com.amaker.dao;import java.util.List;/ 并台功能接口public interface UnionTableDao / 获得桌位列表public List getTableList();/ 更新合并后的数据public void updateStatus(int tableId1,int tableId2);2. 在工程的“com.amaker.dao.impl”包中定义一个UnionTableDaoImpl类实现UnionTableDao。package com.amaker.dao.impl;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.List;import com.amaker.dao.UnionTableDao;import com.amaker.entity.UnionTable;import com.amaker.util.DBUtil;/* * author 郭宏志 * 实现并台功能 */public class UnionTableDaoImpl implements UnionTableDao public List getTableList() / 查询SQL语句String sql = select id,num from TableTbl where flag = 1 ;/ 数据库连接工具类DBUtil util = new DBUtil();/ 获得连接Connection conn = util.openConnection();try / 获得预定义语句Statement pstmt = conn.createStatement();/ 执行查询ResultSet rs = pstmt.executeQuery(sql);/ 判断订单详细List list = new ArrayList();while (rs.next() / 获得菜单信息int id = rs.getInt(1);int num = rs.getInt(2);UnionTable ut = new UnionTable();ut.setId(id);ut.setNum(num);list.add(ut);return list; catch (SQLException e) e.printStackTrace(); finally util.closeConn(conn);return null;public void updateStatus(int tableId1,int tableId2) / 数据库连接工具类DBUtil util = new DBUtil();/ 获得连接Connection conn = util.openConnection();CallableStatement cstmt;try cstmt = conn.prepareCall(call new_proc(?,?);cstmt.setInt(1, tableId1);cstmt.setInt(2, tableId2);cstmt.execute(); catch (SQLException e) e.printStackTrace();3. 定义Servlet响应Android客户端请求,调用DAO更新合并数据。7参考Android应用开发详解 郭宏志 编著
展开阅读全文