为了写这篇文章,准备了很长的时间,自己也学习很多新的知识,譬如简单学习了服务器端的语言PHP,MySQL数据库以及也了解了Http协议。收获很大,学到了很多新的知识,对C/S架构模式,有了更近一步的了解。对近期学习也做一个总结,同时给想做这方面东西的博友们,一点启发,自己就心满意足了。在不久之前,也简单收集了一些资料,然后发表在博客上,没有想到的是,到目前为止,这篇博客成为我写的所有博客里,访问量最多的文章,虽然博客的整体访问量,少的可怜。之前那篇博客文章的名字叫做《Android客户端通过WebService访问MySql数据库》,一直也不明白什么是WebService,然后就查阅了相关的资料。
WebService是一种跨编程语言和跨操作系统平台的远程调用技术,通俗一点理解,就是远程的某个服务器公开了某种服务,而我们可以通过编程来调用这种服务,以获得我们所需要的信息。举个例子,就是Android手机调用支付宝的接口。该博文的题目就是WebService一种体现。
先简单介绍一下,这个小项目,也算不上是小项目,姑且就叫它小项目。总体的实现思路。在服务器端,我是通过PHP的mysqli扩展库去连接的MySQL数据库,在Android客户端,我通过网络请求去访问Apache服务器就OK了。
- 软硬件环境
Android Studio2.2版本
软件集成包XAMPP
真机 华为荣耀3C
2.创建MySQL数据库以及表
a.创建数据库
create database persondb;
b.创建数据表
create table persons(Id_P int(11),LastName varchar(255), FirstName varchar(255),Address varchar(255), City varchar(255));
创建之后的结果如下所示:
数据库方面创建OK了,接下来做PHP的mysqli扩展库连接MySQL数据库
3.PHP的mysqli扩展库连接MySQL数据库
a.先写个配置文件db_config.php
<?php
/*
* All database connection variables
*/
define('DB_USER', "root"); // db user
define('DB_PASSWORD', ""); // db password (mention your db password here)
define('DB_DATABASE', "persondb"); // database name
define('DB_SERVER', "localhost"); // db server
?>
b.连接MySQL数据库的文件db_connect.php
<?php
/**
* A class file to connect to database
*/
/**
* Function to connect with database
*/
function connect() {
/*包含并运行指定的文件*/
// import database connection variables
require_once __DIR__ . '/db_config.php';
global $con;
// Connecting to mysql database
$con = mysqli_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysqli_connect_error());
// Selecing database
$db = mysqli_select_db($con,DB_DATABASE) or die(mysqli_error($con)) ;
// returing connection cursor
return $con;
}
/**
* Function to close db connection
*/
function close() {
// closing db connection
global $con;
mysqli_close($con);
}
?>
c. Android客户端从MySQL数据库里获取数据的文件get_all_persons.php
<?php
/*
* Following code will list all the products
*/
// array for JSON response
$response = array();
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
connect();
// get all products from products table
$result = mysqli_query($con,"SELECT *FROM persons") or die(mysqli_error());
// check for empty result
if (mysqli_num_rows($result) > 0) {
// looping through all results
// products node
$response["persons"] = array();
while ($row = mysqli_fetch_array($result)) {
// temp user array
$info = array();
$info["Id_P"] = $row["Id_P"];
$info["LastName"] = $row["LastName"];
$info["FirstName"] = $row["FirstName"];
$info["Address"] = $row["Address"];
$info["City"] = $row["City"];
// push single product into final response array
array_push($response["persons"], $info);
}
// success
$response["success"] = 1;
// echoing JSON response
echo json_encode($response);
} else {
// no products found
$response["success"] = 0;
$response["message"] = "No products found";
// echo no users JSON
echo json_encode($response);
}
close();
?>
d.Android客户端向MySQL数据库插入数据的文件create_person.php
<?php
$result = file_get_contents('php://input');
$object=json_decode($result);
$Id_P = $object->{'Id_P'};
$LastName=$object->{'LastName'};
$FirstName=$object->{'FirstName'};
$Address=$object->{'Address'};
$City=$object->{'City'};
/*
* Following code will create a new person row
* All person details are read from HTTP Post Request
*/
// array for JSON response
$response = array();
// check for required fields
if (isset($Id_P) || isset($LastName) || isset($FirstName) || isset($Address) || isset($City)) {
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
connect();
// mysql inserting a new row
$result = mysqli_query($con,"INSERT INTO persons(Id_P,LastName,FirstName,Address,City) VALUES('$Id_P', '$LastName','$FirstName','$Address','$City')");
// check if row inserted or not
if ($result) {
// successfully inserted into database
$response["success"] = 1;
$response["message"] = "Person successfully created.";
// echoing JSON response
echo json_encode($response);
} else {
// failed to insert row
$response["success"] = 0;
$response["message"] = "Oops! An error occurred.";
// echoing JSON response
echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";
// echoing JSON response
echo json_encode($response);
}
?>
创建一个文件夹android_connect,把以上的所有php文件都放在该文件夹里,并把android_connect 文件夹放在xampp安装目录里htdocs文件夹下。
4.Android客户端通过网络访问MySQL数据库
先上布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.androidconnectserver.MainActivity">
<Button
android:text="向MYSQL数据库插入数据"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Send"
/>
<Button
android:text="从MYSQL数据库获取数据"
android:layout_below="@id/Send"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Receive"
/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/Receive"
android:layout_marginTop="5dp"
android:text="textView"
android:textSize="20sp"/>
</RelativeLayout>
该布局文件是Android客户端向MySQL数据库插入数据时的一个自定义对话框的布局文件dialog_custom.xml
<?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">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Id_P :"
/>
<EditText
android:id="@+id/et_Id_P"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:hint="请输入信息"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LastName :"
/>
<EditText
android:id="@+id/et_LastName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:hint="请输入信息"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FirstName :"
/>
<EditText
android:id="@+id/et_FirstName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:hint="请输入信息"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address :"
/>
<EditText
android:id="@+id/et_Address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:hint="请输入信息"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:paddingLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="City :"
/>
<EditText
android:id="@+id/et_City"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:hint="请输入信息"/>
</LinearLayout>
</LinearLayout>
最后出场Android端的代码,各位小伙伴们注意了。
package com.android.androidconnectserver;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
public static final String TAG="MainActivity";
private Button Send;
private Button Receive;
private TextView textView;
private String response;
private EditText inputId_P;
private EditText inputLastName;
private EditText inputFirstName;
private EditText inputAddress;
private EditText inputCity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
Receive.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
receive();
textView.setText(response);
}
});
Send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog();
}
});
}
public void initViews(){
Send =(Button) findViewById(R.id.Send);
Receive= (Button) findViewById(R.id.Receive);
textView=(TextView) findViewById(R.id.textView);
}
/*从MySQL里获取数据*/
private void receive() {
new Thread(
new Runnable() {
@Override
public void run() {
response=executeHttpGet();
}
}
).start();
}
private String executeHttpGet() {
HttpURLConnection con=null;
InputStream in=null;
String path="http://172.27.35.1/android_connect/get_all_persons.php";
try {
con= (HttpURLConnection) new URL(path).openConnection();
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
con.setDoInput(true);
con.setRequestMethod("GET");
if(con.getResponseCode()==200){
in=con.getInputStream();
return parseInfo(in);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String parseInfo(InputStream in) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(in));
StringBuilder sb=new StringBuilder();
String line=null;
while ((line=br.readLine())!=null){
sb.append(line+"\n");
}
Log.i(TAG, "parseInfo: sb:"+sb.toString());
return sb.toString();
}
/*发送数据给MySQL数据库*/
private void showDialog(){
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
builder.setTitle("添加个人信息");
View view= View.inflate(MainActivity.this,R.layout.dialog_custom,null);
builder.setView(view);
builder.setPositiveButton("确定", new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
String Id_P=inputId_P.getText().toString();
String LastName=inputLastName.getText().toString();
String FirstName=inputFirstName.getText().toString();
String Address=inputAddress.getText().toString();
String City=inputCity.getText().toString();
try {
jsonObject.put("Id_P",Id_P);
jsonObject.put("LastName",LastName);
jsonObject.put("FirstName",FirstName);
jsonObject.put("Address",Address);
jsonObject.put("City",City);
} catch (JSONException e) {
e.printStackTrace();
};
send();
}
});
builder.setNegativeButton("取消",new OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog ad=builder.create();
ad.show();
inputId_P= (EditText)ad.findViewById(R.id.et_Id_P);
inputLastName= (EditText)ad.findViewById(R.id.et_LastName);
inputFirstName= (EditText)ad.findViewById(R.id.et_FirstName);
inputAddress= (EditText)ad.findViewById(R.id.et_Address);
inputCity= (EditText)ad.findViewById(R.id.et_City);
}
private void send() {
new Thread(new Runnable() {
@Override
public void run() {
executeHttpPost();
}
}).start();
}
JSONObject jsonObject=new JSONObject();
private void executeHttpPost() {
HttpURLConnection con=null;
String path="http://172.27.35.1/android_connect/create_person.php";
try {
URL url=new URL(path);
con= (HttpURLConnection) url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestMethod("POST");
con.setRequestProperty("Connection", "keep-alive");
con.connect();
DataOutputStream out=new DataOutputStream(con.getOutputStream());
out.flush();
if (con.getResponseCode()==HttpURLConnection.HTTP_OK){
InputStream in=con.getInputStream();
byte [] buf=new byte[in.available()];
in.read(buf);
String str=new String(buf);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.运行结果
a.向MySQL数据库插入数据
点击向MySQL数据库插入数据的按钮,会弹出如下图所示的运行结果,在里面输入数据,单击确定就可以向数据库中插入数据了,通过查询数据库,可以查看数据是否插入成功。
b.从MySQL数据库获取数据
点击从MySQL数据库获取数据的按钮,就会JSON格式的字符串,运行结果如下所示:
以上就是一个多月学习的一个简单的总结,如果代码有什么问题,还请各位小伙伴批评指正,让我有进步的机会。最后别忘了打开XAMPP的控制面板,启动Apache服务器和MySQL数据库,同时Android手机要和XAMPP软件所在的计算机在同一个局域网中。