Lab 6 (list all data on ListView, Add Product on DB)

 Part 1: Server-side PHP Script

We will first create the server-side PHP script to:

• Handle the Volley HTTP request to retrieve all products from the database

• Format these products information with suitable separators.

• Return the formatted products information to requesting client.

Let’s get started with creating a get_all_productsVolley.php using the Visual Studio Code and save it in C:\xampp\htdocs\products


Step1: Server Side 

get_all_productsVolley.php

<?php
/*
* Following code will retrieve all the products
*/
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$db= new DB_CONNECT();
$db->connect();
// get all products from products table
$sqlCommand="SELECT * FROM products";
$result =mysqli_query($db->myconn, "$sqlCommand");
$productresult ="";
// check for empty result
if (mysqli_num_rows($result) > 0) 
{
// looping through all results
while ($row = mysqli_fetch_array($result)) {
//each row of product is separated by ":" & each product information is separated by ";"
$productresult = $productresult.$row["pid"].";" .$row["name"].";".$row["price"].":";
}
// return all products with separators to requesting client 
echo ($productresult);
}
else {
// no products found
echo("Error");
}
?>


Step 2: Android Client Side  (Android Studio)

Gradle Scripts> build.gradle (Module:app)

Add the latest version of Volley library into this file inside the dependencies tab, as shown below:

dependencies { 

 implementation 'com.android.volley:volley:1.2.1' 
:
 } 



Step 3:
In the AndroidManifest file, set the Internet permission, by adding this line

< uses-permission android:name="android.permission.INTERNET" />

 before the <application>   tag, which you did in the previous lab on Android Networking: Also, as the network data is sent in clear text via Volley library, add this line within tag 

android:usesCleartextTraffic="true


Step 4:

For a quick start, you may copy the XML codes below and paste on the activity_main.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>

Step 5:
Modify MainActivity.java - Copy and paste the codes below. Note that the codes inside the onClick(View view) are commented out. 

public class MainActivity extends AppCompatActivity {

    //change this ip address to your machine ip address, or you can use your atspace web address.
    public static String ipBaseAddress = "http://192.168.18.17/products";
    Button btnViewProducts;
    Button btnNewProduct;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 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) {
                // Create New Product Activity
            //    Intent i = new Intent(getApplicationContext(), NewProductActivity.class);
            //    startActivity(i);

            }
        });
    }
} //end of class

 

Run it and you should see the following screenshot.  Nothing happens when your click on any of the buttons at this juncture


Step 6:

Proceed to add a new Empty Views Activity to the project app and name it “AllProductsActivity”.  We would like to display all the products retrieve from the database in a ListView in this activity.

Edit the activity_all_products.xml file with the following codes to include a ListView

<?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="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>


Step 7:

 Create a list_item.xml to list the items in the ListView.  Right click on app>new>XML>Layout XML File.  Name it as list_item.xml.  Enter the following codes to list_item.xml.  Note that the TextView for product id is set to Visibility=”gone” as we do not want to display the product id in the list item.

<?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
    Note the attribute visibility is set to gone-->
    <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" />
<!-- Price Label -->
    <TextView
        android:id="@+id/price"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17dip"
        android:textStyle="bold" />
</LinearLayout>

Add the following variable declaration codes at the correct section to AllProductsActivity.java file
//variable to store ListView
ListView lv;

//ArrayLisr to store product list from database
ArrayList<HashMap<String, String>> productsList;

// url to get all products list via the php file get_all_productsJson.php
private static String url_all_products = 
MainActivity.ipBaseAddress+"/get_all_productsVolley.php";


 Add the following codes inside the OnCreate() method of AllProductsActivity.java. Note that we will need to define a method called postData(), which we will use to execute the Volley request.

// get resource id of ListView 
lv = (ListView)findViewById(R.id.list);


// ArrayList to store product info in Hashmap for ListView
productsList = new ArrayList<HashMap<String, String>>();

// re-usable method to use Volley to retrieve products from database
postData(url_all_products, null );

   Add the following codes shown next page for the postData() method inside the AllProductsActivity.java file. This method will pass in 2 parameters. The first is the url that specifies the web resource to connect to, and the second is the Map params() parameters to send data to the webserver in the HTTP Post request.  Since we are not sending any data to the network here, we set the second parameter for Map params() to null.

public void postData(String url, Map params)
{
    //create a RequestQueue for Volley
    RequestQueue queue = Volley.newRequestQueue(this);

    //create a StringRequest for Volley for HTTP Post
    StringRequest stringRequest = new StringRequest( Request.Method.POST, url,
            //response from server
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    //check if error code received from server.
                    if (response.equals("Error"))
                    {
                        Toast.makeText(getApplicationContext(),"Error in retrieving database",Toast.LENGTH_LONG).show();
                        return;
                    }
                    //handle the response data received from server
                    //store each product from database records in String array
                    String[] products = response.split(":");

                    // for each product, retrieve the product details
                    for (int i = 0; i < products.length; i++) {
                        // Storing each product info in variable
                        String[] details = products[i].split(";");
                        String id = details[0];
                        String name = details[1];
                        String price = details[2];
                        // creating new HashMap
                        HashMap<String, String> map = new HashMap<String, String>();
                        // adding each product info to HashMap key-value pair
                        map.put("product_id", id);
                        map.put("product_name", name);
                        map.put("product_price", price);
                        // adding map HashList to ArrayList
                        productsList.add(map);
                    }

                    //populate the listview with product information from Hashmap
                    ListAdapter adapter = new SimpleAdapter(
                            AllProductsActivity.this, productsList,
                            R.layout.list_item, new String[]{"product_id",
                            "product_name","product_price"},
                            new int[]{R.id.pid, R.id.name,R.id.price});
                    // updating listview
                    lv.setAdapter(adapter);
                }
            },
            //error in Volley
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // handle error
                    Toast.makeText(getApplicationContext(),"Error in retrieving database",Toast.LENGTH_LONG).show();
                }
            }
    );
    //add StringRequest to RequestQueue in Volley 
    queue.add(stringRequest);
}

 You may proceed to run the App.  Before that, please uncomment the necessary codes in the MainActivity.java file so that when you click on the “View Products” button, it will load the AllProductsActivity and display the name of all the products retrieve from the database, as shown below. 

 

Ensure that your Apache and MySQL in XAMPP server are running, and the ip address in the MainActivity.java is updated.

Part 3:  To Add New Product to Database

1.     In Android Studio, add new Empty Views Activity to your current Android project, and named it NewProductActivity

2.    You may use the XML codes below for activity_new_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>

 In the NewProductActivity.java file, add the following declarations codes in the correct section:


EditText inputName;
EditText inputPrice;
EditText inputDesc;
Button btnCreateProduct;

String name ,price,description;
private static String url_create_product =MainActivity.ipBaseAddress+"/create_productVolley.php";


Inside the onCreate() method of NewProductActivity.java, add in the following codes shown next page.   Take note that in this case, we will need to send the new product information entered by the user to the server, so that a new product can be added to the database.  The new product information is stored as key-value pair in the Hashmap named params_create


protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_new_product);

    // retrieve the resource id for EditText
    inputName = (EditText) findViewById(R.id.inputName);
    inputPrice = (EditText) findViewById(R.id.inputPrice);
    inputDesc = (EditText) findViewById(R.id.inputDesc);

    // retrieve the resource id for button
    btnCreateProduct = (Button) findViewById(R.id.btnCreateProduct);

    // button click event
    btnCreateProduct.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            //retrieve the values in EditText entered by user
            name = inputName.getText().toString();
            price = inputPrice.getText().toString();
            description = inputDesc.getText().toString();
            //check for no empty values in EditText
            if (name.isEmpty() || price.isEmpty() || description.isEmpty())
            {
                Toast.makeText(getApplicationContext(), "No fields must be empty", Toast.LENGTH_LONG).show();
                return;
            }
            //put the product info as key-values pair in HashMap
            Map<String,String> params_create = new HashMap<String,String>();
            params_create.put("name",name);
            params_create.put("price",price);
            params_create.put("description",description);

            //postData method to use Volley to update new product details in database
            postData(url_create_product,params_create);
        }
    });
}

Add the following codes shown next page for the postData() method.  Place them after the onCreate() method.  Take note that we have added in the codes to override the getParams() method of the StringRequest class, in order for us to send the new product information to the server.


 

public void postData(String url, Map params){
    //create a RequestQueue for Volley
    RequestQueue requestQueue = Volley.newRequestQueue(this);

    //create StringRequest for http post web request to send new product info to database
    StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
            //response from server
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                        if (response.equals("Error"))
                        {
                            Toast.makeText(getApplicationContext(),"Error in updating database", Toast.LENGTH_LONG).show();
                        }
                        if(response.equals("Success"))
                        {
                            Toast.makeText(getApplicationContext(),"Success in updating database", Toast.LENGTH_LONG).show();
                            finish();
                            //load the AllProductActivity with updated ListView
                            Intent i = new Intent (getApplicationContext(), AllProductsActivity.class);
                            startActivity(i);
                        }
                    }
                },
            //error in Volley
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // handle error
                    Toast.makeText(getApplicationContext(),"Error in accessing database",Toast.LENGTH_LONG).show();
                }
            }
    ) {
        @Nullable
        @Override
        // to send product info stored in HashMap params_create to server via HTTP Post
        protected Map<String, String> getParams() {
            return params;
        }
    };
    //add StringRequest to Volley Queue
    requestQueue.add(stringRequest);
}


Proceed to write your own codes for PHP scripts (create_productVolley.php) so that the new product information sent by the Android app can be added to the product database

 

Hint:

 

·       Ensure your new PHP file, create_productVolley.php, is stored in the C:\xampp\htdocs\products folder

 

·       You may refer to the codes in get_all_productsVolley.php for reference.

 

·       To retrieve the product information in PHP, use the following lines of php scripts:

 

    $name = $_POST['name'];  //to retrieve product name

    $price = $_POST['price'];    // to retrieve product price

$description = $_POST['description'];  //to retrieve product description

 

·       Uncomment the codes in MainActivity.java to activate the “Add New Product” Button

https://mappd23.blogspot.com/2024/05/lab-6-codes-part-2-addproduct.html

Comments

Popular posts from this blog

Simple Login Example (PHP Server + Android Client)

Lab 6: Using split