一、项目项目概要
工作期间,周天闲来无聊,就花了一天时间看点视频学习学习,项目虽小,五脏不全,但是涉及到的知识有
1、项目登录流程--获取验证码,通过手机号MD5加密、验证码登录,登录成功后返回Token标识本地存储
2、网络通讯--HttpUrlConnection、AsyncTask异步任务
3、大量的接口编程、回调接口
4、手机联系人上传,评论上传,说说上传及其下载
5、JSon数组、对象的解析和生成
6、还有相关的页面跳转数据回传、适配器等
******************************************************华丽的分割线******************************************************
服务端
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<%
out.clear();
String action = request.getParameter("action");
if (action != null) {
if (action.equals("send_pass")) {
out.print("{\"status\":1}");
} else if (action.equals("login")) {
out.print("{\"status\":1,\"token\":\"asdasdasdsadasd\"}");
} else if (action.equals("upload_contacts")) {
out.print("{\"status\":1}");
} else if (action.equals("timeline")) {
out.print("{\"status\":1,\"page\":1,\"perpage\":20,\"timeline\":["
+ "{\"msg\":\"Haha1\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha2\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha3\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha4\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha5\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha6\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha7\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"},"
+ "{\"msg\":\"Haha8\",\"phone_md5\":\"dasdasdbkas\",\"msgId\":\"1231234\"}"
+ "]}");
} else if (action.equals("get_comment")) {
out.print("{\"status\":1,\"page\":1,\"perpage\":20,\"msgId\":\"12133\",\"comments\":["
+ "{\"content\":\"Hehe1\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe2\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe3\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe4\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe5\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe6\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe7\",\"phone_md5\":\"dasdasdbkas\"},"
+ "{\"content\":\"Hehe8\",\"phone_md5\":\"dasdasdbkas\"}"
+ "]}");
} else if (action.equals("pub_comment")) {
out.print("{\"status\":1}");
} else if (action.equals("publish")) {
out.print("{\"status\":1}");
}
} else {
out.print("请指定action");
}
%>
</body>
</html>
下面是登录界面,首先输入手机号,点击Get Code按钮获取服务器返回的验证码,由于这个小项目没有完善的服务器支持,所以获取验证码,只是让服务器简单的返回所提交的Url地址后服务器返回正确状态值即可,验证码可以随便输入,主要是了解真实的企业项目的开发流程即可,在手机号、验证码输入完毕,点击Login登录按钮进行服务器验证登录,登录操作是传递手机号的MD5值、验证码进行服务器验证,验证成功,在服务器会生成一个对应的Token标识进行返回,登录后进行客户端的手机号码、Token标识进行本地缓存即可
布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingTop="20dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phone"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/etPhoneNum"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:inputType="phone"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<Button
android:id="@+id/btnGetCode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get_code"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/code"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/etCode"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:inputType="number"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
<Button
android:id="@+id/btnLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/login" />
</LinearLayout>
下面这个界面是登录成功后,显示的联系人的说说列表界面,界面初始化,需要同步更新联系人列表之服务器(呵呵,由于项目的服务器不支持,我只是返回了状态值)
然后,进行服务器下载联系人说说数据,然后进行说说列表的数据设置
布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
其Item的布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:padding="5dp"
android:id="@+id/tvCellLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
下面这个是点击每条说说记录,跳转到的界面,在这个界面可以发表评论,上传至服务器
布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tvMessage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</ListView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText
android:id="@+id/etComment"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/btnSendComment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:drawable/ic_menu_send" />
</LinearLayout>
</LinearLayout>
Item的布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:padding="5dp"
android:id="@+id/tvCellLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
下面这个界面是进行发表说说,然后点击发送按钮,关闭后回到联系人说说列表记录,进行重新获取说说记录,更新列表
布局如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/etMsgContent"
android:gravity="left"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:inputType="none"/>
<Button
android:id="@+id/btnPublish"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/publish_message" />
</LinearLayout>
******************************************一些工具类*****************************
Config
package com.jikexueyuan.secret;
import android.content.Context;
import android.content.SharedPreferences.Editor;
public class Config {
public static final String SERVER_URL = "http://10.127.0.11:8090/NiMingServer/api.jsp";
// 为手机号分配的Token值
public static final String KEY_TOKEN = "token";
public static final String KEY_ACTION = "action";
public static final String KEY_PHONE_NUM = "phone";
public static final String KEY_PHONE_MD5 = "phone_md5";
public static final String KEY_STATUS = "status";
// 分配的验证码
public static final String KEY_CODE = "code";
public static final String KEY_CONTACTS = "contatcs";
public static final String KEY_PAGE = "page";
public static final String KEY_PERPAGE = "perpage";
public static final String KEY_TIMELINE = "timeline";
public static final String KEY_MSG_ID = "msgId";
public static final String KEY_MSG = "msg";
public static final String KEY_COMMENTS = "comments";
public static final String KEY_CONTENT = "content";
/**
* 上传服务器所返回的状态值
*/
public static final int RESULT_STATUS_SUCCESS = 1;
public static final int RESULT_STATUS_FAIL = 0;
public static final int RESULT_STATUS_INVALID_TOKEN = 2;
public static final String APP_ID = "com.jikexueyuan.secret";
public static final String CHARSET = "utf-8";
/***
* 上传服务器的action值
*/
public static final String ACTION_GET_CODE = "send_pass";
public static final String ACTION_LOGIN = "login";
public static final String ACTION_UPLOAD_CONTACTS = "upload_contacts";
public static final String ACTION_TIMELINE = "timeline";
public static final String ACTION_GET_COMMENT = "get_comment";
public static final String ACTION_PUB_COMMENT = "pub_comment";
public static final String ACTION_PUBLISH = "publish";
public static final int ACTIVITY_RESULT_NEED_REFRESH = 10000;
public static String getCachedToken(Context context) {
return context.getSharedPreferences(APP_ID, Context.MODE_PRIVATE)
.getString(KEY_TOKEN, null);
}
public static void cacheToken(Context context, String token) {
Editor e = context.getSharedPreferences(APP_ID, Context.MODE_PRIVATE)
.edit();
e.putString(KEY_TOKEN, token);
e.commit();
}
public static String getCachedPhoneNum(Context context) {
return context.getSharedPreferences(APP_ID, Context.MODE_PRIVATE)
.getString(KEY_PHONE_NUM, null);
}
public static void cachePhoneNum(Context context, String phoneNum) {
Editor e = context.getSharedPreferences(APP_ID, Context.MODE_PRIVATE)
.edit();
e.putString(KEY_PHONE_NUM, phoneNum);
e.commit();
}
}
MD5Tool
package com.jikexueyuan.secret.tools;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Tool {
public static String md5(String string) {
byte[] hash;
try {
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Huh, MD5 should be supported?", e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Huh, UTF-8 should be supported?", e);
}
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10) hex.append("0");
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
}