我们先来看一个简单的Android app例子(这里是一个商品存货清单项目),在Android程序中,我们可以访问(call)PHP脚本来执行简单的CRUD操作(创建,读取,更新,删除)。为了使你对它的体系结构有一个大概的了解,这里先说一下它是怎么工作的。首先你的Android项目访问(call)PHP脚本来执行一条数据操作,我们称它为“创建”。然后PHP脚本连接MySQL数据库来执行这个操作。这样,数据从Android程序流向PHP脚本,最终存储在MySQL数据库中。

好了,让我们来深入的看一下。

请注意:这里提供的代码只是为了使你能简单的连接Android项目和PHP,MySQL。你不能把它作为一个标准或者安全编程实践。在生产环境中,理想情况下你需要避免使用任何可能造成潜在注入漏洞的代码(比如MYSQL注入)。MYSQL注入是一个很大的话题,不可能用单独的一篇文章来说清楚,并且它也不在本文讨论的范围内,所以本文不以讨论。

1. 什么是WAMP Server

WAMP是Windows,Apache,MySQL和PHP,Perl,Python的简称。WAMP是一个一键安装的软件,它为开发PHP,MySQL Web应用程序提供一个环境。安装这款软件你相当于安装了Apache,MySQL和PHP。或者,你也可以使用XAMP。

2. 安装和使用WAMP Server

你可以从http://www.wampserver.com/en/下载WAMP,安装完成之后,可以从开始->所有程序->WampServer->StartWampServer运行该程序。

在浏览器中输入http://localhost/来测试你的服务器是否安装成功。同样的,也可以打开http://localhost/phpmyadmin来检验phpmyadmin是否安装成功。

3. 创建和运行PHP项目

现在,你已经有一个能开发PHP和MYSQL项目的环境了。打开安装WAMP Server的文件夹(在我的电脑中,是C:\wamp\),打开www文件夹,为你的项目创建一个新的文件夹。你必须把项目中所有的文件放到这个文件夹中。

新建一个名为android_connect的文件夹,并新建一个php文件,命名为test.php,尝试输入一些简单的php代码(如下所示)。输入下面的代码后,打开http://localhost/android_connect/test.php,你会在浏览器中看到“Welcome,I am connecting Android to PHP,MySQL”(如果没有正确输入,请检查WAMP配置是否正确)

test.php

echo"Welcome, I am connecting Android to PHP, MySQL";

?>

4. 创建MySQL数据库和表

在本教程中,我创建了一个简单的只有一张表的数据库。我会用这个表来执行一些示例操作。现在,请在浏览器中输入http://localhost/phpmyadmin/,并打开phpmyadmin。你可以用PhpMyAdmin工具创建数据库和表。

创建数据库和表:数据库名:androidhive,表:product

CREATE DATABASE androidhive;

CREATE TABLE products(

pid int(11) primary key auto_increment,

name varchar(100) not null,

price decimal(10,2) not null,

description text,

created_at timestamp defaultnow(),

updated_at timestamp

);

5. 用PHP连接MySQL数据库

现在,真正的服务器端编程开始了。新建一个PHP类来连接MYSQL数据库。这个类的主要功能是打开数据库连接和在不需要时关闭数据库连接。

新建两个文件db_config.php,db_connect.php

db_config.php--------存储数据库连接变量

db_connect.php-------连接数据库的类文件

db_config.php

/*

* All database connection variables

*/

define('DB_USER', "root"); // db user

define('DB_PASSWORD', ""); // db password (mention your db password here)

define('DB_DATABASE', "androidhive"); // database name

define('DB_SERVER', "localhost"); // db server

db_connect.php

/**

* A class file to connect to database

*/

classDB_CONNECT {

// constructor

function__construct() {

// connecting to database

$this->connect();

}

// destructor

function__destruct() {

// closing db connection

$this->close();

}

/**

* Function to connect with database

*/

functionconnect() {

// import database connection variables

require_once__DIR__ . '/db_config.php';

// Connecting to mysql database

$con= mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) ordie(mysql_error());

// Selecing database

$db= mysql_select_db(DB_DATABASE) ordie(mysql_error()) ordie(mysql_error());

// returing connection cursor

return$con;

}

/**

* Function to close db connection

*/

functionclose() {

// closing db connection

mysql_close();

}

}

?>

怎么调用:当你想连接MySQl数据库或者执行某些操作时,可以这样使用db_connect.php

$db= newDB_CONNECT(); // creating class object(will open database connection)

6. 使用PHP执行基本CRUD操作

在这部分,我将讲述使用PHP对MySQL数据库执行基本CRUD(创建,读取,更新,删除)操作。

如果你是PHP和MySQL新手,我建议你可以先学习PHP和SQL基础知识。

6. a)在MYSQL中新建一行(创建一行新的产品)

在你的PHP项目中新建一个php文件,命名为create_product.php,并输入以下代码。该文件主要实现在products表中插入一个新的产品。

在下面的代码我使用POST来读取产品数据并把他们存储在products表中。

最后我会输出一些JSON返回值,以便返回给客户端(Android项目)

create_product.php

/*

* Following code will create a new product row

* All product details are read from HTTP Post Request

*/

// array for JSON response

$response= array();

// check for required fields

if(isset($_POST['name']) && isset($_POST['price']) && isset($_POST['description'])) {

$name= $_POST['name'];

$price= $_POST['price'];

$description= $_POST['description'];

// include db connect class

require_once__DIR__ . '/db_connect.php';

// connecting to db

$db= newDB_CONNECT();

// mysql inserting a new row

$result= mysql_query("INSERT INTO products(name, price, description) VALUES('$name', '$price', '$description')");

// check if row inserted or not

if($result) {

// successfully inserted into database

$response["success"] = 1;

$response["message"] = "Product successfully created.";

// echoing JSON response

echojson_encode($response);

} else{

// failed to insert row

$response["success"] = 0;

$response["message"] = "Oops! An error occurred.";

// echoing JSON response

echojson_encode($response);

}

} else{

// required field is missing

$response["success"] = 0;

$response["message"] = "Required field(s) is missing";

// echoing JSON response

echojson_encode($response);

}

?>

对于上面的代码,JSON的返回值会是:

当POST 参数丢失

{

"success": 0,

"message": "Required field(s) is missing"

}

当product成功创建

{

"success": 1,

"message": "Product successfully created."

}

当插入数据时出现错误

{

"success": 0,

"message": "Oops! An error occurred."

}

6. b)从MySQL中读取一行信息(读取产品详细信息)

创建一个新的php文件,命名为get_product_details.php,写入以下代码。

该文件通过传递产品id作为POST参数获得单个产品的详细信息

get_product_details.php

/*

* Following code will get single product details

* A product is identified by product id (pid)

*/

// array for JSON response

$response= array();

// include db connect class

require_once__DIR__ . '/db_connect.php';

// connecting to db

$db= newDB_CONNECT();

// check for post data

if(isset($_GET["pid"])) {

$pid= $_GET['pid'];

// get a product from products table

$result= mysql_query("SELECT *FROM products WHERE pid = $pid");

if(!empty($result)) {

// check for empty result

if(mysql_num_rows($result) > 0) {

$result= mysql_fetch_array($result);

$product= array();

$product["pid"] = $result["pid"];

$product["name"] = $result["name"];

$product["price"] = $result["price"];

$product["description"] = $result["description"];

$product["created_at"] = $result["created_at"];

$product["updated_at"] = $result["updated_at"];

// success

$response["success"] = 1;

// user node

$response["product"] = array();

array_push($response["product"], $product);

// echoing JSON response

echojson_encode($response);

} else{

// no product found

$response["success"] = 0;

$response["message"] = "No product found";

// echo no users JSON

echojson_encode($response);

}

} else{

// no product found

$response["success"] = 0;

$response["message"] = "No product found";

// echo no users JSON

echojson_encode($response);

}

} else{

// required field is missing

$response["success"] = 0;

$response["message"] = "Required field(s) is missing";

// echoing JSON response

echojson_encode($response);

}

?>

The json response for the above file will be

When successfully getting product details

{

"success": 1,

"product": [

{

"pid": "1",

"name": "iPHone 4S",

"price": "300.00",

"description": "iPhone 4S white",

"created_at": "2012-04-29 01:41:42",

"updated_at": "0000-00-00 00:00:00"

}

]

}

When no product found with matched pid

{

"success": 0,

"message": "No product found"

}

6. c)从MySQL读取所有行(读取所有产品信息)

我们需要用json数据在Android设备上显示所有的产品。

新建一个php文件,命名为get_all_products.php,写入以下代码。

get_all_products.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

$db= newDB_CONNECT();

// get all products from products table

$result= mysql_query("SELECT *FROM products") ordie(mysql_error());

// check for empty result

if(mysql_num_rows($result) > 0) {

// looping through all results

// products node

$response["products"] = array();

while($row= mysql_fetch_array($result)) {

// temp user array

$product= array();

$product["pid"] = $row["pid"];

$product["name"] = $row["name"];

$product["price"] = $row["price"];

$product["created_at"] = $row["created_at"];

$product["updated_at"] = $row["updated_at"];

// push single product into final response array

array_push($response["products"], $product);

}

// success

$response["success"] = 1;

// echoing JSON response

echojson_encode($response);

} else{

// no products found

$response["success"] = 0;

$response["message"] = "No products found";

// echo no users JSON

echojson_encode($response);

}

?>

And the JSON response for above code

Listing all Products

{

"products": [

{

"pid": "1",

"name": "iPhone 4S",

"price": "300.00",

"created_at": "2012-04-29 02:04:02",

"updated_at": "0000-00-00 00:00:00"

},

{

"pid": "2",

"name": "Macbook Pro",

"price": "600.00",

"created_at": "2012-04-29 02:04:51",

"updated_at": "0000-00-00 00:00:00"

},

{

"pid": "3",

"name": "Macbook Air",

"price": "800.00",

"created_at": "2012-04-29 02:05:57",

"updated_at": "0000-00-00 00:00:00"

},

{

"pid": "4",

"name": "OS X Lion",

"price": "100.00",

"created_at": "2012-04-29 02:07:14",

"updated_at": "0000-00-00 00:00:00"

}

],

"success": 1

}

When products not found

{

"success": 0,

"message": "No products found"

}

6. d)在MySQL中更新某一行(更新产品详细信息)

新建一个php文件,命名为update_product.php。每一个产品通过pid标识。

update_product.php

/*

* Following code will update a product information

* A product is identified by product id (pid)

*/

// array for JSON response

$response= array();

// check for required fields

if(isset($_POST['pid']) && isset($_POST['name']) && isset($_POST['price']) && isset($_POST['description'])) {

$pid= $_POST['pid'];

$name= $_POST['name'];

$price= $_POST['price'];

$description= $_POST['description'];

// include db connect class

require_once__DIR__ . '/db_connect.php';

// connecting to db

$db= newDB_CONNECT();

// mysql update row with matched pid

$result= mysql_query("UPDATE products SET name = '$name', price = '$price', description = '$description' WHERE pid = $pid");

// check if row inserted or not

if($result) {

// successfully updated

$response["success"] = 1;

$response["message"] = "Product successfully updated.";

// echoing JSON response

echojson_encode($response);

} else{

}

} else{

// required field is missing

$response["success"] = 0;

$response["message"] = "Required field(s) is missing";

// echoing JSON response

echojson_encode($response);

}

?>

The json reponse of above code, when product is updated successfully

{

"success": 1,

"message": "Product successfully updated."

}

6. e)在MySQL中删除某一行(删除一个产品)

新建一个php文件,命名为delete_product.php。该文件主要功能是从数据库中删除一个产品。

delete_product.php

/*

* Following code will delete a product from table

* A product is identified by product id (pid)

*/

// array for JSON response

$response= array();

// check for required fields

if(isset($_POST['pid'])) {

$pid= $_POST['pid'];

// include db connect class

require_once__DIR__ . '/db_connect.php';

// connecting to db

$db= newDB_CONNECT();

// mysql update row with matched pid

$result= mysql_query("DELETE FROM products WHERE pid = $pid");

// check if row deleted or not

if(mysql_affected_rows() > 0) {

// successfully updated

$response["success"] = 1;

$response["message"] = "Product successfully deleted";

// echoing JSON response

echojson_encode($response);

} else{

// no product found

$response["success"] = 0;

$response["message"] = "No product found";

// echo no users JSON

echojson_encode($response);

}

} else{

// required field is missing

$response["success"] = 0;

$response["message"] = "Required field(s) is missing";

// echoing JSON response

echojson_encode($response);

}

?>

When product successfully deleted

{

"success": 1,

"message": "Product successfully deleted"

}

When product not found

{

"success": 0,

"message": "No product found"

}

到目前为止,我们为products表建立了一个简单的接口。服务器端编程已经完成了,接下来让我们开始真正的Android应用程序编程。

7. 新建一个Android应用程序

在Eclipse IDE中创建一个新项目,填写所需的细节信息。

1. 新建项目,在菜单中选择File->New->Android Project,把Activity类命名为MainScreenActivity

2. 打开AndroidManifest.xml,添加以下代码。我先在manifest文件中添加了所需的全部Activity类。同样需要添加INTERNET连接权限(非常重要)

AndroidManifest.xml

package="com.example.androidhive"

android:versionCode="1"

android:versionName="1.0">

android:configChanges="keyboardHidden|orientation"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name">

android:name=".MainScreenActivity"

android:label="@string/app_name">

android:name=".AllProductsActivity"

android:label="All Products">

android:name=".NewProductActivity"

android:label="Add New Product">

android:name=".EditProductActivity"

android:label="Edit Product">

3. 在res->layout文件夹下新建一个xml文件,命名为mian_screen.xml。这个layout文件包含两个简单的按钮,通过这两个按钮可以查看所有产品和添加新产品。如下图所示

main_screen.xml

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

android:gravity="center_horizontal">

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="View Products"

android:layout_marginTop="25dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Add New Products"

android:layout_marginTop="25dip"/>

4. 打开MainScreenActivity.java为main_screen.xml文件里的两个按钮添加点击事件

MainScreenActivity.java

packagecom.example.androidhive;

importandroid.app.Activity;

importandroid.content.Intent;

importandroid.os.Bundle;

importandroid.view.View;

importandroid.widget.Button;

publicclassMainScreenActivity extendsActivity{

Button btnViewProducts;

Button btnNewProduct;

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main_screen);

// Buttons

btnViewProducts = (Button) findViewById(R.id.btnViewProducts);

btnNewProduct = (Button) findViewById(R.id.btnCreateProduct);

// view products click event

btnViewProducts.setOnClickListener(newView.OnClickListener() {

@Override

publicvoidonClick(View view) {

// Launching All products Activity

Intent i = newIntent(getApplicationContext(), AllProductsActivity.class);

startActivity(i);

}

});

// view products click event

btnNewProduct.setOnClickListener(newView.OnClickListener() {

@Override

publicvoidonClick(View view) {

// Launching create new product activity

Intent i = newIntent(getApplicationContext(), NewProductActivity.class);

startActivity(i);

}

});

}

5. 在ListView中显示所有产品(读取)

现在我们需要一个Activity来以列表的形式显示所有产品。如我们所知,使用ListView需要两个xml文件,一个是列表布局,另一个是单个的列表项布局。在res->layout文件夹下新建两个xml文件:all_product.xml和list_item.xml

all_product.xml

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

android:id="@android:id/list"

android:layout_width="fill_parent"

android:layout_height="wrap_content"/>

list_item.xml

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:orientation="vertical">

android:id="@+id/pid"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:visibility="gone"/>

android:id="@+id/name"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:paddingTop="6dip"

android:paddingLeft="6dip"

android:textSize="17dip"

android:textStyle="bold"/>

6. 新建一个名为AllProductActivity.java的类文件。

在下面的代码中,

首先,在后台AsyncTask线程中发送一个请求给get_all_products.php

然后,从get_all_products.php获取JSON格式的数据,我为json转换了格式(parser),并使其显示在ListView中。

如果没有找到产品,会跳转到AddNewProductActivity

AllProductActivity.java

packagecom.example.androidhive;

importjava.util.ArrayList;

importjava.util.HashMap;

importjava.util.List;

importorg.apache.http.NameValuePair;

importorg.json.JSONArray;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.app.ListActivity;

importandroid.app.ProgressDialog;

importandroid.content.Intent;

importandroid.os.AsyncTask;

importandroid.os.Bundle;

importandroid.util.Log;

importandroid.view.View;

importandroid.widget.AdapterView;

importandroid.widget.AdapterView.OnItemClickListener;

importandroid.widget.ListAdapter;

importandroid.widget.ListView;

importandroid.widget.SimpleAdapter;

importandroid.widget.TextView;

publicclassAllProductsActivity extendsListActivity {

// Progress Dialog

privateProgressDialog pDialog;

// Creating JSON Parser object

JSONParser jParser = newJSONParser();

ArrayList> productsList;

// url to get all products list

privatestaticString url_all_products = "http://api.androidhive.info/android_connect/get_all_products.php";

// JSON Node names

privatestaticfinalString TAG_SUCCESS = "success";

privatestaticfinalString TAG_PRODUCTS = "products";

privatestaticfinalString TAG_PID = "pid";

privatestaticfinalString TAG_NAME = "name";

// products JSONArray

JSONArray products = null;

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.all_products);

// Hashmap for ListView

productsList = newArrayList>();

// Loading products in Background Thread

newLoadAllProducts().execute();

// Get listview

ListView lv = getListView();

// on seleting single product

// launching Edit Product Screen

lv.setOnItemClickListener(newOnItemClickListener() {

@Override

publicvoidonItemClick(AdapterView> parent, View view,

intposition, longid) {

// getting values from selected ListItem

String pid = ((TextView) view.findViewById(R.id.pid)).getText()

.toString();

// Starting new intent

Intent in = newIntent(getApplicationContext(),

EditProductActivity.class);

// sending pid to next activity

in.putExtra(TAG_PID, pid);

// starting new activity and expecting some response back

startActivityForResult(in, 100);

}

});

}

// Response from Edit Product Activity

@Override

protectedvoidonActivityResult(intrequestCode, intresultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

// if result code 100

if(resultCode == 100) {

// if result code 100 is received

// means user edited/deleted product

// reload this screen again

Intent intent = getIntent();

finish();

startActivity(intent);

}

}

/**

* Background Async Task to Load all product by making HTTP Request

* */

classLoadAllProducts extendsAsyncTask {

/**

* Before starting background thread Show Progress Dialog

* */

@Override

protectedvoidonPreExecute() {

super.onPreExecute();

pDialog = newProgressDialog(AllProductsActivity.this);

pDialog.setMessage("Loading products. Please wait...");

pDialog.setIndeterminate(false);

pDialog.setCancelable(false);

pDialog.show();

}

/**

* getting All products from url

* */

protectedString doInBackground(String... args) {

// Building Parameters

List params = newArrayList();

// getting JSON string from URL

JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);

// Check your log cat for JSON reponse

Log.d("All Products: ", json.toString());

try{

// Checking for SUCCESS TAG

intsuccess = json.getInt(TAG_SUCCESS);

if(success == 1) {

// products found

// Getting Array of Products

products = json.getJSONArray(TAG_PRODUCTS);

// looping through All Products

for(inti = 0; i < products.length(); i++) {

JSONObject c = products.getJSONObject(i);

// Storing each json item in variable

String id = c.getString(TAG_PID);

String name = c.getString(TAG_NAME);

// creating new HashMap

HashMap map = newHashMap();

// adding each child node to HashMap key => value

map.put(TAG_PID, id);

map.put(TAG_NAME, name);

// adding HashList to ArrayList

productsList.add(map);

}

} else{

// no products found

// Launch Add New product Activity

Intent i = newIntent(getApplicationContext(),

NewProductActivity.class);

// Closing all previous activities

i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

startActivity(i);

}

} catch(JSONException e) {

e.printStackTrace();

}

returnnull;

}

/**

* After completing background task Dismiss the progress dialog

* **/

protectedvoidonPostExecute(String file_url) {

// dismiss the dialog after getting all products

pDialog.dismiss();

// updating UI from Background Thread

runOnUiThread(newRunnable() {

publicvoidrun() {

/**

* Updating parsed JSON data into ListView

* */

ListAdapter adapter = newSimpleAdapter(

AllProductsActivity.this, productsList,

R.layout.list_item, newString[] { TAG_PID,

TAG_NAME},

newint[] { R.id.pid, R.id.name });

// updating listview

setListAdapter(adapter);

}

});

}

}

}

7. 添加一个新产品(写入)

创建一个新的view和activity来向MySQL数据库添加新产品。

新建一个简单的表单,创建提供输入产品名称,价格和描述的EditText

add_product.xml

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_height="wrap_content"

android:text="Product Name"

android:paddingLeft="10dip"

android:paddingRight="10dip"

android:paddingTop="10dip"

android:textSize="17dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_margin="5dip"

android:layout_marginBottom="15dip"

android:singleLine="true"/>

android:layout_height="wrap_content"

android:text="Price"

android:paddingLeft="10dip"

android:paddingRight="10dip"

android:paddingTop="10dip"

android:textSize="17dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_margin="5dip"

android:layout_marginBottom="15dip"

android:singleLine="true"

android:inputType="numberDecimal"/>

android:layout_height="wrap_content"

android:text="Description"

android:paddingLeft="10dip"

android:paddingRight="10dip"

android:paddingTop="10dip"

android:textSize="17dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_margin="5dip"

android:layout_marginBottom="15dip"

android:lines="4"

android:gravity="top"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Create Product"/>

8. 新建一个Activity来处理向MySQL数据库插入新产品。

新建名为NewProductActivity.java的文件,输入以下代码。在下面的代码中

首先,从EditText获得用户输入的产品数据,格式化成基本参数格式

然后,向create_product.php发送请求,通过HTTP POST创建一个新的产品

最后,从create_product.php获取json返回值,如果success值为1,新得到的列表中就加入了新增的产品。

NewProductActivity.java

packagecom.example.androidhive;

importjava.util.ArrayList;

importjava.util.List;

importorg.apache.http.NameValuePair;

importorg.apache.http.message.BasicNameValuePair;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.app.Activity;

importandroid.app.ProgressDialog;

importandroid.content.Intent;

importandroid.os.AsyncTask;

importandroid.os.Bundle;

importandroid.util.Log;

importandroid.view.View;

importandroid.widget.Button;

importandroid.widget.EditText;

publicclassNewProductActivity extendsActivity {

// Progress Dialog

privateProgressDialog pDialog;

JSONParser jsonParser = newJSONParser();

EditText inputName;

EditText inputPrice;

EditText inputDesc;

// url to create new product

privatestaticString url_create_product = "http://api.androidhive.info/android_connect/create_product.php";

// JSON Node names

privatestaticfinalString TAG_SUCCESS = "success";

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.add_product);

// Edit Text

inputName = (EditText) findViewById(R.id.inputName);

inputPrice = (EditText) findViewById(R.id.inputPrice);

inputDesc = (EditText) findViewById(R.id.inputDesc);

// Create button

Button btnCreateProduct = (Button) findViewById(R.id.btnCreateProduct);

// button click event

btnCreateProduct.setOnClickListener(newView.OnClickListener() {

@Override

publicvoidonClick(View view) {

// creating new product in background thread

newCreateNewProduct().execute();

}

});

}

/**

* Background Async Task to Create new product

* */

classCreateNewProduct extendsAsyncTask {

/**

* Before starting background thread Show Progress Dialog

* */

@Override

protectedvoidonPreExecute() {

super.onPreExecute();

pDialog = newProgressDialog(NewProductActivity.this);

pDialog.setMessage("Creating Product..");

pDialog.setIndeterminate(false);

pDialog.setCancelable(true);

pDialog.show();

}

/**

* Creating product

* */

protectedString doInBackground(String... args) {

String name = inputName.getText().toString();

String price = inputPrice.getText().toString();

String description = inputDesc.getText().toString();

// Building Parameters

List params = newArrayList();

params.add(newBasicNameValuePair("name", name));

params.add(newBasicNameValuePair("price", price));

params.add(newBasicNameValuePair("description", description));

// getting JSON Object

// Note that create product url accepts POST method

JSONObject json = jsonParser.makeHttpRequest(url_create_product,

"POST", params);

// check log cat fro response

Log.d("Create Response", json.toString());

// check for success tag

try{

intsuccess = json.getInt(TAG_SUCCESS);

if(success == 1) {

// successfully created product

Intent i = newIntent(getApplicationContext(), AllProductsActivity.class);

startActivity(i);

// closing this screen

finish();

} else{

// failed to create product

}

} catch(JSONException e) {

e.printStackTrace();

}

returnnull;

}

/**

* After completing background task Dismiss the progress dialog

* **/

protectedvoidonPostExecute(String file_url) {

// dismiss the dialog once done

pDialog.dismiss();

}

}

}

9. 读取,更新,删除一项产品

你稍加注意就会发现,在AllProductsActivity.java中,选中列表的某一项,会进入EditProductActivity.java。

接下来新建一个名为edit_product,xml的xml文件,创建类似create_product,xml的表单。

edit_product,xml

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_height="wrap_content"

android:text="Product Name"

android:paddingLeft="10dip"

android:paddingRight="10dip"

android:paddingTop="10dip"

android:textSize="17dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_margin="5dip"

android:layout_marginBottom="15dip"

android:singleLine="true"/>

android:layout_height="wrap_content"

android:text="Price"

android:paddingLeft="10dip"

android:paddingRight="10dip"

android:paddingTop="10dip"

android:textSize="17dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_margin="5dip"

android:layout_marginBottom="15dip"

android:singleLine="true"

android:inputType="numberDecimal"/>

android:layout_height="wrap_content"

android:text="Description"

android:paddingLeft="10dip"

android:paddingRight="10dip"

android:paddingTop="10dip"

android:textSize="17dip"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_margin="5dip"

android:layout_marginBottom="15dip"

android:lines="4"

android:gravity="top"/>

android:layout_height="wrap_content"

android:orientation="horizontal">

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Save Changes"

android:layout_weight="1"/>

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="Delete"

android:layout_weight="1"/>

10. 对应edit_product.xml新建EditProductActivity.java,并输入下列代码。

在以下代码中:

首先,从intent中读取发送给ListView的产品id(pid)

然后,向get_product_details.php发送请求,获得json格式的产品详细信息,把它显示在EditText中。

然后,当产品信息显示在表单中后,如果用户点击保存按钮,会向update_product.php发送另一个HTTP请求,更新数据库中的产品信息

如果用户点击删除按钮,将会向delete_product.php发送请求,该产品慧聪MySQL数据库中删除,ListView刷新后显示新的产品列表。

EditProductActivity.java

packagecom.example.androidhive;

importjava.util.ArrayList;

importjava.util.List;

importorg.apache.http.NameValuePair;

importorg.apache.http.message.BasicNameValuePair;

importorg.json.JSONArray;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.app.Activity;

importandroid.app.ProgressDialog;

importandroid.content.Intent;

importandroid.os.AsyncTask;

importandroid.os.Bundle;

importandroid.util.Log;

importandroid.view.View;

importandroid.widget.Button;

importandroid.widget.EditText;

publicclassEditProductActivity extendsActivity {

EditText txtName;

EditText txtPrice;

EditText txtDesc;

EditText txtCreatedAt;

Button btnSave;

Button btnDelete;

String pid;

// Progress Dialog

privateProgressDialog pDialog;

// JSON parser class

JSONParser jsonParser = newJSONParser();

// single product url

privatestaticfinalString url_product_detials = "http://api.androidhive.info/android_connect/get_product_details.php";

// url to update product

privatestaticfinalString url_update_product = "http://api.androidhive.info/android_connect/update_product.php";

// url to delete product

privatestaticfinalString url_delete_product = "http://api.androidhive.info/android_connect/delete_product.php";

// JSON Node names

privatestaticfinalString TAG_SUCCESS = "success";

privatestaticfinalString TAG_PRODUCT = "product";

privatestaticfinalString TAG_PID = "pid";

privatestaticfinalString TAG_NAME = "name";

privatestaticfinalString TAG_PRICE = "price";

privatestaticfinalString TAG_DESCRIPTION = "description";

@Override

publicvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.edit_product);

// save button

btnSave = (Button) findViewById(R.id.btnSave);

btnDelete = (Button) findViewById(R.id.btnDelete);

// getting product details from intent

Intent i = getIntent();

// getting product id (pid) from intent

pid = i.getStringExtra(TAG_PID);

// Getting complete product details in background thread

newGetProductDetails().execute();

// save button click event

btnSave.setOnClickListener(newView.OnClickListener() {

@Override

publicvoidonClick(View arg0) {

// starting background task to update product

newSaveProductDetails().execute();

}

});

// Delete button click event

btnDelete.setOnClickListener(newView.OnClickListener() {

@Override

publicvoidonClick(View arg0) {

// deleting product in background thread

newDeleteProduct().execute();

}

});

}

/**

* Background Async Task to Get complete product details

* */

classGetProductDetails extendsAsyncTask {

/**

* Before starting background thread Show Progress Dialog

* */

@Override

protectedvoidonPreExecute() {

super.onPreExecute();

pDialog = newProgressDialog(EditProductActivity.this);

pDialog.setMessage("Loading product details. Please wait...");

pDialog.setIndeterminate(false);

pDialog.setCancelable(true);

pDialog.show();

}

/**

* Getting product details in background thread

* */

protectedString doInBackground(String... params) {

// updating UI from Background Thread

runOnUiThread(newRunnable() {

publicvoidrun() {

// Check for success tag

intsuccess;

try{

// Building Parameters

List params = newArrayList();

params.add(newBasicNameValuePair("pid", pid));

// getting product details by making HTTP request

// Note that product details url will use GET request

JSONObject json = jsonParser.makeHttpRequest(

url_product_detials, "GET", params);

// check your log for json response

Log.d("Single Product Details", json.toString());

// json success tag

success = json.getInt(TAG_SUCCESS);

if(success == 1) {

// successfully received product details

JSONArray productObj = json

.getJSONArray(TAG_PRODUCT); // JSON Array

// get first product object from JSON Array

JSONObject product = productObj.getJSONObject(0);

// product with this pid found

// Edit Text

txtName = (EditText) findViewById(R.id.inputName);

txtPrice = (EditText) findViewById(R.id.inputPrice);

txtDesc = (EditText) findViewById(R.id.inputDesc);

// display product data in EditText

txtName.setText(product.getString(TAG_NAME));

txtPrice.setText(product.getString(TAG_PRICE));

txtDesc.setText(product.getString(TAG_DESCRIPTION));

}else{

// product with pid not found

}

} catch(JSONException e) {

e.printStackTrace();

}

}

});

returnnull;

}

/**

* After completing background task Dismiss the progress dialog

* **/

protectedvoidonPostExecute(String file_url) {

// dismiss the dialog once got all details

pDialog.dismiss();

}

}

/**

* Background Async Task to Save product Details

* */

classSaveProductDetails extendsAsyncTask {

/**

* Before starting background thread Show Progress Dialog

* */

@Override

protectedvoidonPreExecute() {

super.onPreExecute();

pDialog = newProgressDialog(EditProductActivity.this);

pDialog.setMessage("Saving product ...");

pDialog.setIndeterminate(false);

pDialog.setCancelable(true);

pDialog.show();

}

/**

* Saving product

* */

protectedString doInBackground(String... args) {

// getting updated data from EditTexts

String name = txtName.getText().toString();

String price = txtPrice.getText().toString();

String description = txtDesc.getText().toString();

// Building Parameters

List params = newArrayList();

params.add(newBasicNameValuePair(TAG_PID, pid));

params.add(newBasicNameValuePair(TAG_NAME, name));

params.add(newBasicNameValuePair(TAG_PRICE, price));

params.add(newBasicNameValuePair(TAG_DESCRIPTION, description));

// sending modified data through http request

// Notice that update product url accepts POST method

JSONObject json = jsonParser.makeHttpRequest(url_update_product,

"POST", params);

// check json success tag

try{

intsuccess = json.getInt(TAG_SUCCESS);

if(success == 1) {

// successfully updated

Intent i = getIntent();

// send result code 100 to notify about product update

setResult(100, i);

finish();

} else{

// failed to update product

}

} catch(JSONException e) {

e.printStackTrace();

}

returnnull;

}

/**

* After completing background task Dismiss the progress dialog

* **/

protectedvoidonPostExecute(String file_url) {

// dismiss the dialog once product uupdated

pDialog.dismiss();

}

}

/*****************************************************************

* Background Async Task to Delete Product

* */

classDeleteProduct extendsAsyncTask {

/**

* Before starting background thread Show Progress Dialog

* */

@Override

protectedvoidonPreExecute() {

super.onPreExecute();

pDialog = newProgressDialog(EditProductActivity.this);

pDialog.setMessage("Deleting Product...");

pDialog.setIndeterminate(false);

pDialog.setCancelable(true);

pDialog.show();

}

/**

* Deleting product

* */

protectedString doInBackground(String... args) {

// Check for success tag

intsuccess;

try{

// Building Parameters

List params = newArrayList();

params.add(newBasicNameValuePair("pid", pid));

// getting product details by making HTTP request

JSONObject json = jsonParser.makeHttpRequest(

url_delete_product, "POST", params);

// check your log for json response

Log.d("Delete Product", json.toString());

// json success tag

success = json.getInt(TAG_SUCCESS);

if(success == 1) {

// product successfully deleted

// notify previous activity by sending code 100

Intent i = getIntent();

// send result code 100 to notify about product deletion

setResult(100, i);

finish();

}

} catch(JSONException e) {

e.printStackTrace();

}

returnnull;

}

/**

* After completing background task Dismiss the progress dialog

* **/

protectedvoidonPostExecute(String file_url) {

// dismiss the dialog once product deleted

pDialog.dismiss();

}

}

}

11. JSONParser类

我用一个JSONParser类从URL获得JSON格式的数据。这个类支持两种http请求,GET和POST方法从URL获取JSON数据

JSONParser.java

packagecom.example.androidhive;

importjava.io.BufferedReader;

importjava.io.IOException;

importjava.io.InputStream;

importjava.io.InputStreamReader;

importjava.io.UnsupportedEncodingException;

importjava.util.List;

importorg.apache.http.HttpEntity;

importorg.apache.http.HttpResponse;

importorg.apache.http.NameValuePair;

importorg.apache.http.client.ClientProtocolException;

importorg.apache.http.client.entity.UrlEncodedFormEntity;

importorg.apache.http.client.methods.HttpGet;

importorg.apache.http.client.methods.HttpPost;

importorg.apache.http.client.utils.URLEncodedUtils;

importorg.apache.http.impl.client.DefaultHttpClient;

importorg.json.JSONException;

importorg.json.JSONObject;

importandroid.util.Log;

publicclassJSONParser {

staticInputStream is = null;

staticJSONObject jObj = null;

staticString json = "";

// constructor

publicJSONParser() {

}

// function get json from url

// by making HTTP POST or GET mehtod

publicJSONObject makeHttpRequest(String url, String method,

List params) {

// Making HTTP request

try{

// check for request method

if(method == "POST"){

// request method is POST

// defaultHttpClient

DefaultHttpClient httpClient = newDefaultHttpClient();

HttpPost httpPost = newHttpPost(url);

httpPost.setEntity(newUrlEncodedFormEntity(params));

HttpResponse httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity = httpResponse.getEntity();

is = httpEntity.getContent();

}elseif(method == "GET"){

// request method is GET

DefaultHttpClient httpClient = newDefaultHttpClient();

String paramString = URLEncodedUtils.format(params, "utf-8");

url += "?"+ paramString;

HttpGet httpGet = newHttpGet(url);

HttpResponse httpResponse = httpClient.execute(httpGet);

HttpEntity httpEntity = httpResponse.getEntity();

is = httpEntity.getContent();

}

} catch(UnsupportedEncodingException e) {

e.printStackTrace();

} catch(ClientProtocolException e) {

e.printStackTrace();

} catch(IOException e) {

e.printStackTrace();

}

try{

BufferedReader reader = newBufferedReader(newInputStreamReader(

is, "iso-8859-1"), 8);

StringBuilder sb = newStringBuilder();

String line = null;

while((line = reader.readLine()) != null) {

sb.append(line + "\n");

}

is.close();

json = sb.toString();

} catch(Exception e) {

Log.e("Buffer Error", "Error converting result "+ e.toString());

}

// try parse the string to a JSON object

try{

jObj = newJSONObject(json);

} catch(JSONException e) {

Log.e("JSON Parser", "Error parsing data "+ e.toString());

}

// return JSON String

returnjObj;

}

}

到这里,本教程就结束了。

运行你的代码,测试一下程序吧。你可能会遇到不少错误,经常使用LogCat来调试你的项目。

php和android和mysql_如何使用JSON连接Android和PHP Mysql数据库相关推荐

  1. python解析json文件写入数据库_Python3实现将本地JSON大数据文件写入MySQL数据库的方法...

    本文实例讲述了Python3实现将本地JSON大数据文件写入MySQL数据库的方法.分享给大家供大家参考,具体如下: 最近导师给了一个yelp上的评论数据,数据量达到3.55个G,如果进行分析时直接使 ...

  2. 计算机毕业设计之android平台的出租打车软件app(源码+系统+mysql数据库+Lw文档)

    城市生活中,出租车已经成为人们日常出行经常使用的交通工具.但城市里每天上下班时间人流较大,给人的出行带来不便,有些偏远的地区也许只有少数的公交车,上下班时人数又比较多,上不了公交,而这些地方招出租车也 ...

  3. 语言把数据写入csv文件_把JSON/CSV文件打造成MySQL数据库

    生活中,你我一定都看到过这种「xx元爆改出租屋」,「爆改小汽车」之类的文章,做为IT人,折腾的劲头一点也不差. 软件开发过程中,你是否有时候,会拿着业务提供的一个个CSV或者JSON的数据文件,写个解 ...

  4. Scrapy网络爬虫实战[保存为Json文件及存储到mysql数据库]

    本文博客为原创,未经本人允许,不得扒下来传到百度文库及相关平台. 目录 Scrapy介绍 Scrapy建立新工程 用Pycharm打开工程并编辑 items的编写 Spider的编写 存储pipeli ...

  5. android蓝牙在有效范围内自动连接,android – 如何在范围内找到可用的蓝牙设备?...

    这就是我在Activity中搜索蓝牙设备并在ListView中显示其名称和mac地址的方法.除了在ListView中显示设备外,您几乎可以使用发现的BluetoothDevice对象执行任何操作. F ...

  6. java解析json文件并保存到mysql数据库

    一.数据是从"聚合数据"这个网站获取的,点我下载json文件,访问相应的地址,就返回很长的json格式的数据.因为不太了解json数据格式,我自己另外加了双引号(其实值的部分可以是 ...

  7. 计算机毕业设计Android高校图书馆推荐书目系统APP(源码+系统+mysql数据库+Lw文档)

    项目介绍 本次毕业设计采用B/S模式进行设计,结合Android技术设计一个高校图书馆推荐书目系统,数据口采用瑞典MySQL AB公司的MySQL数据库,此系统是为高校图书馆推荐书目设计的,具有一定的 ...

  8. 计算机毕业设计android的消防安全知识宣传app(源码+系统+mysql数据库+Lw文档)

    项目介绍 近年来,随着消防重要性的逐渐增加,人工书写数据已经不能够处理如此庞大的数据.为了更好的适应信息时代的高效性,一个利用计算机来实现消防网站工作的网站将必然诞生.基于这一点,设计了一个消防网站, ...

  9. 计算机毕业设计Android家庭理财系统手机软件app(源码+系统+mysql数据库+Lw文档)

    项目介绍 本Android家庭理财系统app包含有手机端(客户端)和电脑端(服务端),服务端开发环境是eclipse,客户端开发环境是Android eclipse ADT. 总结出本系统需要的功能如 ...

最新文章

  1. Python3 调试技巧 —— 死循环
  2. 以太网的MAC帧(二)
  3. Buildroot构建指南——工具链
  4. 利用ant构建 jsp-servlet-class-jar
  5. Linux下磁盘分区卸载和磁盘配额
  6. SQL SERVER占用CPU过高排查和优化
  7. oracle递归查询出现死循环,oracle 递归查询求出起点、终点问题的解决方法
  8. SQL优化之not in
  9. 清北复交人浙南 计算机交叉学科项目大盘点
  10. 怎样一次删除许多WPS word中的文本框(及其内容)?简单方法
  11. DDOS hulk,rudy
  12. JAVA 学习第三天 Scanner顺序\选择\循环结构!
  13. 最详细bugku杂项小白解法(1~24已完结)
  14. maya linux 安装教程视频,Maya快捷键插件增强工具ZooTools Pro 2.2.4 for Maya Win/Linux+ Assets pack 2.3+视频教程...
  15. java是c语言吗_java和c语言的区别是什么
  16. jQuery 下载保存图片的方法
  17. 目前为止学习过的循环解析过程
  18. Office 365导出PDF带备注页
  19. mysql5.7增加ssl认证(1)
  20. cometd: Bayeux Protocol

热门文章

  1. iso14443_TypeB TR0/TR1/TR2 时序观测
  2. 如何拆分PDF成多个文件?这样拆分非常简单
  3. 快递查询APP隐私条款
  4. 盘点2020年北京市小升初考试关于信息学竞赛的那些事儿!
  5. 关于extjs中的cls ≠ class
  6. ChatGPT套壳网站汇总-5月22日更新
  7. 爱上一个自己讨厌的人
  8. linux 读取内存颗粒,Linux中的内存管理模型浅析
  9. 中国的美女为什么这样少的原因
  10. Win11十二月系统更新了什么内容?