Lab9 Demo & Explanation of Codes

 





Lab9 Part 4 Login (Volley)

To Create a Login Activity



Suppose you were asked to add a login activity to the Application.
How do you make Login as the First Activity instead of Main Activity as the First Activity(Page)?

Let's get started.




PHP Server Side
Step 1: Create a table name as users3

CREATE TABLE `users3` (
 
  `username` varchar(23) NOT NULL,
  `password` varchar(80) NOT NULL,
   PRIMARY KEY (`username`)
 )


INSERT INTO `users3` (`username`, `password`) VALUES ('user1', 'u1234');


Step 2: Create a php page name as LoginJ.php


<?php
 
//php
// Get raw data from request
$json = file_get_contents('php://input');

// Convert json to php object
$json_object = json_decode($json, true);

// Get pid value from json object

$username = $json_object['username']; //htmlspecialchars to be added
$password = $json_object['password']; //htmlspecialchars to be added
 
// array for JSON response
$response = array();
  
 
  // include db connect class
    require_once __DIR__ . '/db_connect.php';
 // connecting to db
    $myConnection= new DB_CONNECT();
    $myConnection->connect();
 
 // mysql inserting a new row
    $sqlCommand="select password from users3 where username= '$username'"; 
    
   // echo $sqlCommand;
    $result =mysqli_query($myConnection->myconn, "$sqlCommand");
    
    
       // check for empty result
        if (mysqli_num_rows($result) > 0) {
 
            $result = mysqli_fetch_array($result);
 
            if($password ==$result["password"]  )
            
            { $response["success"] = 1;
 
            $response["message"] = "Login Successful";
            }
            else {
      
            $response["success"] = 0;
            $response["message"] = "Login Failed";       
            }
            
        
            
            
        } else {
            // no product found
            $response["success"] = 0;
            $response["message"] = "Login Failed";
 
            // echo no users JSON
           
        }
        
        
            echo json_encode($response);
        
        
    
 
?>


Android Client Side
Step 1: Create a new Empty Activity name as Login

activity_login.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"

 
    tools:context=".LoginActivity">


           <EditText

                    android:id="@+id/username"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/prompt_username"
                    android:inputType="text"
                    android:maxLines="1"
                    android:singleLine="true" />

             



                <EditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/prompt_password"
                    android:imeActionId="6"
                    android:imeActionLabel="@string/action_sign_in_short"
                    android:imeOptions="actionUnspecified"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:singleLine="true" />


            <Button
                android:id="@+id/btnSignIn"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:text="@string/action_sign_in"
                android:textStyle="bold" />


</LinearLayout>

Step 2:  Modify  strings.xml as shown below:




 <!-- Strings related to login -->
    <string name="prompt_username">Username</string>
    <string name="prompt_password">Password</string>
    <string name="action_sign_in">Sign in</string>
    <string name="action_sign_in_short">Sign in</string>
    <string name="error_invalid_email">This email address is invalid</string>
    <string name="error_invalid_password">This password is too short</string>
    <string name="error_incorrect_password">This password is incorrect</string>
    <string name="error_field_required">This field is required</string>
    <string name="permission_rationale">"Contacts permissions are needed for providing email
        completions."
    </string>



Step 3: Modify LoginActivity.java. Copy and Paste the code below:


package networkclient.mdad.sql_databaseexample;


import android.content.Intent;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;


/**
 * A login screen that offers login via email/password.
 */
public class LoginActivity extends AppCompatActivity  {


    private EditText mPassword,mUserName;
    private Button btnSignIn;
    // url to update product
    private static final String url_login = MainActivity.ipBaseAddress+"/loginJ.php";
    // JSON Node names
    private static final String TAG_SUCCESS = "success";

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

        mPassword = (EditText) findViewById(R.id.password);
        mUserName = (EditText) findViewById(R.id.username);
        btnSignIn = (Button) findViewById(R.id.btnSignIn);


        // view products click event
        btnSignIn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                String pw= mPassword.getText().toString();
                String uName= mUserName.getText().toString();

                if(pw.isEmpty())
                {
                    mPassword.setError(getString(R.string.error_field_required));

                }else

                if(uName.isEmpty())
                {
                    mUserName.setError(getString(R.string.error_field_required));

                }else
                {
                    JSONObject dataJson = new JSONObject();
                    try{
                        dataJson.put("username", uName);
                            dataJson.put("password", pw);


                    }catch(JSONException e){

                    }

                    postData(url_login,dataJson,1 );

                }

            }
        });



    }

    public void postData(String url, final JSONObject json, final int option){
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        JsonObjectRequest json_obj_req = new JsonObjectRequest(
                Request.Method.POST, url, json, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {


                switch (option){
                     case 1:checkResponseLogin(response); break;

                }

            }

        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
//                String alert_message;
//                alert_message = error.toString();
//                showAlertDialogue("Error", alert_message);
            }

        });
        requestQueue.add(json_obj_req);
    }


    public void checkResponseLogin(JSONObject response)
    {
        Log.i("----Response", response+" "+url_login);
        try {
            if(response.getInt(TAG_SUCCESS)==1){

                finish();
                Intent i = new Intent(this, MainActivity.class);
                startActivity(i);



            }else{
                Toast.makeText(this, "Wrong Password", Toast.LENGTH_SHORT).show();
            }

        } catch (JSONException e) {
            e.printStackTrace();

        }

    }





}


Step 4: Try running your App now. You will find that Login is NOT the First acitivity(Page).


Step 5: How to set Login Activity as the First Activity (Page) to Launch?

Modify AndroidManifest.xml as shown below



We make LoginActivity as the MAIN , LAUNCHER

 <activity android:name=".LoginActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Lab9 Part3 Android Update/Delete Product at Mysql DB (Volley)



Update/Delete data from MySql database from Wamp server and display in Android Client








PHP Server Side at WampServer
Create 3 php files named update_productJson.php ,
 delete_productJson.php and get_product_detailsJson.php





<?php

//php
// Get raw data from request
$json = file_get_contents('php://input');

// Convert json to php object
$json_object = json_decode($json, true);

// Get pid value from json object
$pid = $json_object['pid']; //htmlspecialchars to be added
$name = $json_object['name']; //htmlspecialchars to be added
$price = $json_object['price']; //htmlspecialchars to be added
$description = $json_object['description']; //htmlspecialchars to be added

 
// array for JSON response
$response = array();
 

// include db connect class
    require_once __DIR__ . '/db_connect.php';
 // connecting to db
    $db= new DB_CONNECT();
    $db->connect();

    // mysql update row with matched pid
    $sqlCommand="UPDATE products SET name = '$name', price = '$price', description = '$description' WHERE pid = $pid";
    $result =mysqli_query($db->myconn, "$sqlCommand");


    // 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 {
 
              // Wrong data types e.g. user enter 2d for price
              $response["success"] = 0;
              $response["message"] = "Error in updating. Data mismatched";
 
              // echoing JSON response
                echo json_encode($response);
             }
   

 
?>


delete_productJson.php

<?php
 
//php
// Get raw data from request
$json = file_get_contents('php://input');

// Convert json to php object
$json_object = json_decode($json, true);

// Get pid value from json object
$pid = $json_object['pid']; //htmlspecialchars to be added

 
// array for JSON response
$response = array();
 
 
  // include db connect class
    require_once __DIR__ . '/db_connect.php';
 // connecting to db
    $db= new DB_CONNECT();
    $db->connect();

    // mysql delete row with matched pid
    $sqlCommand="DELETE FROM products WHERE pid = $pid";
    $result =mysqli_query($db->myconn, "$sqlCommand");
 
//echo "$sqlCommand";
 
 
    // check if row deleted 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);
    }
 
?>


get_product_detailsJson.php

<?php
  
/*/*
  * Following code will get single product details* Following code will g
 * A product is identified by product id (pid)
 */
 
  

// Get raw data from request
$json = file_get_contents('php://input');

// Convert json to php object
$json_object = json_decode($json, true);

// Get pid value from json object
$pid = $json_object['pid']; //htmlspecialchars to be added

 
// array for JSON response
$response = array();
 
 

// include db connect class
    require_once __DIR__ . '/db_connect.php';
 // connecting to db
    $db= new DB_CONNECT();
    $db->connect();


    // get a product from products table
    $sqlCommand="SELECT *FROM products WHERE pid = $pid";
    $result =mysqli_query($db->myconn, "$sqlCommand");

 
    if (!empty($result)) {
        // check for empty result
        if (mysqli_num_rows($result) > 0) {
 
            $result = mysqli_fetch_array($result);
 
            $product = array();
            $product["pid"] = $result["pid"];
            $product["name"] = $result["name"];
            $product["price"] = $result["price"];
            $product["description"] = $result["description"];
 
            // 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 product found 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); } ?>



Android Client Side
Step 1: Create another activity called EditProductActivity
Right clicked on app>new>Activity>Empty Activity. Name it as EditProductActivity
Copy and paste the codes below for activity_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>



Step 2: Modify EditProductActivity.java. 
Codes shall be explained in class. Whenever in doubt please ask your tutor.

 Copy and paste the codes below:


package networkclient.mdad.sql_databaseexample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import android.view.View;
import java.io.InputStream;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.Intent;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

public class EditProductActivity extends AppCompatActivity {

    EditText txtName;
    EditText txtPrice;
    EditText txtDesc;
    EditText txtCreatedAt;
    Button btnSave;
    Button btnDelete;
    // Response
    String responseServer;

    JSONObject json=null;

    String pid;
    static InputStream is = null;
    // Progress Dialog
    private ProgressDialog pDialog;



    // single product url
    private static final String url_product_details = MainActivity.ipBaseAddress+"/get_product_detailsJson.php";

    // url to update product
    private static final String url_update_product = MainActivity.ipBaseAddress+"/update_productJson.php";

    // url to delete product
    private static final String url_delete_product = MainActivity.ipBaseAddress+"/delete_productJson.php";
    // 152.226.144.250
    // 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";

    private static String prodName="";
    private static String prodPrice="";
    private static String prodDesc="";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_product);

        pDialog = new ProgressDialog(EditProductActivity.this);
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
                
Log
.i("url_product_detials", url_product_details); // 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); // Log.i("----------Extra:::",pid); // Getting complete product details in background thread JSONObject dataJson = new JSONObject(); try{ dataJson.put("pid", pid); // dataJson.put("password", "def"); }catch(JSONException e){ } postData(url_product_details,dataJson,1 ); // save button click event btnSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { // getting updated data from EditTexts String name = txtName.getText().toString(); String price = txtPrice.getText().toString(); String description = txtDesc.getText().toString(); pDialog.setMessage("Saving product ..."); pDialog.show(); // starting background task to update product JSONObject dataJson = new JSONObject(); try{ dataJson.put("pid", pid); dataJson.put(TAG_NAME, name); dataJson.put(TAG_PRICE, price); dataJson.put(TAG_DESCRIPTION, description); }catch(JSONException e){ } postData(url_update_product,dataJson,1 ); } }); // Delete button click event btnDelete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { pDialog.setMessage("Deleting product ..."); pDialog.show(); // deleting product in background thread JSONObject dataJson = new JSONObject(); try{ dataJson.put("pid", pid); }catch(JSONException e){ } postData(url_delete_product,dataJson,2); } }); } public void postData(String url, final JSONObject json, final int option){ RequestQueue requestQueue = Volley.newRequestQueue(this); JsonObjectRequest json_obj_req = new JsonObjectRequest( Request.Method.POST, url, json, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { switch (option){ case 1:checkResponseEditProduct(response); break; case 2:checkResponseSave_delete_Product(response); break; } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); // String alert_message; // alert_message = error.toString(); // showAlertDialogue("Error", alert_message); } }); requestQueue.add(json_obj_req); } public void checkResponseSave_delete_Product(JSONObject response) { try { // dismiss the dialog once product updated pDialog.dismiss(); if(response.getInt("success")==1){ // successfully updated Intent i = getIntent(); // send result code 100 to notify about product update setResult(100, i); finish(); }else{ //Error Response from server
            Toast.makeText(getApplicationContext(),"Error in deleting...", Toast.LENGTH_LONG).show();

            }

        } catch (JSONException e) {

            e.printStackTrace();

        }


    }


    public void checkResponseEditProduct(JSONObject response)
    {
        try {
            pDialog.dismiss();

            if(response.getInt("success")==1){
                // successfully received product details
                JSONArray productObj = response.getJSONArray(TAG_PRODUCT); // JSON Array
                // get first product object from JSON Array
                JSONObject product = productObj.getJSONObject(0);
                prodName=product.getString(TAG_NAME);
                prodPrice=product.getString(TAG_PRICE);
                prodDesc=product.getString(TAG_DESCRIPTION);

//                Log.i("---Prod details",prodName+"  "+prodPrice+"  "+prodDesc);
                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(prodName);
                txtPrice.setText(prodPrice);
                txtDesc.setText(prodDesc);



            }else{
                //Error Response from server 
               Toast.makeText(getApplicationContext(),"Error in Editing...", Toast.LENGTH_LONG).show();
} } catch (JSONException e) { e.printStackTrace(); } } }//end class


Step 2: Modify AllProductsActivity.java. Look for lv.setOnItemClickListener
Add in 3 lines shown below.  When user click on any of the list item, pid value will be captured and stored in String pid.
And It will move the activity from current activity (in this case is AllProductsActivity) to  EditProductActivity.class and Passed the valueof pid to EditProductActivity
using the lines highlighted in yellow.

 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);
            }
        });


Discussion.....

Take  a look at the partial codes of EditProductActivity.java 

It takes the PID value from AllProductsActivity using the lines highlighted in yellow

public class EditProductActivity extends AppCompatActivity {

    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_product);


        Log.i("url_product_detials", url_product_detials);
        // 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);

        Log.i("----------Extra:::",pid); //print to logcat 

        // Getting complete product details in background thread