《多媒体通信技术》
| 题 目: | 快递 | 
完 成 日 期 2022年05月
目 录
1 绪论1
2 设计方案2
2.1 设计思路和方案2
2.2 功能要求2
2.3 设计的流程图2
3 设计过程3
3.1 界面布局3
3.2 功能实现3
4 运行结果与分析4
4.1 设计的使用步骤4
4.2 运行结果与分析4
5 总结5
附录6
1 绪论
快递业务有两个基本的特点,一个是快件运转的速度快,另外一个特点是对快件进行全程跟踪为用户提供服务。业务之所以能快速运转,能在最短的时间内为用户提点对点的服务,一个很重要的因素就是有强大的信息系统做支撑,而且信息流必须领先于实物流。实物流在运转的过程中,信息系统如果不能对下一个环节提供前置信息,下一个环节就很难及时有效地调配资源,如调配航空资源,车辆等运力资源以及人力资源为实物流流向下一个环节做好准备。客户之所以选择快递公司,除了速度与价格上的因素之外,另外一个重要的因素是所提供服务,强大的管理系统是快递公司提升服务质量的唯一选择。另外一方面信息系统是快递公司运行效率的保证,快递物品在运输过程中希望以最高效、最经济的方式流向下一个环节,如果不能提供及时有效的实物流信息,就有可能造成公司资源的浪费或者是造成快递物品的投递时效性的降低。
2 设计方案
2.1 设计思路和方案
在移动互联网的时代,快递企业开发快递APP软件,可以帮助企业节省人力物力、简化操作程序、降低成本费用、加强与用户的信息交流。开发快递APP就能在移动互联网时代抢占到主动权,开拓更广阔的市场。
本次课题设计开发了一个快递查询录入系统,用户可以在注册登入之后进行快递的查询、输入、删除和修改。
系统需要包含注册、登入功能,保存账号和密码到SharedPreferences。按钮实现页面跳转和弹窗提示。利用SQLite进行增删查改的实现,实例化四个Button,两个EditText,两个TextView,连接数据库。按钮增加监听点击事件,editText用来获取输入,TextView来展示成果。
2.2 功能要求
本设计是快递查询录入系统的设计与实现,应具备的功能包括:
- 登陆;
- 注册;
(3)查询;
(4)输入;
(5)删除;
(6)修改。
2.3 设计的流程图
本设计中用户操作的流程图如图2.2所示。

图2.2 流程图
由图2.2可见,该设计首先要运行小手机然后会显示登录界面,如果是新用户就直接登录,如果不是需要注册一个账号进行登录。登录后可对快递订单输入/查询,还有选择快递公司。
3 设计过程
3.1 界面布局
本设计的登录界面布局如图3.1所示。

图3.1 登录界面布局
本设计的登录后快递输入/查询界面布局如图3.2所示。

图3.2 快递查询录入界面布局
3.2功能实现
1界面的实现
登入注册界面设计,包括用户名和密码的输入框,页面的输入框和按钮均采用了自定义样式,加入圆角的设计和颜色的渐变,视觉上看起来更舒适美观。
2菜单界面实现
登入成功后跳转到导航页面,每个按钮都会有对应的文字提示,对应要跳转到的各个子页面。
3各模块详细实现
增删查改详细设计包括输入、更新、查询、删除快递单号。
4快递公司页面实现
程序功能还包括登入和注册两个重要功能,用户的用户名和密码存放在sharedpreferences数据类中。
4 运行结果与分析
4.1 设计的使用步骤
本设计的使用步骤为:
- 首先打开模拟器运行小手机
- 已有账号直接登陆
- 没有账号注册一个账号然后登陆
- 点击订单输入/查询进行查询
- 可以输入,更新,查询,删除
- 查看寄快递公司
4.2 运行结果与分析
效果注册和登录如图4.1注册界面和4.2登录界面所示。

图4.1 注册界面

图4.2 登录界面
若账号没有注册过,将会显示此用户名不存在。如图4.3登陆失败界面所示。

图4.3 登陆失败界面
快递录入查询和快递公司界面如图4.4所示。

图4.4 快递录入查询和快递公司界面
点击订单输入/查询,页面跳转,在此页面可以对订单进行输入更新查询删除,效果如图4.5订单输入/查询页面所示。

图4.5 订单输入/查询界面
点击快递公司,可对快递公司进行查询,下拉还有其他快递公司可供选择。如图4.6快递公司界面所示。


图4.6 快递公司界面
5 总结
本设计主要完成了快递查询录入系统的设计与实现。回顾此次课程报告感慨颇多,在这次移动终端开发课程设计过程中,我发现平时学习的知识与实践环节所用到的有一定的差距,往往我觉得自己掌握的很好或者自认为熟练的技术却在此次实践环节中往往出问题,书本上的知识只提供方法的借鉴,实践中自己必须摸索出适合具体工作的方法,这一切都离不开钻研精神与勤学好问的精神.在人与人相处过程中我收获更大,首先要谦虚谨慎,不能自以为是,认为自己懂得很多,而仅仅埋头苦干,而不向他人请教,工作不但是实践与应用的过程,同时也是学习的过程。在这短短的时间里,让我深深的感觉到自己在实际应用中所学专业知识的匮乏。让我真真领悟到“学无止境”这句话的涵义。而老师在专业认识周中所讲的,都是课本上没有而对我们又非常实用的东西,这又给我们的实训增加了浓墨淡采的光辉。我懂得了实际生活中,专业知识是怎样应用与实践的。
在Android studio调试过程中我也遇到了很多问题,比如图片的选择,我刚开始选择的图片过于清晰,导致程序无法运行。后来选择大小较小的图片发现还是出错,回顾老师的课堂回放视频才发现老师讲过,需要将图片的格式也进行更改。
附录
- 登入实现代码
 public class LoginActivity extends AppCompatActivity {
 private TextView tv_main_title;//标题
 private TextView tv_back,tv_register,tv_find_psw;//返回键,显示的注册,找回密码
 private Button btn_login;//登录按钮
 private String userName,psw,spPsw;//获取的用户名,密码,加密密码
 private EditText et_user_name,et_psw;//编辑框
 @Override
 protected void onCreate(Bundle savedInstanceState){
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_login);
 //设置此界面为竖屏
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 init();
 }
 //获取界面控件
 private void init() {
 //从main_title_bar中获取的id
 tv_main_title=findViewById(R.id.tv_main_title);
 tv_main_title.setText("登录");
 tv_back=findViewById(R.id.tv_back);
 //从activity_login.xml中获取的
 tv_register=findViewById(R.id.tv_register);
 tv_find_psw=findViewById(R.id.tv_find_psw);
 btn_login=findViewById(R.id.btn_login);
 et_user_name=findViewById(R.id.et_user_name);
 et_psw=findViewById(R.id.et_psw);
 //返回键的点击事件
 tv_back.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //登录界面销毁
 LoginActivity.this.finish();
 }
 });
 //立即注册控件的点击事件
 tv_register.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //为了跳转到注册界面,并实现注册功能
 Intent intent=new Intent(LoginActivity.this,RegisterActivity.class);
 startActivityForResult(intent, 1);
 }
 });
 //找回密码控件的点击事件
 tv_find_psw.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //跳转到找回密码界面
 }
 });
 //登录按钮的点击事件
 btn_login.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //开始登录,获取用户名和密码 getText().toString().trim();
 userName=et_user_name.getText().toString().trim();
 psw=et_psw.getText().toString().trim();
 //对当前用户输入的密码进行MD5加密再进行比对判断, MD5Utils.md5( ); psw 进行加密判断是否一致
 String md5Psw= MD5Utils.md5(psw);
 // md5Psw ; spPsw 为 根据从SharedPreferences中用户名读取密码
 // 定义方法 readPsw为了读取用户名,得到密码
 spPsw=readPsw(userName);
 // TextUtils.isEmpty
 if(TextUtils.isEmpty(userName)){
 Toast.makeText(LoginActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
 return;
 }else if(TextUtils.isEmpty(psw)){
 Toast.makeText(LoginActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
 return;
 // md5Psw.equals(); 判断,输入的密码加密后,是否与保存在SharedPreferences中一致
 }else if(md5Psw.equals(spPsw)){
 //一致登录成功
 Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
 //保存登录状态,在界面保存登录的用户名 定义个方法 saveLoginStatus boolean 状态 , userName 用户名;
 saveLoginStatus(true, userName);
 //登录成功后关闭此页面进入主页
 Intent data=new Intent();
 //datad.putExtra( ); name , value ;
 data.putExtra("isLogin",true);
 //RESULT_OK为Activity系统常量,状态码为-1
 // 表示此页面下的内容操作成功将data返回到上一页面,如果是用back返回过去的则不存在用setResult传递data值
 setResult(RESULT_OK,data);
 //销毁登录界面
 LoginActivity.this.finish();
 //跳转到主界面,登录成功的状态传递到 MainActivity 中
 startActivity(new Intent(LoginActivity.this,Classification.class));
 return;
 }else if((spPsw!=null&&!TextUtils.isEmpty(spPsw)&&!md5Psw.equals(spPsw))){
 Toast.makeText(LoginActivity.this, "输入的用户名和密码不一致", Toast.LENGTH_SHORT).show();
 return;
 }else{
 Toast.makeText(LoginActivity.this, "此用户名不存在", Toast.LENGTH_SHORT).show();
 }
 }
 });
 }
 /**
 *从SharedPreferences中根据用户名读取密码
 */
 private String readPsw(String userName){
 //getSharedPreferences("loginInfo",MODE_PRIVATE);
 //"loginInfo",mode_private; MODE_PRIVATE表示可以继续写入
 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
 //sp.getString() userName, "";
 return sp.getString(userName , "");
 }
 /**
 *保存登录状态和登录用户名到SharedPreferences中
 */
 private void saveLoginStatus(boolean status,String userName){
 //saveLoginStatus(true, userName);
 //loginInfo表示文件名 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
 //获取编辑器
 SharedPreferences.Editor editor=sp.edit();
 //存入boolean类型的登录状态
 editor.putBoolean("isLogin", status);
 //存入登录状态时的用户名
 editor.putString("loginUserName", userName);
 //提交修改
 editor.commit();
 }
 /**
 * 注册成功的数据返回至此
 * @param requestCode 请求码
 * @param resultCode 结果码
 * @param data 数据
 */
 @Override
 //显示数据, onActivityResult
 //startActivityForResult(intent, 1); 从注册界面中获取数据
 //int requestCode , int resultCode , Intent data
 // LoginActivity -> startActivityForResult -> onActivityResult();
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 //super.onActivityResult(requestCode, resultCode, data);
 super.onActivityResult(requestCode, resultCode, data);
 if(data!=null){
 //是获取注册界面回传过来的用户名
 // getExtra().getString("***");
 String userName=data.getStringExtra("userName");
 if(!TextUtils.isEmpty(userName)){
 //设置用户名到 et_user_name 控件
 et_user_name.setText(userName);
 //et_user_name控件的setSelection()方法来设置光标位置
 et_user_name.setSelection(userName.length());
 }
 }
 }
 }
- 注册实现代码
 public class RegisterActivity extends AppCompatActivity {
 private TextView tv_main_title;//标题
 private TextView tv_back;//返回按钮
 private Button btn_register;//注册按钮
 //用户名,密码,再次输入的密码的控件
 private EditText et_user_name,et_psw,et_psw_again;
 //用户名,密码,再次输入的密码的控件的获取值
 private String userName,psw,pswAgain;
 //标题布局
 private RelativeLayout rl_title_bar;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 //设置页面布局 ,注册界面
 setContentView(R.layout.activity_register);
 //设置此界面为竖屏
 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
 init();
 }
 private void init() {
 //从main_title_bar.xml 页面布局中获取对应的UI控件
 tv_main_title=findViewById(R.id.tv_main_title);
 tv_main_title.setText("注册");
 tv_back=findViewById(R.id.tv_back);
 //布局根元素
 rl_title_bar=findViewById(R.id.title_bar);
 rl_title_bar.setBackgroundColor(Color.TRANSPARENT);
 //从activity_register.xml 页面中获取对应的UI控件
 btn_register=findViewById(R.id.btn_register);
 et_user_name=findViewById(R.id.et_user_name);
 et_psw=findViewById(R.id.et_psw);
 et_psw_again=findViewById(R.id.et_psw_again);
 tv_back.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //返回键
 RegisterActivity.this.finish();
 }
 });
 //注册按钮
 btn_register.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 //获取输入在相应控件中的字符串
 getEditString();
 //判断输入框内容
 if(TextUtils.isEmpty(userName)){
 Toast.makeText(RegisterActivity.this, "请输入用户名", Toast.LENGTH_SHORT).show();
 return;
 }else if(TextUtils.isEmpty(psw)){
 Toast.makeText(RegisterActivity.this, "请输入密码", Toast.LENGTH_SHORT).show();
 return;
 }else if(TextUtils.isEmpty(pswAgain)){
 Toast.makeText(RegisterActivity.this, "请再次输入密码", Toast.LENGTH_SHORT).show();
 return;
 }else if(!psw.equals(pswAgain)){
 Toast.makeText(RegisterActivity.this, "输入两次的密码不一样", Toast.LENGTH_SHORT).show();
 return;
 /**
 *从SharedPreferences中读取输入的用户名,判断SharedPreferences中是否有此用户名
 */
 }else if(isExistUserName(userName)){
 Toast.makeText(RegisterActivity.this, "此账户名已经存在", Toast.LENGTH_SHORT).show();
 return;
 }else{
 Toast.makeText(RegisterActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
 //把账号、密码和账号标识保存到sp里面
 /**
 * 保存账号和密码到SharedPreferences中
 */
 saveRegisterInfo(userName, psw);
 //注册成功后把账号传递到LoginActivity.java中
 // 返回值到loginActivity显示
 Intent data = new Intent();
 data.putExtra("userName", userName);
 setResult(RESULT_OK, data);
 //RESULT_OK为Activity系统常量,状态码为-1,
 // 表示此页面下的内容操作成功将data返回到上一页面,如果是用back返回过去的则不存在用setResult传递data值
 RegisterActivity.this.finish();
 }
 }
 });
 }
 /**
 * 获取控件中的字符串
 */
 private void getEditString(){
 userName=et_user_name.getText().toString().trim();
 psw=et_psw.getText().toString().trim();
 pswAgain=et_psw_again.getText().toString().trim();
 }
 /**
 * 从SharedPreferences中读取输入的用户名,判断SharedPreferences中是否有此用户名
 */
 private boolean isExistUserName(String userName){
 boolean has_userName=false;
 //mode_private SharedPreferences sp = getSharedPreferences( );
 // "loginInfo", MODE_PRIVATE
 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
 //获取密码
 String spPsw=sp.getString(userName, "");//传入用户名获取密码
 //如果密码不为空则确实保存过这个用户名
 if(!TextUtils.isEmpty(spPsw)) {
 has_userName=true;
 }
 return has_userName;
 }
 private void saveRegisterInfo(String userName,String psw){
 String md5Psw = MD5Utils.md5(psw);//把密码用MD5加密
 //loginInfo表示文件名, mode_private SharedPreferences sp = getSharedPreferences( );
 SharedPreferences sp=getSharedPreferences("loginInfo", MODE_PRIVATE);
 //获取编辑器, SharedPreferences.Editor editor -> sp.edit();
 SharedPreferences.Editor editor=sp.edit();
 //以用户名为key,密码为value保存在SharedPreferences中
 //key,value,如键值对,editor.putString(用户名,密码);
 editor.putString(userName, md5Psw);
 //提交修改 editor.commit();
 editor.commit();
 }
- 增删查改代码实现
public class DictActivity extends AppCompatActivity {
private Button insertButton, updateButton, searchButton, deleteButton;
private Button btn_xl1;
private EditText name, age;
private TextView show, showAge;
final DatabaseHelper dbHelper = new DatabaseHelper(DictActivity.this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dict);
btn_xl1 = findViewById(R.id.btn_xl);
btn_xl1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//创建Intent 对象
Intent intent = new Intent(DictActivity.this, Classification.class);
//启动Activity
startActivity(intent);
}
});
insertButton = findViewById(R.id.btn_insert);
updateButton = findViewById(R.id.btn_update);
searchButton = findViewById(R.id.btn_search);
deleteButton = findViewById(R.id.btn_delete);
name = findViewById(R.id.name);
age = findViewById(R.id.age);
show = findViewById(R.id.tv_show);
showAge = findViewById(R.id.tv_showAge);
SQLiteDatabase db = dbHelper.getReadableDatabase();
myShow();
insertButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name.getText().toString());
values.put("age", age.getText().toString());
long id = db.insert("information", null, values);
Log.d("myDeBug", "insert");
myShow();
db.close();
name.setText(null);
age.setText(null);
}
});
updateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("age", age.getText().toString());
db.update("information", values, "name=?", new String[]{name.getText().toString()});
myShow();
db.close();
Log.d("myDebug", "update");
name.setText(null);
age.setText(null);
}
});
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
String name1 = name.getText().toString();
show.setText(null);
if (name1.equals("")) {
// show.setText("姓名");
// showAge.setText("单号");
// Cursor cursor = db.rawQuery("select * from information",null);
//
// while (cursor.moveToNext()) {
// String newName = cursor.getString(cursor.getColumnIndex("name"));
// int newAge = cursor.getInt(cursor.getColumnIndex("age"));
// show.setText(show.getText() + "\n" + newName);
// showAge.setText(showAge.getText()+"\n" + newAge);
// }
myShow();
db.close();
} else {
show.setText("姓名");
showAge.setText("单号");
Cursor cursor = db.rawQuery("select * from information where name = ? ", new String[]{name1});
while (cursor.moveToNext()) {
String newName = cursor.getString(cursor.getColumnIndex("name"));
int newAge = cursor.getInt(cursor.getColumnIndex("age"));
// show.setText(show.getText() + "\n" + newName + "\t" + newAge);
show.setText(show.getText() + "\n" + newName);
showAge.setText(showAge.getText() + "\n" + newAge);
}
cursor.close();
db.close();
name.setText(null);
age.setText(null);
}
}
});
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("information", "name=?", new String[]{name.getText().toString()});
myShow();
db.close();
Log.d("myDeBug", "DeleteSuccess");
name.setText(null);
age.setText(null);
}
});
}
public void myShow() {
SQLiteDatabase db = dbHelper.getReadableDatabase();
show.setText("姓名");
showAge.setText("单号");
Cursor cursor = db.rawQuery("select * from information", null);
while (cursor.moveToNext()) {
String newName = cursor.getString(cursor.getColumnIndex("name"));
int newAge = cursor.getInt(cursor.getColumnIndex("age"));
show.setText(show.getText() + "\n" + newName);
showAge.setText(showAge.getText() + "\n" + newAge);
}
cursor.close();
}
}
public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context){super(context,"Test.db",null,1);}
//第一个参数是上下文,第二个参数是数据库名称,
//第三个参数是CursorFactory对象,一般设置为null,第四个参数是数据库的版本
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE information(_id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20),age INTEGER)");
}
//创建表 表名information 表结构 自增id,字符串姓名,int年龄
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("myDeBug","数据库版本已更新");










