前言
進行綜合設計的時候,要求做個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);
}
}