前言
进行综合设计的时候,要求做个javaweb
项目并挂到服务器上,与此同时在Android上通过访问后台接口实现部分功能。经过了一番的摸索和踩坑,终于实现了和后台服务的通信登陆注册和信息列表显示功能。这是 github
地址,先看一下效果。
项目介绍
目录结构介绍
功能介绍
登陆功能
首先在layout
目录下新建xml文件进行布局和定义样式,然后注册事件进行监听,通过intent
对象控制activity的跳转,MainActivity类
public class MainActivity extends Activity implements OnClickListener{
//声明全局控件
private EditText mPhoneNumberEditText;
private EditText mPassWordEditText;
private Button mLoginButton, mRegisterButton;
private RadioButton admin, user;
private String originAddress = "http://47.97.193.151/parkingsystem2/Login"; //登陆请求的网址接口
Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
String result = "";
if ("OK".equals(msg.obj.toString())){
result = "success";
}else if ("Wrong".equals(msg.obj.toString())){
result = "fail";
}else {
String data = msg.obj.toString();
// Toast.makeText(MainActivity.this, data, Toast.LENGTH_LONG).show();
try {
JSONObject jsonObject = new JSONObject(data);
String code = jsonObject.getString("code");
if (code.equals("1")) {
result = jsonObject.getString("data");
//通过Bundle封装数据在intent对象中,传递到不同的activity
Bundle bundle = new Bundle();
bundle.putString("data", result);
//通过Intent控制Activity跳转
Intent intent = new Intent();
intent.setClass(MainActivity.this, ListActivity.class);
intent.putExtras(bundle);
finish();
startActivity(intent);
}else {
result = jsonObject.getString("data");
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
//初始化控件方法
private void initView() {
mPhoneNumberEditText = (EditText) findViewById(R.id.phoneNumberEditText);
mPassWordEditText = (EditText) findViewById(R.id.passwordEditText);
mLoginButton = (Button) findViewById(R.id.loginButton);
mRegisterButton = (Button) findViewById(R.id.registerButton);
admin = (RadioButton)findViewById(R.id.admin);
user = (RadioButton)findViewById(R.id.user);
}
//注册事件方法
private void initEvent() {
mLoginButton.setOnClickListener(this);
mRegisterButton.setOnClickListener(this);
}
private boolean isInputValid() {
//检查用户输入的合法性,这里暂且默认用户输入合法
return true;
}
//实现接口onCreate方法
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.loginButton:{
login(); //调用登陆方法
break;
}
case R.id.registerButton: {
register(); //调用注册方法
break;
}
}
}
//跳转到注册界面
public void register() {
Intent intent = new Intent();
intent.setClass(MainActivity.this, RegisterActivity.class); //跳转
startActivity(intent); //启动
finish();
}
//登陆
public void login() {
//取得用户输入的账号和密码
if (!isInputValid()){
return;
}
String number = mPhoneNumberEditText.getText().toString().trim();
String password = mPassWordEditText.getText().toString().trim();
if (number.isEmpty()) {
Toast.makeText(MainActivity.this, "账号不能为空!", Toast.LENGTH_LONG).show();
return;
}else if (password.isEmpty()) {
Toast.makeText(MainActivity.this, "密码不能为空!", Toast.LENGTH_LONG).show();
return;
}else if (!admin.isChecked() && !user.isChecked()) {
Toast.makeText(MainActivity.this, "请选择权限!", Toast.LENGTH_LONG).show();
return;
}
HashMap<String, String> params = new HashMap<String, String>();
params.put(User.USERNAME, number);
params.put(User.PASSWORD, password);
if (admin.isChecked()) {
params.put(User.POWER, "1");
}else if (user.isChecked()) {
params.put(User.POWER, "2");
}
try {
//发起HTTP请求
String compeletedURL = HttpUtil.getURLWithParams(originAddress, params); //originAddress请求地址, params请求参数
HttpUtil.sendHttpRequest(compeletedURL, new HttpCallbackListener() {
@Override
public void onFinish(String response) { //请求回调函数,response是响应的数据
Message message = new Message();
message.obj = response;
mHandler.sendMessage(message); //给Handlder传递数据
}
@Override
public void onError(Exception e) {
Message message = new Message();
message.obj = e.toString();
mHandler.sendMessage(message);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
特别重要
在进行Activity跳转时,需要在 AndroidMainfest.xml
配置文件注册,同时网络请求也要配置允许设置。
网络请求封装类
public class HttpUtil {
//封装的发送请求函数
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) {
if (!HttpUtil.isNetworkAvailable()){
//这里写相应的网络设置处理
return;
}
new Thread(new Runnable() {
@Override
public void run() {
HttpURLConnection connection = null;
try{
URL url = new URL(address);
//使用HttpURLConnection
connection = (HttpURLConnection) url.openConnection();
//设置方法和参数
connection.setRequestMethod("GET");
connection.setConnectTimeout(8000);
connection.setReadTimeout(8000);
connection.setDoInput(true);
connection.setDoOutput(true);
//获取返回结果
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null){
response.append(line);
}
//成功则回调onFinish
if (listener != null){
listener.onFinish(response.toString());
}
} catch (Exception e) {
e.printStackTrace();
//出现异常则回调onError
if (listener != null){
listener.onError(e);
}
}finally {
if (connection != null){
connection.disconnect();
}
}
}
}).start();
}
//组装出带参数的完整URL
public static String getURLWithParams(String address,HashMap<String,String> params) throws UnsupportedEncodingException {
//设置编码
final String encode = "UTF-8";
StringBuilder url = new StringBuilder(address);
url.append("?");
//将map中的key,value构造进入URL中
for(Map.Entry<String, String> entry:params.entrySet())
{
url.append(entry.getKey()).append("=");
url.append(URLEncoder.encode(entry.getValue(), encode));
url.append("&");
}
//删掉最后一个&
url.deleteCharAt(url.length() - 1);
return url.toString();
}
//判断当前网络是否可用
public static boolean isNetworkAvailable(){
return true;
}
}
回调监听接口类
public interface HttpCallbackListener {
void onFinish(String response);
void onError(Exception e);
}
注册功能
注册功能和登陆功能基本流程相同,只不过增加了两个控件,请求的接口一样,不过请求的参数不一样,具体流程可以参考下 github
的源码
列表显示功能
登陆成功后,后台服务响应返回一个 json
数据格式的数据,需要解析 json
格式数据并显示在列表上
{"code":1,
"data":[
{"cardtype":"VIP","cartype":"小型车","id":1,"number":"111","sum":"¥1011","time":"每小时"},
{"cardtype":"VIP","cartype":"中型车","id":2,"number":"112","sum":"¥12","time":"每小时"},
{"cardtype":"VIP","cartype":"大型车","id":3,"number":"113","sum":"¥15","time":"每小时"},
{"cardtype":"普通卡","cartype":"小型车","id":4,"number":"114","sum":"¥15","time":"每小时"},
{"cardtype":"普通卡","cartype":"中型车","id":5,"number":"115","sum":"¥20","time":"每小时"},
{"cardtype":"普通卡","cartype":"大型车","id":6,"number":"116","sum":"¥25","time":"每小时"}
]}
借助 JSONArray
和 JSONObject
两个对象将 json
数据 通过哈希值hash
存放在 ArrayList
对象上,然后通过 simpleAdapter
适配器将 hash
的键list_item_activity.xml
文件 的控件 id
项对应显示列表
public class ListActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
ListView listView; //声明一个ListView对象
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//获取intent对象上的传过来的数据
Bundle myBundle = this.getIntent().getExtras();
String data = myBundle.getString("data");
setContentView(R.layout.list_activity);
//存放json数据
List<HashMap<String, String>> list = new ArrayList<HashMap<String,String>>();
try {
JSONArray jsonArray = new JSONArray(data);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = (JSONObject)jsonArray.get(i);
HashMap<String, String> map = new HashMap<String, String>();
map.put("id",jsonObject.getString("id"));
map.put("enterPort",jsonObject.getString("cardtype"));
map.put("exitPort",jsonObject.getString("cartype"));
map.put("parkName",jsonObject.getString("number"));
map.put("parkTel",jsonObject.getString("sum"));
map.put("parkTotal",jsonObject.getString("time"));
list.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
String[] str = new String[]{"id", "enterPort", "exitPort", "parkName", "parkTel", "parkTotal"}; //数组存放对应上面hash的键
int[] rId = new int[]{R.id.park_id, R.id.enter, R.id.exit, R.id.parkname, R.id.phone, R.id.total}; //对应list_item.activity.xml文件的控件id
SimpleAdapter simpleAdapter = new SimpleAdapter(ListActivity.this, list, R.layout.list_item_activity, str, rId); //参数,第一个是列表Activity的类,第二个参数是ArrayList数据,第三个参数是list_item_activity的layout的id,第四和第五对应上面的两个数据,分别为hash键数组和控件id数组
listView = (ListView)this.findViewById(R.id.listview);
listView.setAdapter(simpleAdapter);
}
}