Android客户端与PHP服务端的数据交互

时间:2022-02-13 19:27:06

最近在学习Android客户端,刚好学到了Android的网络应用,钻研了一下,写一篇博客来记录学习心得。

由于安卓系统一般是作为客户端,所以我们除了需要编写客户端之外,还需要自己写一个服务端,这里的服务端我是用PHP+MySQL来建立的。

以下分为两个方面来详细说明:

服务端:
1.笔者的电脑搭建的是WAMP服务器环境,集成了PHP和Apache环境,所以我直接使用PHP来编写。
2.首先先建立相对应的数据库、数据表、以及字段名。(这里笔者建立了一个“android”的数据库,”user”的数据表,以及id、name、password、state的字段)
3.接下来是PHP搭建的服务端的代码:

<?php
```PHP
$conn=@mysql_connect("localhost","root",""); //与本地服务器连接
if(!$conn)
{
die('Could not connect'.mysql_error());
}
mysql_query("set name utf8");
mysql_select_db("android",$conn); //选择数据库
$name=$_POST['name']; //获取客户端传递过来的数据
$password=md5($_POST['password']);
//查询数据
$result=mysql_query("select * FROM user WHERE name='$name' and password='$password' ");
$info=mysql_fetch_array($result);
if(!$info)
{
echo "登录失败!";
}else{
$array=array('user'=>array('id'=>$info["id"],'username'=>$name,'password'=>$info["state"]));
echo json_encode($array);
}?>
```

客户端:
安卓系统提供了一个类:URLConnection类来让应用程序与URL进行通信。以下为建立URL的连接,发送请求以及读取服务器的返回数据的几个步骤:
①通过调用URL对象的openConnection()方法来创建URLConnection对象。
②设置URLConnection的参数和属性。
③发送GET或者POST请求
④建立连接后,利用输入流读取远程资源数据。

以下是客户端各部分的代码

PostUtil.java 工具类

```java
public class PostUtil
{
/**
*
*
public static String sendPost(String url, Map<String,String> params, String encode)
{
String data = getRequestData(params, encode).toString();//获得请求体
//System.out.print(data);
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try
{
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(data); // 向服务端输出参数
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null)
{
result += "\n" + line;
}
}
catch (Exception e)
{
System.out.println("发送POST请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输出流、输入流
finally
{
try
{
if (out != null)
{
out.close();
}
if (in != null)
{
in.close();
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
return result;
}
public static StringBuffer getRequestData(Map<String, String> params, String encode)
{
StringBuffer stringBuffer = new StringBuffer(); //存储封装好的请求体信息
try {
for(Map.Entry<String, String> entry : params.entrySet()) {
stringBuffer.append(entry.getKey())
.append("=")
.append(URLEncoder.encode(entry.getValue(), encode))
.append("&");
}
stringBuffer.deleteCharAt(stringBuffer.length() - 1); //删除最后的一个"&"
} catch (Exception e) {

e.printStackTrace();
}
return stringBuffer;
}
public static Map<String, String> parseJson(String result)
{
Map<String,String> info=new HashMap<>();
try{
System.out.println(result);
JSONObject jsonObject=new JSONObject(result).getJSONObject("user");
int id=jsonObject.getInt("id");
String name=jsonObject.getString("username");
String pass=jsonObject.getString("password");
info.put("name",name);
info.put("pass",pass);
info.put("id", String.valueOf(id));

}catch (JSONException js)
{
js.printStackTrace();
System.out.print("Error");
}
return info;
}
}
```

MainActivity.java

public class MainActivity extends Activity
{
Button post;
TextView show;
Intent intent;
// 代表服务器响应的字符串
String response;
Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
if(msg.what == 0x123)
{
// 设置show组件显示服务器响应
//show.setText(response);
startActivity(intent);
}
}
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
post = (Button) findViewById(R.id.post);
show = (TextView)findViewById(R.id.show);
post.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
EditText name=(EditText)findViewById(R.id.name);
EditText password=(EditText) findViewById(R.id.password);
final String Strname=name.getText().toString();
final String Strpass=password.getText().toString();
new Thread()
{
@Override
public void run()
{
Map<String,String> map=new HashMap<String, String>();
map.put("name",Strname);
map.put("password",Strpass);
response = GetPostUtil.sendPost(
"http://192.168.191.1/android/login.php"
,map,"utf-8");
Map<String,String> info=GetPostUtil.parseJson(response);
System.out.println(info);
String username=info.get("name");
String password=info.get("pass");
int id= parseInt(info.get("id"));
Bundle data=new Bundle();
data.putInt("id", id);
data.putString("username", username);
data.putString("password", password);
intent=new Intent(MainActivity.this,ResultActivity.class);
intent.putExtras(data);
handler.sendEmptyMessage(0x123);
}


}.start();
// 发送消息通知UI线程更新UI组件
}
});
}
}

ResultActivity.java 第二个Activity

/**
*该Activivty主要用于显示已经解析好的数据
**/
public class ResultActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
TextView name=(TextView) findViewById(R.id.name);
TextView password=(TextView) findViewById(R.id.password);
TextView id=(TextView) findViewById(R.id.id);
Intent intent=getIntent();
String username= (String) intent.getExtras().get("username");
String userpass= (String) intent.getExtras().get("password");
int userid= (Integer) intent.getExtras().get("id");
name.setText("你的用户名为:"+username);
password.setText("你的密码为"+userpass);
id.setText("你的id为"+userid);
}
}

activity_main.xml MainActivity对应的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:orientation="vertical">

<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入账号"/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入密码"/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登陆"
android:id="@+id/post"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal" />

<TextView
android:id="@+id/show"
android:layout_width="match_parent"
android:layout_height="wrap_content" /></LinearLayout>

result.xml ResultActivity.java对应的布局文件

<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/name"
android:textSize="18sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/password"
android:textSize="18sp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/id"
android:textSize="18sp"/></LinearLayout>

最后:不要忘记在布局文件内声明第二个活动以及添加允许访问互联网的权限。