目的:
创建一个简单的Android项目,并搭建PHP后台,实现Android与PHP之间的通信。
本地环境:
Android Studio3.1.2
Tomcat 7.0.63
一、创建一个简单的安卓项目
File->New->New project,写好项目名称,选择好本地存储路径后,一直NEXT就可以创建出一个项目。
二、Http Client
java中要发送http请求可通过Http Client实现。接下来是封装httpclient的get()和post()。下面是个人第一次在网上查阅后尝试写的,有些地方可能写得不好,见谅哈,小白一只。
1、新建HttpClient类
package com.example.zwl.myapplication;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
public class HttpClient {
private String Url;
private int timeout;
public String getUrl() {
return Url;
}
public void setUrl(String url) {
this.Url = url;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int time) {
this.timeout = time;
}
public HashMap<String, Object> get() {
//get请求:存放状态码和请求内容
HashMap<String, Object> result = null;
//用于存放http状态码
int STATUS;
try {
//创建URL对象
URL geturl = new URL(Url);
HttpURLConnection httpURLConnection = (HttpURLConnection) geturl.openConnection();
//设置连接超时(ms)
httpURLConnection.setConnectTimeout(timeout);
//设定请求方式(默认为get)
httpURLConnection.setRequestMethod("GET");
//建立到远程对象的实际连接
httpURLConnection.connect();
//获取状态码
STATUS = httpURLConnection.getResponseCode();
//返回打开连接读取的输入流,输入流转化为StringBuffer类型
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
StringBuffer stringBuffer = new StringBuffer();
String line;
while ((line = bufferedReader.readLine()) != null) {
//转化为utf-8的编码格式
line = new String(line.getBytes("utf-8"));
stringBuffer.append(line);
}
bufferedReader.close();
httpURLConnection.disconnect();
result = new HashMap<>();
result.put("status", STATUS);
result.put("data", stringBuffer.toString());
} catch (MalformedURLException e) {
Log.d("get", "build url failed");
e.printStackTrace();
} catch (IOException e) {
Log.d("get", "build failed");
e.printStackTrace();
}
return result;
}
public HashMap<String, Object> post(HashMap<String, String> param) {
HashMap result = null;
try {
URL posturl = new URL(Url);
HttpURLConnection httpURLConnection = (HttpURLConnection) posturl.openConnection();
httpURLConnection.setConnectTimeout(timeout);
httpURLConnection.setRequestMethod("POST");
//设置是否向httpURLConnection输出
httpURLConnection.setDoOutput(true);
//设置是否从httpURLConnection读入
httpURLConnection.setDoInput(true);
//POST不能使用缓存
httpURLConnection.setUseCaches(false);
httpURLConnection.setInstanceFollowRedirects(true);
//设置请求头
httpURLConnection.setRequestProperty("Charset", "utf-8");
httpURLConnection.setRequestProperty("contentType", "utf-8");
httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
httpURLConnection.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
//配置需在连接之前完成
httpURLConnection.connect();
//设置请求内容
DataOutputStream out = new DataOutputStream(httpURLConnection.getOutputStream());
String content = "";
//遍历Map,构造表单参数
//keySet()返回postcontent内所有的关键字
for (String key : param.keySet()) {
String value = param.get(key);
content += key + "=" + URLEncoder.encode(value, "utf-8") + "&";
}
if (!content.isEmpty()) {
content = content.substring(0, content.length() - 1);
}
out.writeBytes(content);
out.flush();
out.close();
int code = httpURLConnection.getResponseCode();
Log.d("post", "content:" + content);
Log.d("post", "out:" + out);
//返回打开连接读取的输入流,输入流转化为StringBuffer类型
//BufferedReader提供通用的缓冲方式文本读取
//InputStreamReader()能将字节流输出为字符流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
String line;
StringBuffer stringBuffer = new StringBuffer();
while ((line = bufferedReader.readLine()) != null) {
line = new String(line.getBytes("utf-8"));
// Log.d(tag:"post",line);
stringBuffer.append(line);
}
Log.d("post", "data : " + stringBuffer.toString());
bufferedReader.close();
httpURLConnection.disconnect();
result = new HashMap<>();
result.put("status", code);
result.put("data", stringBuffer.toString());
} catch (MalformedURLException e) {
Log.d("post", "build url failed");
e.printStackTrace();
} catch (IOException e) {
Log.d("post", "build failed");
e.printStackTrace();
}
return result;
}
}
2、实现了HttpClient类后就是如何使用这个类来进行http请求。由于android4.0以后不能在主线程发起网络请求,所以这里需要创建一个线程用于进行网络请求。
我这里直接在MainActivity.java中创建线程。同时在类MyThread中重写run()。
这里贴的是发送post请求的代码。
package com.example.zwl.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建新线程
MyThread t = new MyThread();
/* 启动线程 */
t.start();
}
}
package com.example.zwl.myapplication;
import android.util.Log;
import java.util.HashMap;
public class MyThread extends Thread{
@Override
public void run(){
super.run();
HttpClient http = new HttpClient();
//此处ip为自己电脑的ip地址
http.setUrl("http://10.201.220.149:8080/phpbin/index.php");
http.setTimeout(10000);
HashMap<String, String> params = new HashMap<String, String>();
params.put("test","test");
HashMap<String,Object> result = http.post(params);
Object code = result.get("status");
Object data = result.get("data");
Log.v("post","post数据"+String.valueOf(code));
Log.v("post","post数据"+String.valueOf(data));
}
}
这里可以测试一下,编写的程序是否可用。为了测试,我将 MyThread类中的run()改成下面这样,这里是发送get请求的代码:
package com.example.zwl.myapplication;
import android.util.Log;
import java.util.HashMap;
public class MyThread extends Thread{
@Override
public void run(){
super.run();
HttpClient http = new HttpClient();
http.setUrl("https://www.baidu.com");
http.setTimeout(10000);
HashMap<String,Object> result = http.get();
Object code = result.get("status");
Object data = result.get("data");
Log.v("get","get数据"+String.valueOf(code));
Log.v("get","get数据"+String.valueOf(data));
}
}
记得配置一下联网权限,在AndroidManifest.xml文件中:
运行一下程序:Build -> Buid APK(s),Run ‘app’。
从打印的数据来看,请求成功了。
3、查看本机ip
win+r,输入cmd,输入ipconfig即可看到本机ip。
三、搭建本地PHP服务器
1、tomcat下载
这里选择压缩包解压。将压缩包解压在自己想要放置的文件夹下,环境配置方面需要在系统环境变量中新建JAVA_HOME变量,其值为本机jdk的安装目录。
查看apache-tomcat-7.0.63\bin目录下catalina.bat文件
出现这个代表tomcat安装成功。双击apache-tomcat-7.0.63\bin目录下startup.bat文件。浏览器:localhost:8080访问。
假如双击startup.bat出现闪退,可编辑startup.bat文件,在末尾加上PAUSE,再次启动,根据信息进行调试。
2、tomcat登陆
打开apache-tomcat-7.0.63\webapps\host-manager\WEB-INF下的web.xml文件。
找到admin-gui,复制红框内容,增加管理角色manager-gui
打开conf/tomcat-users.xml。
目的是为了创建一个用户名和密码均为tomcat的用户,此用户拥有管理员权限。manager-gui是管理者角色,对于tomcat6,mangaer是管理者角色,不是manager-gui。
重启tomcat之后再次输入localhost:8080,点击server status,输入tomcat,密码为tomcat,即可登陆。
3、配置tomcat支持php运行。
下载好php压缩包后解压至apache-tomcat-7.0.63(tomcat安装目录)下,进入php目录。
支持php cgi运行,修改php.ini如下:
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
extension_dir = "ext"
; On windows:
cgi.force_redirect = 0
; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
; sys_temp_dir = "/tmp"
打开apache-tomcat-7.0.63\conf\context.xml,修改如下:
<!-- The contents of this file will be loaded for each web application -->
<Context privileged = "true" >
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
作用详情可参考:http://elf8848.iteye.com/blog/1931777
打开apache-tomcat-7.0.63\conf\web.xml,修改如下:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>php</servlet-name>
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class>
<init-param>
<param-name>clientInputTimeout</param-name>
<param-value>200</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>executable</param-name>
<!-- tomcat安装目录下php下的php-cgi.exe -->
<param-value>C:\apache-tomcat-7.0.63\php7.1.9\php-cgi.exe</param-value>
</init-param>
<init-param>
<param-name>passShellEnvironment</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cgiPathPrefix</param-name>
<!--指定php在apache-tomcat-7.0.63\webapps\ROOT\WEB-INF\phpbin下-->
<param-value>WEB-INF/phpbin</param-value>
</init-param>
<load-on-startup>5</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>php</servlet-name>
<url-pattern>/phpbin/*</url-pattern>
</servlet-mapping>
重启tomcat,在apache-tomcat-7.0.63\webapps\ROOT\WEB-INF在新建phpbin,新建index.php,内容如下:
<?php phpinfo() ?>
访问:localhost:8080/phpbin/index.php,看到下面,搭建成功。
4、手机访问本地服务器
保证手机与电脑连接在同一wifi下,使用手机浏览器访问:http://ip(电脑ip):8080即可访问到tomcat主页
四、php与android间的交互
通过上面步骤,Android端已经可以发送请求,设置url为自己本机ip+php文件路径,就可以向php文件发送post请求。这里贴一下php文件的代码。
<?php
//定义返回数据
$data = ["code" => "","msg" => ""];
if (!empty($_POST)) {
//
foreach($_POST as $key=>$value){
//接收数据的键对值
$data = ["code" => $key,"msg" => $value]; //因为post数据只有一对键对值,这里我偷懒直接把返回数据在此循环里填装
};
}
echo json_encode($data);
?>
注意:
- 在运行前记得开启本地tomcat
php文件中echo、var_dump数据将显示在android端。通过网页访问php文件看不到数据。
运行:
php成功返回数据给android端。