如何使用JSON连接Android和PHP Mysql数据库
2012-09-18 18:08
786 查看
我们先来看一个简单的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
在本教程中,我创建了一个简单的只有一张表的数据库。我会用这个表来执行一些示例操作。现在,请在浏览器中输入http://localhost/phpmyadmin/,并打开phpmyadmin。你可以用PhpMyAdmin工具创建数据库和表。
创建数据库和表:数据库名:androidhive,表:product
现在,真正的服务器端编程开始了。新建一个PHP类来连接MYSQL数据库。这个类的主要功能是打开数据库连接和在不需要时关闭数据库连接。
新建两个文件db_config.php,db_connect.php
db_config.php--------存储数据库连接变量
db_connect.php-------连接数据库的类文件
db_config.php
这里的DB_USER DB_PASSWORD要换成自己数据库对应的用户名、密码
db_connect.php
在这部分,我将讲述使用PHP对MySQL数据库执行基本CRUD(创建,读取,更新,删除)操作。
如果你是PHP和MySQL新手,我建议你可以先学习PHP和SQL基础知识。
6. a)在MYSQL中新建一行(创建一行新的产品)
在你的PHP项目中新建一个php文件,命名为create_product.php,并输入以下代码。该文件主要实现在products表中插入一个新的产品。
在下面的代码我使用POST来读取产品数据并把他们存储在products表中。
最后我会输出一些JSON返回值,以便返回给客户端(Android项目)
create_product.php
当POST 参数丢失
实际测试的时候,出现Required field(s) is missing php错误,我把$_POST换成$_GET就对了,对应的NewProductActivity也要换成GET方法
6. b)从MySQL中读取一行信息(读取产品详细信息)
创建一个新的php文件,命名为get_product_details.php,写入以下代码。
该文件通过传递产品id作为POST参数获得单个产品的详细信息
get_product_details.php
我们需要用json数据在Android设备上显示所有的产品。
新建一个php文件,命名为get_all_products.php,写入以下代码。
get_all_products.php
新建一个php文件,命名为update_product.php。每一个产品通过pid标识。
update_product.php
新建一个php文件,命名为delete_product.php。该文件主要功能是从数据库中删除一个产品。
delete_product.php
7. 新建一个Android应用程序
在Eclipse IDE中创建一个新项目,填写所需的细节信息。
1. 新建项目,在菜单中选择File->New->Android Project,把Activity类命名为MainScreenActivity
2. 打开AndroidManifest.xml,添加以下代码。我先在manifest文件中添加了所需的全部Activity类。同样需要添加INTERNET连接权限(非常重要)
AndroidManifest.xml
main_screen.xml
4. 打开MainScreenActivity.java为main_screen.xml文件里的两个按钮添加点击事件
MainScreenActivity.java
现在我们需要一个Activity来以列表的形式显示所有产品。如我们所知,使用ListView需要两个xml文件,一个是列表布局,另一个是单个的列表项布局。在res->layout文件夹下新建两个xml文件:all_product.xml和list_item.xml
all_product.xml
在下面的代码中,
首先,在后台AsyncTask线程中发送一个请求给get_all_products.php
然后,从get_all_products.php获取JSON格式的数据,我为json转换了格式(parser),并使其显示在ListView中。
如果没有找到产品,会跳转到AddNewProductActivity
AllProductActivity.java
7. 添加一个新产品(写入)
创建一个新的view和activity来向MySQL数据库添加新产品。
新建一个简单的表单,创建提供输入产品名称,价格和描述的EditText
add_product.xml
8. 新建一个Activity来处理向MySQL数据库插入新产品。
新建名为NewProductActivity.java的文件,输入以下代码。在下面的代码中
首先,从EditText获得用户输入的产品数据,格式化成基本参数格式
然后,向create_product.php发送请求,通过HTTP POST创建一个新的产品
最后,从create_product.php获取json返回值,如果success值为1,新得到的列表中就加入了新增的产品。
NewProductActivity.java
你稍加注意就会发现,在AllProductsActivity.java中,选中列表的某一项,会进入EditProductActivity.java。
接下来新建一个名为edit_product,xml的xml文件,创建类似create_product,xml的表单。
edit_product,xml
在以下代码中:
首先,从intent中读取发送给ListView的产品id(pid)
然后,向get_product_details.php发送请求,获得json格式的产品详细信息,把它显示在EditText中。
然后,当产品信息显示在表单中后,如果用户点击保存按钮,会向update_product.php发送另一个HTTP请求,更新数据库中的产品信息
如果用户点击删除按钮,将会向delete_product.php发送请求,该产品慧聪MySQL数据库中删除,ListView刷新后显示新的产品列表。
EditProductActivity.java
11. JSONParser类
我用一个JSONParser类从URL获得JSON格式的数据。这个类支持两种http请求,GET和POST方法从URL获取JSON数据
JSONParser.java
运行你的代码,测试一下程序吧。你可能会遇到不少错误,经常使用LogCat来调试你的项目。
如果你不能解决那些错误,请在此留言。
原文链接:http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/
测试环境:WAMP: 2.4 Apache :2.4.4 PHP: 5.4.16
源码下载地址: http://download.csdn.net/detail/welovesunflower/7383361
好了,让我们来深入的看一下。
请注意:这里提供的代码只是为了使你能简单的连接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 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 default now(), 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_USER DB_PASSWORD要换成自己数据库对应的用户名、密码
db_connect.php
<?php /** * A class file to connect to database */ class DB_CONNECT { // constructor function __construct() { // connecting to database $this->connect(); } // destructor function __destruct() { // closing db connection $this->close(); } /** * Function to connect with database */ function connect() { // import database connection variables require_once __DIR__ . '/db_config.php'; // Connecting to mysql database $con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysql_error()); // Selecing database $db = mysql_select_db(DB_DATABASE) or die(mysql_error()) or die(mysql_error()); // returing connection cursor return $con; } /** * Function to close db connection */ function close() { // closing db connection mysql_close(); } } ?>怎么调用:当你想连接MySQl数据库或者执行某些操作时,可以这样使用db_connect.php
$db= new DB_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
<?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 = new DB_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 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); } ?>对于上面的代码,JSON的返回值会是:
当POST 参数丢失
{ "success": 0, "message": "Required field(s) is missing" }当product成功创建
{ "success": 1, "message": "Product successfully created." }当插入数据时出现错误
{ "success": 0, "message": "Oops! An error occurred." }
实际测试的时候,出现Required field(s) is missing php错误,我把$_POST换成$_GET就对了,对应的NewProductActivity也要换成GET方法
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 = new DB_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 echo json_encode($response); } else { // no product found $response["success"] = 0; $response["message"] = "No product found"; // echo no users JSON echo json_encode($response); } } else { // no product found $response["success"] = 0; $response["message"] = "No product found"; // echo no users JSON 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); } ?>
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 = new DB_CONNECT(); // get all products from products table $result = mysql_query("SELECT *FROM products") or die(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 echo json_encode($response); } else { // no products found $response["success"] = 0; $response["message"] = "No products found"; // echo no users JSON echo json_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 = new DB_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 echo json_encode($response); } else { } } else { // required field is missing $response["success"] = 0; $response["message"] = "Required field(s) is missing"; // echoing JSON response echo json_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 = new DB_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 echo json_encode($response); } else { // no product found $response["success"] = 0; $response["message"] = "No product found"; // echo no users JSON 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); } ?>
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
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.androidhive" android:versionCode="1" android:versionName="1.0" > <uses-sdk android: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> <action android:name="android.intent.action.MAIN" /> <category android: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-permission android:name="android.permission.INTERNET" /> </manifest>3. 在res->layout文件夹下新建一个xml文件,命名为mian_screen.xml。这个layout文件包含两个简单的按钮,通过这两个按钮可以查看所有产品和添加新产品。如下图所示
main_screen.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: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 --> <Button android: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 --> <Button android: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
package com.example.androidhive; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainScreenActivity extends Activity{ Button btnViewProducts; Button btnNewProduct; @Override public void onCreate(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(new View.OnClickListener() { @Override public void onClick(View view) { // Launching All products Activity Intent i = new Intent(getApplicationContext(), AllProductsActivity.class); startActivity(i); } }); // view products click event btnNewProduct.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Launching create new product activity Intent i = new Intent(getApplicationContext(), NewProductActivity.class); startActivity(i); } }); } }5. 在ListView中显示所有产品(读取)
现在我们需要一个Activity来以列表的形式显示所有产品。如我们所知,使用ListView需要两个xml文件,一个是列表布局,另一个是单个的列表项布局。在res->layout文件夹下新建两个xml文件:all_product.xml和list_item.xml
all_product.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: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
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: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
package com.example.androidhive; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.http.NameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.ListActivity; import android.app.ProgressDialog; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; public class AllProductsActivity extends ListActivity { // Progress Dialog private ProgressDialog pDialog; // Creating JSON Parser object JSONParser jParser = new JSONParser(); ArrayList<HashMap<String, String>> productsList; // url to get all products list private static String url_all_products = "http://api.androidhive.info/android_connect/get_all_products.php"; // JSON Node names private static final String TAG_SUCCESS = "success"; private static final String TAG_PRODUCTS = "products"; private static final String TAG_PID = "pid"; private static final String TAG_NAME = "name"; // products JSONArray JSONArray products = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.all_products); // Hashmap for ListView productsList = new ArrayList<HashMap<String, String>>(); // Loading products in Background Thread new LoadAllProducts().execute(); // Get listview ListView lv = getListView(); // on seleting single product // launching Edit Product Screen lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // getting values from selected ListItem String pid = ((TextView) view.findViewById(R.id.pid)).getText() .toString(); // Starting new intent Intent in = new Intent(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 protected void onActivityResult(int requestCode, int resultCode, 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 * */ class LoadAllProducts extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(AllProductsActivity.this); pDialog.setMessage("Loading products. Please wait..."); pDialog.setIndeterminate(false); pDialog.setCancelable(false); pDialog.show(); } /** * getting All products from url * */ protected String doInBackground(String... args) { // Building Parameters List<NameValuePair> params = new ArrayList<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 int success = json.getInt(TAG_SUCCESS); if (success == 1) { // products found // Getting Array of Products products = json.getJSONArray(TAG_PRODUCTS); // looping through All Products for (int i = 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 = new HashMap<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 = new Intent(getApplicationContext(), NewProductActivity.class); // Closing all previous activities i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); } } catch (JSONException e) { e.printStackTrace(); } return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog after getting all products pDialog.dismiss(); // updating UI from Background Thread runOnUiThread(new Runnable() { public void run() { /** * Updating parsed JSON data into ListView * */ ListAdapter adapter = new SimpleAdapter( AllProductsActivity.this, productsList, R.layout.list_item, new String[] { TAG_PID, TAG_NAME}, new int[] { R.id.pid, R.id.name }); // updating listview setListAdapter(adapter); } }); } } }
7. 添加一个新产品(写入)
创建一个新的view和activity来向MySQL数据库添加新产品。
新建一个简单的表单,创建提供输入产品名称,价格和描述的EditText
add_product.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" > <!-- Name Label --> <TextView android: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 --> <EditText android: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 --> <TextView android: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 --> <EditText android: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 --> <TextView android: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 --> <EditText android: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 --> <Button android: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
package com.example.androidhive; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; public class NewProductActivity extends Activity { // Progress Dialog private ProgressDialog pDialog; JSONParser jsonParser = new JSONParser(); EditText inputName; EditText inputPrice; EditText inputDesc; // url to create new product private static String url_create_product = "http://api.androidhive.info/android_connect/create_product.php"; // JSON Node names private static final String TAG_SUCCESS = "success"; @Override public void onCreate(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(new View.OnClickListener() { @Override public void onClick(View view) { // creating new product in background thread new CreateNewProduct().execute(); } }); } /** * Background Async Task to Create new product * */ class CreateNewProduct extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(NewProductActivity.this); pDialog.setMessage("Creating Product.."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Creating product * */ protected String doInBackground(String... args) { String name = inputName.getText().toString(); String price = inputPrice.getText().toString(); String description = inputDesc.getText().toString(); // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("name", name)); params.add(new BasicNameValuePair("price", price)); params.add(new BasicNameValuePair("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 { int success = json.getInt(TAG_SUCCESS); if (success == 1) { // successfully created product Intent i = new Intent(getApplicationContext(), AllProductsActivity.class); startActivity(i); // closing this screen finish(); } else { // failed to create product } } catch (JSONException e) { e.printStackTrace(); } return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(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
<?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" > <!-- Name Label --> <TextView android: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 --> <EditText android: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 --> <TextView android: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 --> <EditText android: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 --> <TextView android: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 --> <EditText android: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"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <!-- Button Create Product --> <Button android:id="@+id/btnSave" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Save Changes" android:layout_weight="1"/> <!-- Button Create Product --> <Button android: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
package com.example.androidhive; import java.util.ArrayList; import java.util.List; import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; public class EditProductActivity extends Activity { EditText txtName; EditText txtPrice; EditText txtDesc; EditText txtCreatedAt; Button btnSave; Button btnDelete; String pid; // Progress Dialog private ProgressDialog pDialog; // JSON parser class JSONParser jsonParser = new JSONParser(); // single product url private static final String url_product_detials = "http://api.androidhive.info/android_connect/get_product_details.php"; // url to update product private static final String url_update_product = "http://api.androidhive.info/android_connect/update_product.php"; // url to delete product private static final String url_delete_product = "http://api.androidhive.info/android_connect/delete_product.php"; // JSON Node names private static final String TAG_SUCCESS = "success"; private static final String TAG_PRODUCT = "product"; private static final String TAG_PID = "pid"; private static final String TAG_NAME = "name"; private static final String TAG_PRICE = "price"; private static final String TAG_DESCRIPTION = "description"; @Override public void onCreate(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 new GetProductDetails().execute(); // save button click event btnSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // starting background task to update product new SaveProductDetails().execute(); } }); // Delete button click event btnDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // deleting product in background thread new DeleteProduct().execute(); } }); } /** * Background Async Task to Get complete product details * */ class GetProductDetails extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Loading product details. Please wait..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Getting product details in background thread * */ protected String doInBackground(String... params) { // updating UI from Background Thread runOnUiThread(new Runnable() { public void run() { // Check for success tag int success; try { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("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(); } } }); return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog once got all details pDialog.dismiss(); } } /** * Background Async Task to Save product Details * */ class SaveProductDetails extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Saving product ..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Saving product * */ protected String 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 = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair(TAG_PID, pid)); params.add(new BasicNameValuePair(TAG_NAME, name)); params.add(new BasicNameValuePair(TAG_PRICE, price)); params.add(new BasicNameValuePair(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 { int success = 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(); } return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog once product uupdated pDialog.dismiss(); } } /***************************************************************** * Background Async Task to Delete Product * */ class DeleteProduct extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(EditProductActivity.this); pDialog.setMessage("Deleting Product..."); pDialog.setIndeterminate(false); pDialog.setCancelable(true); pDialog.show(); } /** * Deleting product * */ protected String doInBackground(String... args) { // Check for success tag int success; try { // Building Parameters List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("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(); } return null; } /** * After completing background task Dismiss the progress dialog * **/ protected void onPostExecute(String file_url) { // dismiss the dialog once product deleted pDialog.dismiss(); } } }
11. JSONParser类
我用一个JSONParser类从URL获得JSON格式的数据。这个类支持两种http请求,GET和POST方法从URL获取JSON数据
JSONParser.java
package com.example.androidhive; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class JSONParser { static InputStream is = null; static JSONObject jObj = null; static String json = ""; // constructor public JSONParser() { } // function get json from url // by making HTTP POST or GET mehtod public JSONObject 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 = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(params)); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); is = httpEntity.getContent(); }else if(method == "GET"){ // request method is GET DefaultHttpClient httpClient = new DefaultHttpClient(); String paramString = URLEncodedUtils.format(params, "utf-8"); url += "?" + paramString; HttpGet httpGet = new HttpGet(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 = new BufferedReader(new InputStreamReader( is, "iso-8859-1"), 8); StringBuilder sb = new StringBuilder(); 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 = new JSONObject(json); } catch (JSONException e) { Log.e("JSON Parser", "Error parsing data " + e.toString()); } // return JSON String return jObj; } }到这里,本教程就结束了。
运行你的代码,测试一下程序吧。你可能会遇到不少错误,经常使用LogCat来调试你的项目。
如果你不能解决那些错误,请在此留言。
原文链接:http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/
测试环境:WAMP: 2.4 Apache :2.4.4 PHP: 5.4.16
源码下载地址: http://download.csdn.net/detail/welovesunflower/7383361
相关文章推荐
- 如何使用JSON连接Android和PHP Mysql数据库
- 如何使用JSON连接Android和PHP Mysql数据库
- 如何使用JSON连接Android和PHP Mysql数据库
- php使用pdo连接mysql数据库如何设置发送的字符集?
- PHP当中如何使用Wampserver连接到Mysql数据库以及怎样使用!
- 如何使用R语言连接MySQL数据库,rjson,网页抓取
- Android如何连接MySQL数据库
- PHP连接MySQL数据库并以json格式输出
- PHP如何连接MySQL数据库
- Android使用json对中文进行编码 使用php接收时进行解码
- Android网络开发中如何使用JSON进行网络通信
- Android笔记——什么是json?json如何使用?
- PHP连接mysql数据库,并将取出的数据以json的格式输出
- PHP中如何使用json
- php如何连接MYSQL数据库并进行添加、修改、删除操作
- Android SDK Setup如何使用 解决连接失败
- json在php中的使用之如何转换json为数组
- PHP从零单排(十二)使用PHP连接MySQL数据库
- matlab如何使用jdbc和mysql数据库连接
- [PHP]如何在百度(BAE)和新浪(SAE)的云平台使用PHP连接MySQL并返回结果数据