Android开发项目--跑腿APP-跑儿
跑儿是一款跑腿APP,用户可以发布自己的跑腿需求然后跑手可以进行接单来完成相应的“任务”。
开发工具:Android Studio,SQLite Expert Professional,Photoshop
开发语言:Android,Java
1.初始界面
初始界面会有两个按钮,一个登录,一个注册,两个按钮分别加了监听,点击时会出现不同的响应。
2.注册
当点击注册界面时,会弹出一个AlertDialog的注册界面,头像选择采用的是一个网格布局来显示的,用户名跟密码采用了正则表达式来进行判断,当用户名或密码出现特殊字符时系统会弹出一个Toast提示用户名或密码格式错误,并清空你刚才输入的用户名跟密码让你重新输入,当你填写用户名时,会拿你这个用户名在数据库里进行查找比对,如果这个用户名在数据库中存在,则系统会提示用户名已被注册,你可以选择返回主页面直接进行登陆;当所有信息填写无误时点击注册,系统会弹出一个对话框提示你注册成功,点击返回主页登录,Dialog将关闭回到初始界面登录。
3.登陆
点击登录按钮,会弹出一个Dialog,输入注册时的账号跟密码,点击登录按钮,将你输入的账号跟密码去数据库进行进行查找,如果账号密码跟数据库的某条相同,则返回一个true并显示登录成功,否则显示登陆失败,登陆成功后系统会提示你打开地图定位权限,为了后面地图功能的正常运行。
4.管理员模式
管理员账号:liuaichao 密码:123456 进入管理员模式后,会将注册的数据库信息通过ListView呈现出来包括用户名,性别,手机号,头像,点击窗口右上角的按钮,会出现管理,点击管理后,每个用户的后面会出现删除按钮,点击删除可将此用户从数据库中删除,也可以点击对应的CheckBox来进行批量删除,给每个条目上面的CheckBox加监听,点击储存当前CheckBox的选中状态到对应条目的User对象里面去,避免适配器刷新后导致CheckBox恢复初始未选中状态。ListView的Adapter是继承了自己写的一个MyAdapter,为了方便数据的传入。
5.主页
主页是跑儿的订单编辑跟提交界面,左上角为你当前位置的定位,右上角为地图,这里使用了百度地图的API,给你在写起点终点时提供了一个位置参考和您当前位置的官方描述
物品类型采用了ArrayList跟下拉框的配合,使物品类型更加形象的展示出来,具体内容可以输入一些自己对跑手的要求;
点击提交按钮会弹出一个对话框提示订单提交成功,并清空刚才订单输入的信息,点击返回主页将返回到登陆成功界面(注:初始APP未加入金钱建议功能,因为接入第三方支付比如支付宝,微信等,需要企业的营业执照等相关信息的提交,所以未涉及金钱交易)
6.订单
订单界面是单独的一个数据库,为了实现单个用户拥有自己单独的订单,自己想了一个方法:单独建立一个数据库,根据getWritableDatabase()的用法打开或创建数据库,即当存在这个数据库是是打开,不存在时是创建,我想的是通过改变数据库的名字来实现订单的独立,当你登录成功时,获取你的用户名,因为用户名是不可重复的即唯一的,用这个用户名来创建或打开数据库,这样每个账户便有了一个自己唯一的订单管理库,可以查看历史订单跟新订单。每条订单信息包括起点,终点,备注,下单时间,订单状态,取消订单,地图,确认完成按钮,通过date中的toLocaleString()方法获取系统的下单时间来作为之后跑手版的订单唯一标识,状态会显示订单目前的状态,当跑手未接单时状态显示未接单,跑手接单后,会显示已接单,点击确认订单完成按钮后,会显示已完成,取消订单会将订单取消并且将订单从数据库中删除,地图按钮会显示你跟跑手之间的位置,跑手方会给你传一个经纬度坐标,然后跟你的经纬度进行骑行规划,来实时跟踪订单位置。
7.我的
“我的”界面,也就是简单个人信息界面,包括头像跟用户名,点击个人信息会跳转到详细的个人信息界面,点击切换到跑手版将会进入跑手界面,可进行接单操作。
8.个人信息
个人信息界面会从数据库中找到该条记录,然后详细的展示出来,默认用户名是不可修改的,点击密码栏的“点击修改”将进入修改密码的界面,输入旧密码,根据用户名去数据库中找出旧密码进行比对,成功返回true,新密码跟确认新密码进行一次比对,相同返回true,同样的,新密码也有正则表达式的验证,成功后,新密码将填入数据库,系统提示重新登录,确定后进入登陆界面;手机号可以直接修改,点击“保存”后会将修改的信息保存并返回“我的”界面;点击退出账号即退出当前账号,返回登陆界面。
9.跑手版
为了跟好的测试,我们加入了跑手版,也就是接单的模块,这个模块相当于一个大厅效果,所有的用户提交订单号一份数据传入自己私有的数据库,另一份传入“大厅”数据库,跑手版的数据也是有ListViev呈现出来的,点击电话按钮时,会根据你所点条目第position来确定某个用户的订单,然后根据用户注册时输入的手机号通过Uri.parse(“tel:”+tel)来调用系统拨号来给下单者拨号;点击“确认接单”按钮,该订单将从“大厅”数据库中删除,并修改私有数据库的状态为已接单,给下单者一个准确的提示。
下面部分代码(代码太长,有需要的可以在底下评论):
package com.example.thinkpad.apps.ui;import android.app.Activity;import android.content.ContentValues;import android.content.Intent;import android.database.sqlite.SQLiteDatabase;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageButton;import android.widget.Toast;import com.example.thinkpad.apps.R;import com.example.thinkpad.apps.dao.IUserDao;import com.example.thinkpad.apps.dao.impl.UserDaoDBImpl;import com.example.thinkpad.apps.dao.utils.CheckString;import com.example.thinkpad.apps.dao.utils.MyOpenHelper;public class ChangeActivity extends Activity implements View.OnClickListener { private ImageButton fanhui; private EditText oldpwd; private EditText newpwd; private EditText renewpwd; private Button enter; private IUserDao userDao; private MyOpenHelper mOpenHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_change); fanhui=findViewById(R.id.xg_fanhui); oldpwd=findViewById(R.id.xg_oldpwd); newpwd=findViewById(R.id.xg_newpwd); renewpwd=findViewById(R.id.xg_renewpwad); enter=findViewById(R.id.xg_enter); //监听 fanhui.setOnClickListener(this); enter.setOnClickListener(this); userDao= UserDaoDBImpl.getDao(this); mOpenHelper=new MyOpenHelper(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.xg_fanhui: Intent intent=new Intent(this,PersonActivity.class); startActivity(intent); finish(); break; case R.id.xg_enter: String old=oldpwd.getText().toString().trim(); String news=newpwd.getText().toString().trim(); String renew=renewpwd.getText().toString().trim(); String name=WelcomeActivity.Noname; if(CheckString.check(news)){ if(userDao.findUserPwd(old)&&news.equals(renew)){ Toast.makeText(this, "密码修改成功,请重新登录", Toast.LENGTH_SHORT).show(); //数据库进行修改 SQLiteDatabase db=mOpenHelper.getWritableDatabase(); ContentValues contentValues=new ContentValues(); contentValues.put("pwd",news); db.update("user",contentValues,"name=?",new String[]{name}); db.close(); Intent intent1=new Intent(this,WelcomeActivity.class); startActivity(intent1); this.overridePendingTransition(R.anim.main_in1,R.anim.main_out1); finish(); }else if(userDao.findUserPwd(old)==false){ Toast.makeText(this, "旧密码输入不正确,请重新输入", Toast.LENGTH_SHORT).show(); }else if((userDao.findUserPwd(old)==true)&&(news.equals(renew)==false)){ Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show(); } }else{ Toast.makeText(this, "密码中含有非法字符或密码长度短", Toast.LENGTH_SHORT).show(); } break; } }}package com.example.thinkpad.apps.ui;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.Intent;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.provider.ContactsContract;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.ImageButton;import android.widget.Spinner;import android.widget.TextView;import java.util.Date;import com.example.thinkpad.apps.IUserDao2;import com.example.thinkpad.apps.R;import com.example.thinkpad.apps.dao.IUserDao3;import com.example.thinkpad.apps.dao.entity.User;import com.example.thinkpad.apps.dao.entity.User2;import com.example.thinkpad.apps.dao.entity.User3;import com.example.thinkpad.apps.dao.impl.UserDaoDBImpl2;import com.example.thinkpad.apps.dao.impl.UserDaoDBImpl3;import com.example.thinkpad.apps.dao.utils.MyOpenHelper;import com.example.thinkpad.apps.dao.utils.MyOpenHelperPao;import com.example.thinkpad.apps.map.Ditu;import java.util.ArrayList;import java.util.List;public class jinru extends Activity implements View.OnClickListener { private TextView dn_didian; private ImageButton dn_ditu; private EditText dn_qidian; private EditText dn_zhongdian; private EditText dn_jiner; private EditText dn_neirong; private Spinner dn_spinner; private Button dn_tijiao; private Button dn_zhuye; private Button dn_dingdan; private Button dn_wode; private List list; private Date loca_time; private IUserDao2 userDao; private IUserDao3 userDao3; private AlertDialog.Builder mBuilder2; private AlertDialog.Builder mBuilder3; private AlertDialog alertDialog2; private AlertDialog alertDialog3; private static MyOpenHelper mOpenHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.zhuye); //实例化对象 dn_didian=findViewById(R.id.didian); dn_ditu=findViewById(R.id.ditu); dn_qidian=findViewById(R.id.zy_qidian); dn_zhongdian=findViewById(R.id.zy_zhongdian); dn_jiner=findViewById(R.id.zy_jiner); dn_neirong=findViewById(R.id.zy_neirong); dn_spinner=findViewById(R.id.spinner); dn_tijiao=findViewById(R.id.zy_tijiao); dn_zhuye=findViewById(R.id.zy_zhuye); dn_dingdan=findViewById(R.id.zy_dingdan); dn_wode=findViewById(R.id.zy_wode); mOpenHelper=new MyOpenHelper(this); //设置按钮的监听 dn_ditu.setOnClickListener(this);//地图 dn_tijiao.setOnClickListener(this);//提交 dn_zhuye.setOnClickListener(this);//主页 dn_zhuye.setEnabled(false);//主页 dn_dingdan.setOnClickListener(this);//订单 dn_wode.setOnClickListener(this);//我的 dn_didian.setText(Ditu.weizhi); list = new ArrayList(); list.add("---请选择物品类型---"); list.add("快递"); list.add("食品"); list.add("电子产品"); list.add("大型物品>50kg"); list.add("代购"); list.add("其他"); final ArrayAdapter adapter=new ArrayAdapter(this, android.R.layout.simple_spinner_item,list); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); dn_spinner.setAdapter(adapter); //时间 loca_time=new Date(); userDao= UserDaoDBImpl2.getDao(this,WelcomeActivity.Noname,null,1); userDao3= UserDaoDBImpl3.getDao(this); //提交成功弹出对话框 mBuilder2=new AlertDialog.Builder(this); mBuilder2.setTitle(""); mBuilder2.setMessage("订 单 提 交 成 功"); mBuilder2.setPositiveButton("返回主页", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dn_qidian.setText(""); dn_zhongdian.setText(""); dn_jiner.setText(""); dn_neirong.setText(""); alertDialog2.dismiss(); adapter.notifyDataSetChanged(); } }); alertDialog2=mBuilder2.create(); //返回键监听提示框 mBuilder3=new AlertDialog.Builder(this); mBuilder3.setTitle(""); mBuilder3.setMessage("您 确 定 要 退 出 吗"); mBuilder3.setPositiveButton("退出", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); alertDialog3.dismiss(); adapter.notifyDataSetChanged(); } }); mBuilder3.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { alertDialog3.dismiss(); adapter.notifyDataSetChanged(); } }); alertDialog3=mBuilder3.create();}public void askGoOn2(){ alertDialog2.show();}public void onBackPressed() { alertDialog3.show();}//按钮监听@Overridepublic void onClick(View v) { switch (v.getId()){ case R.id.ditu: Intent intent=new Intent(this, Ditu.class); startActivity(intent); this.overridePendingTransition(R.anim.main_in4,R.anim.main_out4); finish(); break; case R.id.zy_tijiao://提交订单按钮实现 String name=WelcomeActivity.Noname; String qidian=dn_qidian.getText().toString(); String zhongdian=dn_zhongdian.getText().toString(); String jiner=dn_jiner.getText().toString(); String neirong=dn_neirong.getText().toString(); String time= loca_time.toLocaleString(); //查找电话 String tel; tel=""; SQLiteDatabase db=mOpenHelper.getWritableDatabase(); String sql="select * from user where name=?"; Cursor cursor=db.rawQuery(sql,new String[]{name}); while (cursor.moveToNext()){ tel=cursor.getString(cursor.getColumnIndex("tel")); } String state="未接单"; User2 u=new User2(); u.setStart(qidian); u.setFina(zhongdian); u.setRemark(neirong); u.setTime(time); u.setState(state); u.setNamer(name); userDao.addUser(u); //写入add数据库 User3 u1=new User3(); u1.setStart(qidian); u1.setFina(zhongdian); u1.setRemark(neirong); u1.setTime(time); u1.setState(state); u1.setNamer(name); u1.setTel(tel); userDao3.addUser(u1); askGoOn2(); break; case R.id.zy_zhuye: break; case R.id.zy_dingdan: Intent intent1=new Intent(this,ResultActivity2.class); startActivity(intent1); this.overridePendingTransition(R.anim.main_in1,R.anim.main_out1); finish(); break; case R.id.zy_wode: Intent intent2=new Intent(this,WodeActivity.class); startActivity(intent2); this.overridePendingTransition(R.anim.main_in1,R.anim.main_out1); finish(); break; }}}package com.example.thinkpad.apps.ui;import android.app.Activity;import android.content.ContentValues;import android.content.Intent;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import com.example.thinkpad.apps.R;import com.example.thinkpad.apps.dao.utils.MyOpenHelper;public class PersonActivity extends Activity implements View.OnClickListener { private Button fanhui; private Button baocun; private Button tuichu; private Button xiugai; private ImageView head; private TextView zhanghao; private EditText tel; private MyOpenHelper mOpenHelper; private String namer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_person); //实例化 fanhui=findViewById(R.id.ps_fanhui); baocun=findViewById(R.id.ps_baocun); tuichu=findViewById(R.id.ps_tuichu); xiugai=findViewById(R.id.ps_xiugai); head=findViewById(R.id.ps_head); zhanghao=findViewById(R.id.ps_zhanghao); tel=findViewById(R.id.ps_tel); mOpenHelper=new MyOpenHelper(this); //按钮监听 fanhui.setOnClickListener(this); baocun.setOnClickListener(this); tuichu.setOnClickListener(this); xiugai.setOnClickListener(this); //信息展示 xinxishow(); } private void xinxishow() { SQLiteDatabase db=mOpenHelper.getWritableDatabase(); String sql="select * from user where name=?"; Cursor cursor=db.rawQuery(sql,new String[]{WelcomeActivity.Noname}); while(cursor.moveToNext()){ namer=cursor.getString(cursor.getColumnIndex("name")); head.setImageResource(cursor.getInt(cursor.getColumnIndex("headImg")));//设置头像 zhanghao.setText(namer); tel.setText(cursor.getString(cursor.getColumnIndex("tel"))); } }@Overridepublic void onClick(View v) { switch(v.getId()){ case R.id.ps_fanhui://取消 Intent intent3=new Intent(this,WodeActivity.class); startActivity(intent3); this.overridePendingTransition(R.anim.main_in2,R.anim.main_out2); finish(); break; case R.id.ps_baocun://保存电话 String ntel=tel.getText().toString().trim(); String nname=zhanghao.getText().toString().trim(); SQLiteDatabase db=mOpenHelper.getWritableDatabase(); ContentValues contentValues=new ContentValues(); contentValues.put("tel",ntel); db.update("user",contentValues,"name=?",new String[]{nname}); db.close(); Toast.makeText(this, "信息保存成功", Toast.LENGTH_SHORT).show(); Intent intent=new Intent(this,WodeActivity.class); startActivity(intent); this.overridePendingTransition(R.anim.main_in1,R.anim.main_out1); finish(); break; case R.id.ps_xiugai://修改密码 Intent intent1=new Intent(this,ChangeActivity.class); startActivity(intent1); break; case R.id.ps_tuichu://退出 Intent intent2=new Intent(this,WelcomeActivity.class); startActivity(intent2); this.overridePendingTransition(R.anim.main_in1,R.anim.main_out1); finish(); break; }}}package com.example.thinkpad.apps.ui;import android.app.Activity;import android.app.Dialog;import android.content.Intent;import android.database.sqlite.SQLiteDatabase;import android.os.Bundle;import android.util.Log;import android.view.View;import android.view.Window;import android.widget.Button;import android.widget.EditText;import android.widget.Toast;import com.example.thinkpad.apps.R;import com.example.thinkpad.apps.dao.IUserDao;import com.example.thinkpad.apps.dao.impl.UserDaoDBImpl;import com.example.thinkpad.apps.dao.utils.CheckString;import com.example.thinkpad.apps.dao.utils.MyOpenHelper;public class WelcomeActivity extends Activity implements View.OnClickListener{private Button item_login;private Button item_reg;private EditText mEdtLoginname;//用户名输入框private EditText mEdtLoginpwd;//密码输入框private Button mBtLogingo;private Button mBtLogincancel;private IUserDao userDao;private Button denglu;private Button zhuce;private Dialog dig_login;private UserDaoDBImpl userDaoDB;public static String Noname;@Overrideprotected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_welcome); userDao=UserDaoDBImpl.getDao(this); dig_login=new Dialog(this); dig_login.setContentView(R.layout.login_dig); dig_login.setTitle("登录"); denglu=(Button) findViewById(R.id.denglu);//登录按钮 zhuce=(Button) findViewById(R.id.zhuce);//注册按钮 //登录界面监控 mEdtLoginname=(EditText)dig_login.findViewById(R.id.edt_loginname); mEdtLoginpwd=(EditText)dig_login.findViewById(R.id.edt_loginpwd); mBtLogingo=(Button)dig_login.findViewById(R.id.bt_logingo); mBtLogincancel=(Button)dig_login.findViewById(R.id.bt_logincancel); denglu.setOnClickListener(this); zhuce.setOnClickListener(this); mBtLogingo.setOnClickListener(this); mBtLogincancel.setOnClickListener(this); }@Overridepublic void onClick(View v) { switch (v.getId()){ case R.id.denglu://登录进入监听 dig_login.show(); break; case R.id.bt_logingo://登录监听 String name=mEdtLoginname.getText().toString(); String pwd=mEdtLoginpwd.getText().toString(); if(CheckString.check(name)&&CheckString.check(pwd)){ //判断数据库中是否有数据,能否登录 if(userDao.findUserByNameAndPwd(name,pwd)){ Toast.makeText(this, "登陆成功", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "请开启地图定位权限", Toast.LENGTH_SHORT).show(); Noname=name; Intent intent=new Intent(this,jinru.class); startActivity(intent); this.overridePendingTransition(R.anim.main_in1,R.anim.main_out1); dig_login.cancel(); finish(); }else if(name.equals("liuaichao")&&pwd.equals("123456")){ Toast.makeText(this, "进入管理员模式", Toast.LENGTH_SHORT).show(); Intent intent=new Intent(this,ResultActivity.class); startActivity(intent); } else { Toast.makeText(this, "账号或密码错误,请重新输入", Toast.LENGTH_SHORT).show(); } }else{ Toast.makeText(this, "用户名或密码格式错误,请重新输入", Toast.LENGTH_SHORT).show(); } break; case R.id.bt_logincancel://取消监听 dig_login.cancel(); break; case R.id.zhuce: Toast.makeText(this, "注册", Toast.LENGTH_SHORT).show(); Intent intent=new Intent(this,RegActivity.class); startActivity(intent); break; }}}
更多相关文章
- [Android开发实战]Android手势密码(支付宝手势密码)实现(支持2.x)
- Android(安卓)Widget开发详解
- Android仿微信下拉列表实现(附源码)
- android 9 patch
- 第2步:第一个“Hello,world!”之Android(安卓)App(从零开始学Andro
- Android单选和多选按钮的使用
- 旋转中 android 的视图按钮
- Android(安卓)Framework 之HelloWorld(一)
- Android中SharedPreferences的使用(登陆,记住密码)