如何使用JSON连接Android和PHP Mysql数据库

我们先来看一个简单的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

 

<?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

 

<?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

<?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新手,我建议你可以先学习PHPSQL基础知识。

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

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

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

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

create_product.php

 

<?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

 

<?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

 

<?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

 

<?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

 

<?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

 

<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidhive"
android:versionCode="1"
android:versionName="1.0">
<uses-sdkandroid:minSdkVersion="8"/>
<application
android:configChanges="keyboardHidden|orientation"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<activity
android:name=".MainScreenActivity"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- All Product Activity -->
<activity
android:name=".AllProductsActivity"
android:label="All Products">
</activity>
<!-- Add Product Activity -->
<activity
android:name=".NewProductActivity"
android:label="Add New Product">
</activity>
<!-- Edit Product Activity -->
<activity
android:name=".EditProductActivity"
android:label="Edit Product">
</activity>
</application>
<!-- Internet Permissions -->
<uses-permissionandroid:name="android.permission.INTERNET"/>
</manifest>

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

 

main_screen.xml

 

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal">
<!-- Sample Dashboard screen with Two buttons -->
<!-- Button to view all products screen -->
<Buttonandroid:id="@+id/btnViewProducts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="View Products"
android:layout_marginTop="25dip"/>
<!-- Button to create a new product screen -->
<Buttonandroid:id="@+id/btnCreateProduct"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Add New Products"
android:layout_marginTop="25dip"/>
</LinearLayout>





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

 

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- Main ListView 
Always give id value as list(@android:id/list) 
-->
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

list_item.xml

 

 

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Product id (pid) - will be HIDDEN - used to pass to other activity -->
<TextView
android:id="@+id/pid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<!-- Name Label -->
<TextView
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"/>
</LinearLayout>

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<HashMap<String, String>> 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<HashMap<String, String>>(); 
// 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<String, String, String> { 
/** 
* 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<NameValuePair> params = newArrayList<NameValuePair>(); 
// 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<String, String> map = newHashMap<String, String>(); 
// 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

 

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Name Label -->
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Product Name"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="17dip"/>
<!-- Input Name -->
<EditTextandroid:id="@+id/inputName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_marginBottom="15dip"
android:singleLine="true"/>
<!-- Price Label -->
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Price"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="17dip"/>
<!-- Input Price -->
<EditTextandroid:id="@+id/inputPrice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_marginBottom="15dip"
android:singleLine="true"
android:inputType="numberDecimal"/>
<!-- Description Label -->
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Description"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="17dip"/>
<!-- Input description -->
<EditTextandroid:id="@+id/inputDesc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_marginBottom="15dip"
android:lines="4"
android:gravity="top"/>
<!-- Button Create Product -->
<Buttonandroid:id="@+id/btnCreateProduct"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Create Product"/>
</LinearLayout>

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<String, String, String> { 
/** 
* 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<NameValuePair> params = newArrayList<NameValuePair>(); 
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

 

<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Name Label -->
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Product Name"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="17dip"/>
<!-- Input Name -->
<EditTextandroid:id="@+id/inputName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_marginBottom="15dip"
android:singleLine="true"/>
<!-- Price Label -->
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Price"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="17dip"/>
<!-- Input Price -->
<EditTextandroid:id="@+id/inputPrice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_marginBottom="15dip"
android:singleLine="true"
android:inputType="numberDecimal"/>
<!-- Description Label -->
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Description"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="17dip"/>
<!-- Input description -->
<EditTextandroid:id="@+id/inputDesc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_marginBottom="15dip"
android:lines="4"
android:gravity="top"/>
<LinearLayoutandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Button Create Product -->
<Buttonandroid:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Save Changes"
android:layout_weight="1"/>
<!-- Button Create Product -->
<Buttonandroid:id="@+id/btnDelete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Delete"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>

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<String, String, String> { 
/** 
* 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<NameValuePair> params = newArrayList<NameValuePair>(); 
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<String, String, String> { 
/** 
* 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<NameValuePair> params = newArrayList<NameValuePair>(); 
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<String, String, String> { 
/** 
* 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<NameValuePair> params = newArrayList<NameValuePair>(); 
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<NameValuePair> 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来调试你的项目。

如果你不能解决那些错误,请在此留言。
原文链接:http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/

转载于:https://www.cnblogs.com/cc-Cheng/archive/2012/09/18/2714076.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值