原创:http://blog.csdn.net/iwanghang
其实,一般的App来说学到这里,足够应付一般的接口了。
但是,我们目标是除了接口还有Socket通讯,所以。。。路漫漫啊。。。。
1.先看一下App端的GIF效果
2.为了方便测试,我们手动修改一下数据库
把一部分id改成online为1
2.我们增加了一个接口
用于App端获取在线用户
package com.iwanghang.servletDemo;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class UserOnline implements Servlet{
private String date; // 返回的Json数据
public UserOnline() {
System.out.println("HelloServlet...");
}
@Override
public void destroy() {
System.out.println("destroy...");
}
@Override
public ServletConfig getServletConfig() {
System.out.println("getServletConfig...");
return null;
}
@Override
public String getServletInfo() {
System.out.println("getServletInfo...");
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("init...");
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("service...");
/**
* 查询在线用户username的sql语句如下
* select * from aaa_user where `online` = '1'
* select * from aaa_user where online = '1'
* select username from aaa_user where online = '1'
* 我们用最后一个
*/
try {
Class.forName("com.mysql.jdbc.Driver");//创建驱动器
// 写法1. 这样写会有警告,但是不影响使用
// Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql","root","123456");//这是数据库的路径,并且还有输入账号(一般默认是root),密码之前创建用户时的那个
// 写法2. 看起来比较复杂,但是没有警告
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo1113?useUnicode=true&characterEncoding=utf-8&useSSL=false","root", "123456");
PreparedStatement pst = con.prepareCall("select username from aaa_user where online = '1'");//输入的是要在MySQL中执行的代码
ResultSet rs = pst.executeQuery();//获得执行上面代码后的结果集
date = "[";
while(rs.next()){
String username = rs.getString("username");
System.out.println("username = " + username);
date = date + "{\"username\":\"" + username+"\"},";
}
date = date.substring(0, date.length()-1); // 截取字符串,从第1个字符串开始,截取至,倒数第2个。也就是,去掉最后一个","
date = date + "]";
}
catch (ClassNotFoundException ex) {
Logger.getLogger(UserOnline.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(UserOnline.class.getName()).log(Level.SEVERE, null, ex);
}
// 如果date长度小于3,可以认为没有数据,给date赋值no,告诉App没有数据
if (date.length()<3) {
//System.out.println("date.length() = " + date.length());
date = "no";
}
System.out.println("date = " + date);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
String jsonStr = date;
PrintWriter out = null;
try {
out = response.getWriter();
out.write(jsonStr);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
}
}
同时,不要忘记在web.xml里做映射
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<!-- Servlet 配置 -->
<servlet>
<!-- Servlet 注册的名字 -->
<servlet-name>test01</servlet-name>
<!-- Servlet 全类名 -->
<servlet-class>com.iwanghang.servletDemo.Test01</servlet-class>
<!-- Servlet 创建邮件级别 0为最先创建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Servlet 映射 -->
<servlet-mapping>
<!-- 映射 配置中一个同名节点 -->
<servlet-name>test01</servlet-name>
<!-- 映射 具体的访问路径 -->
<url-pattern>/test01</url-pattern>
</servlet-mapping>
<!-- Servlet 配置 -->
<servlet>
<!-- Servlet 注册的名字 -->
<servlet-name>useronline</servlet-name>
<!-- Servlet 全类名 -->
<servlet-class>com.iwanghang.servletDemo.UserOnline</servlet-class>
<!-- Servlet 创建邮件级别 0为最先创建 -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Servlet 映射 -->
<servlet-mapping>
<!-- 映射 配置中一个同名节点 -->
<servlet-name>useronline</servlet-name>
<!-- 映射 具体的访问路径 -->
<url-pattern>/useronline</url-pattern>
</servlet-mapping>
</web-app>
3.接下来,我们看一看App端的几个Activity
MainActivity:
package com.iwanghang.demo1114;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import static com.iwanghang.demo1114.Constant.LOGINCHECK;
public class MainActivity extends Activity {
private String TAG = "MainActivity";
// 创建请求队列
RequestQueue requestQueue = null;
private EditText et_username;
private EditText et_password;
private Button bt_login;
private TextView tv_log;
private String username;
private String password;
private String islogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestQueue = Volley.newRequestQueue(this);
et_username = findViewById(R.id.et_username);
et_password = findViewById(R.id.et_password);
bt_login = findViewById(R.id.bt_login);
tv_log = findViewById(R.id.tv_log);
initLogin(); // 登录 按钮点击事件监听
}
/**
* 登录 按钮点击事件监听
*/
private void initLogin() {
bt_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 获取输入账号密码
username = et_username.getText().toString();
password = et_password.getText().toString();
Log.v(TAG, " username = " + username);
netLogin(); // 发送网络请求
}
});
}
/**
* 发送网络请求 尝试登陆
*/
private void netLogin() {
// 请求地址
//String url = "hhttp://192.168.1.129:8080/servletDemo/test01";
StringRequest request = new StringRequest(Request.Method.POST, LOGINCHECK, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.v(TAG,"response = " + response);// 返回结果
try {
if (response.equals("no")){
Toast.makeText(MainActivity.this, "登录失败,请检查ID是否正确", Toast.LENGTH_SHORT).show();
}else {
JSONObject object1 = new JSONObject(response);
islogin = object1.getString("islogin"); // islogin
Log.e("TAG", "islogin = " + islogin);
Toast.makeText(MainActivity.this, "islogin = " + islogin, Toast.LENGTH_SHORT).show();
if (islogin.equals("yes")){
tv_log.setText("登录成功");
goListActivity(username); // 跳转到 在线 且 不在会话中 的用户列表 Activity
}else if (islogin.equals("no")) {
tv_log.setText("登录失败");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.v(TAG,"error = " + error); // 错误结果
Toast.makeText(getApplication(),"网络出问题",Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
// 请求的内容
Map<String,String> params = new HashMap<>();
params.put("username",username);
params.put("password",password);
return params;
}
};
// 添加到请求队列
requestQueue.add(request);
}
/**
* 跳转到 在线 且 不在会话中 的用户列表 Activity
*/
private void goListActivity(String username) {
Intent intent = new Intent(MainActivity.this, ListActivity.class);
intent.putExtra("username",username); // 姓名
startActivity(intent);
}
}
ListActivity:
package com.iwanghang.demo1114;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import static com.iwanghang.demo1114.Constant.USERLIST;
public class ListActivity extends Activity {
private String TAG = "ListActivity";
// 创建请求队列
RequestQueue requestQueue = null;
private TextView tv_name;
private Button bt_getList;
private String username;
private String usernameArray;
private ListAdapter adapter;
private ListView lv_main;
private ArrayList<String> list = new ArrayList<String>();
private String clickName = "noData"; // 获取点击的字符串
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
requestQueue = Volley.newRequestQueue(this);
// 接过来传递的值
Bundle extras = getIntent().getExtras();
username = extras.getString("username");
tv_name = findViewById(R.id.tv_name);
tv_name.setText(username);
bt_getList = findViewById(R.id.bt_getList);
initList(); // 获取 在线 且 不在会话中 的用户列表 按钮点击事件监听
lv_main = findViewById(R.id.lv_main);
adapter = new ListAdapter();
}
/**
* 获取 在线 且 不在会话中 的用户列表 按钮点击事件监听
*/
private void initList() {
bt_getList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getList(); // 发送网络请求
}
});
}
/**
* 获取 在线 且 不在会话中 的用户列表
*/
private void getList() {
// 请求地址
//String url = "http://192.168.1.111:8001/app_new/user_sc.asp";
StringRequest request = new StringRequest(Request.Method.POST, USERLIST, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.v(TAG,"response = " + response);// 返回结果
try {
if (response.equals("no")){
Toast.makeText(ListActivity.this, "登录失败,请检查ID是否正确", Toast.LENGTH_SHORT).show();
}else {
JSONArray jsonArray = new JSONArray(response.toString());
Toast.makeText(ListActivity.this, "response.jsonArray.toString() = " + jsonArray, Toast.LENGTH_SHORT).show();
usernameArray = "";
for(int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.e("TAG", jsonObject.getString("username"));
String username = jsonObject.getString("username");
if (usernameArray == "") {
usernameArray = usernameArray + username;
}else{
usernameArray = usernameArray +"," + username;
}
}
Toast.makeText(ListActivity.this, "在线 且 不在会话中 的用户列表 = " + usernameArray, Toast.LENGTH_SHORT).show();
initListData(); // 初始化列表数据
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.v(TAG,"error = " + error); // 错误结果
Toast.makeText(getApplication(),"网络出问题",Toast.LENGTH_SHORT).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
// 请求的内容
Map<String,String> params = new HashMap<>();
params.put("username",username);
return params;
}
};
// 添加到请求队列
requestQueue.add(request);
}
/**
* 初始化列表数据
*/
private void initListData() {
String temp = null;
list.clear();
String[] temp_all = usernameArray.split(",");
for (int i = 0 ; i <temp_all.length ; i++ ) { // 遍历数据
temp = temp_all[i];
list.add(temp);
}
lv_main.setAdapter(adapter);
}
private class ListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
ListAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
System.out.println("getView " + position + " " + convertView);
ListActivity.viewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_list, null);
holder = new viewHolder();
holder.text = convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ListActivity.viewHolder) convertView.getTag();
}
Log.v(TAG,""+ list.get(position));
holder.text.setText(list.get(position));
holder.text.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickName = list.get(position);
Log.v(TAG,"text OnClickListener = " + clickName);
Toast.makeText(ListActivity.this, clickName, Toast.LENGTH_SHORT).show();
goCallActivity(username,clickName); // 跳转到 视频通话请求页面
}
});
return convertView;
}
}
/**
* 使用一个类来保存Item中的元素
*/
public static class viewHolder {
public TextView text;
}
/**
* 跳转到 视频通话请求页面
*/
private void goCallActivity(String username,String clickName) {
Intent intent = new Intent(ListActivity.this, CallActivity.class);
intent.putExtra("username",username); // 姓名
intent.putExtra("clickName",clickName); // 对方
startActivity(intent);
}
}
CallActivity:
package com.iwanghang.demo1114;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
public class CallActivity extends Activity {
private String TAG = "CallActivity";
private TextView tv_i;
private TextView tv_u;
private ImageView iv_call;
private TextView tv_log;
private String username;
private String clickName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
tv_i = findViewById(R.id.tv_i);
tv_u = findViewById(R.id.tv_u);
iv_call = findViewById(R.id.iv_call);
tv_log = findViewById(R.id.tv_log);
// 接过来传递的值
Bundle extras = getIntent().getExtras();
username = extras.getString("username");
clickName = extras.getString("clickName");
tv_i.setText(username);
tv_u.setText(clickName);
}
}
原创: http://blog.csdn.net/iwanghang