Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Android (http://www.go4expert.com/articles/android/)
-   -   Step by Step Guide to Sending Data from Android Application to Server (http://www.go4expert.com/articles/step-step-guide-sending-data-android-t30182/)

faribasiddiq 17Jul2014 11:08

Step by Step Guide to Sending Data from Android Application to Server
 
Communication between android application and server is one of the most common requirements. In frequent cases, you need to collect information from user in your android application and store it in the database for future use.

In this tutorial, we will make a user interface where user will select some choices and submit the information. The data will then be processed by a script on the server. Next, these data will be stored in a table of a database. More concisely, we are going to make a prediction application, where user predicts about a football match and these predictions are stored in server.

User input in android application:

Now, we will create our android application and take user input.
  • Open eclipse and start a new android application.
  • Change the launcher activity name to PredictionActivity.java from default activity name MainActivity.java. The layout file name will be activity_prediction.xml.
  • Create a new class named Servicehandler.java and save it in src folder.
activity_prediction.xml:

It is the main layout file of your application. We have used a table layout to display the information in tabular format. There are three (3) questions and three (3) options to choose for every question. The options are in radio button. The format will be like this:
  1. How many goals will be scored in the match?
    • 0-2
    • 3-4
    • More than 4
  2. How many yellow cards will be shown?
    • 0-3
    • 4-5
    • More than 5
  3. What will be the difference of ball possession percentage between two teams?
    • 0-5%
    • 6-10%
    • More than 10%
We will make 6 table rows: Three (3) rows for three questions and three rows for the options of the three questions. The first option of every question is selected by default while application launches. User can change the selection and submit their answer.

Here is the source code of activity_prediction.xml
Code:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical" >

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#000000"
        android:shrinkColumns="*"
        android:stretchColumns="*" >

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_span="4"
                android:padding="18dip"
                android:text="1.How many goals will be scored in the match?"
                android:textColor="#ffffff"
                android:textSize="18dp" />
        </TableRow>

        <TableRow
            android:id="@+id/tableRow1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <RadioGroup
                android:id="@+id/answer1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.4" >

                <RadioButton
                    android:id="@+id/answer1A"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:text="0-2"
                    android:textColor="#ffffff" />

                <RadioButton
                    android:id="@+id/answer1B"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="3-4"
                    android:textColor="#ffffff" />

                <RadioButton
                    android:id="@+id/answer1C"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="More than 4"
                    android:textColor="#ffffff" />
            </RadioGroup>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_span="4"
                android:padding="18dip"
                android:text="2. How many yellow card will be shown?"
                android:textColor="#ffffff"
                android:textSize="18dp" />
        </TableRow>

        <TableRow
            android:id="@+id/tableRow1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <RadioGroup
                android:id="@+id/answer2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.4" >

                <RadioButton
                    android:id="@+id/answer2A"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:text="0-3"
                    android:textColor="#ffffff" />

                <RadioButton
                    android:id="@+id/answer2B"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="4-5"
                    android:textColor="#ffffff" />

                <RadioButton
                    android:id="@+id/answer2C"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="More than 5"
                    android:textColor="#ffffff" />
            </RadioGroup>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal" >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_span="4"
                android:padding="18dip"
                android:text="3. What will be the difference of ball possession percentage between two teams?"
                android:textColor="#ffffff"
                android:textSize="18dp" />
        </TableRow>

        <TableRow
            android:id="@+id/tableRow1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <RadioGroup
                android:id="@+id/answer3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.4" >

                <RadioButton
                    android:id="@+id/answer3A"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:checked="true"
                    android:text="0-5%"
                    android:textColor="#ffffff" />

                <RadioButton
                    android:id="@+id/answer3B"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="6-10%"
                    android:textColor="#ffffff" />

                <RadioButton
                    android:id="@+id/answer3C"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="More than 10%"
                    android:textColor="#ffffff" />
            </RadioGroup>
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal" >

            <Button
                android:id="@+id/submit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true"
                android:gravity="center"
                android:text="Submit" />
        </TableRow>
    </TableLayout>

</ScrollView>

AndroidManifest.xml:

It is the configuration file of your application. Here is one important change you need to make: Add the following line:
Code:

<uses-permission android:name="android.permission.INTERNET"/>
As we need to access the internet in this application to send data in the server, we need to mention it in the manifest file. So our manifest file will be something like this:
Code:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.predictiontest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET"/>
   
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".PredictionActivity"
            android:label="@string/title_activity_prediction" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

ServiceHandler.java:

This file is used for http request and response handling. There is a function makeServiceCall with two different signatures (function overloading). You can use any of them according to your requirement.
  • String makeServiceCall(String url, int method)
  • String makeServiceCall(String url, int method,List<NameValuePair> params)
Let’s look at the parameters:
  • String url: Provide the url you want to hit in the server.
  • int method: provide the method you want to use, either GET or POST.
  • List<NameValuePair> params: Provide list of parameters you want to send to get your filtered response or to store new data information.
Here is the full code of ServiceHandler.java file.
Code:

package com.example.testjsonparsing;

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 android.util.Log;
public class ServiceHandler {
   
    static InputStream is = null;
    static String response = null;
    public final static int GET = 1;
    public final static int POST = 2;

    public ServiceHandler() {

    }
   
    public String makeServiceCall(String url, int method) {
        return this.makeServiceCall(url, method, null);
    }
   
   
    public String makeServiceCall(String url, int method,
            List<NameValuePair> params) {
        try {
           
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;
           
           
            if (method == POST) {
                HttpPost httpPost = new HttpPost(url);
               
                if (params != null) {
                    httpPost.setEntity(new UrlEncodedFormEntity(params));
                }

                httpResponse = httpClient.execute(httpPost);

            } else if (method == GET) {
               
                if (params != null) {
                    String paramString = URLEncodedUtils
                            .format(params, "utf-8");
                    url += "?" + paramString;
                }
                HttpGet httpGet = new HttpGet(url);

                httpResponse = httpClient.execute(httpGet);

            }
            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, "UTF-8"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            response = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error: " + e.toString());
        }

        return response;
    }
}

PredictionActivity.java:

This file is used to send information to server through service handler class using HTTP POST method. To perform this, we have to consider the following things:

Don’t implement http communication in the main thread. It will block your main thread, so UI will be blocked and unwanted situation may occur. We will use Asynctask method to perform communication with server.

Let’s look at the steps we need to follow:

1. Our PredictionAcitivity class will extend Activity class.
Code:

public class PredictionActivity extends Activity {
}

2. Provide the url of the script which will receive data from your application. As we are using localhost, we are using the localhost server ip http://10.0.2.2
Code:

private String URL_ITEMS = "http://10.0.2.2/tech/new_predict.php";
3. Declare three string variables which will be used to store the user selection. Initialize these variables to a default value.
Code:

    String numOfGoal = "1";
    String numOfCard = "1";
    String diffOfPos = "1";

4. Create one button and three radio group objects and bind these objects with the resources of the layout file.
Code:

    private Button btnAddPrediction;
    btnAddPrediction = (Button) findViewById(R.id.submit);
    RadioGroup goal=(RadioGroup)findViewById(R.id.answer1);
    RadioGroup card=(RadioGroup)findViewById(R.id.answer2);
    RadioGroup pos=(RadioGroup)findViewById(R.id.answer3);

5. Add check change listener event to the radio group. When any radio button is selected, the event is handled by this listener. Here, we have set the selected option to the string variable.
Code:

        RadioGroup goal = (RadioGroup) findViewById(R.id.answer1);

        goal.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub

                switch (checkedId) {
                case R.id.answer1A:
                    numOfGoal = "1";
                    break;
                case R.id.answer1B:
                    numOfGoal = "2";
                    break;
                case R.id.answer1C:
                    numOfGoal = "3";
                    break;
                }
            }
        });

6. Implement the same method for the two rest radiogroup card and pos.
7. Add click listener event for the button object. When submit button is clicked, the listener event will be executed and operation is performed according to our requirement. In this tutorial, we will send the selected options to a server. For this task, we will execute a method named AddNewPrediction with three parameters numOfGoal, numOfCard and diffOfPos.
Code:

btnAddPrediction = (Button) findViewById(R.id.submit);

btnAddPrediction.setOnClickListener(new View.OnClickListener() {

    public void onClick(View v) {
        // TODO Auto-generated method stub

        new AddNewPrediction().execute(numOfGoal, numOfCard, diffOfPos);
    }
});

8. Create a class which will extend asynctask. We will perform communication with server and send the user data from application to server.

Code:

private class GetFixture extends AsyncTask< String, Void, Void> {
}

9. Look at the parameters of this class. The three types used by an asynchronous task are the following:
  • Params, the type of the parameters sent to the task upon execution. Here, three string variables are sent to the background task, so type is String.
  • Progress, the type of the progress units published during the background computation. We are not using any progress units here, so type is Void.
  • Result, the type of the result of the background computation. As we are not using the result, the type is Void.
10. Override 3 methods in this class:
  • protected void onPreExecute() : This function performs any required task before data fetch for data send. We are doing nothing in this function. You can show any progress bar, loading messages or other things here.
  • protected Void doInBackground(String... arg) : The main background works are performed here. Let’s look at the steps we need to follow here:
    • Extract the received String parameters.
      Code:

          String goalNo = arg[0];
          String cardNo = arg[1];
          String posDiff = arg[2];

    • Prepare the parameter to post using namevalue pair.
      Code:

          List<NameValuePair> params = new ArrayList<NameValuePair>();
          params.add(new BasicNameValuePair("goalNo", goalNo));
          params.add(new BasicNameValuePair("cardNo", cardNo));
          params.add(new BasicNameValuePair("posDiff", posDiff));

    • Using ServiceHandler class, call the makeServicecall function with url, method and parameters.
      Code:

          ServiceHandler serviceClient = new ServiceHandler();
          String json = serviceClient.makeServiceCall(URL_NEW_PREDICTION,
          ServiceHandler.POST, params);

  • protected void onPostExecute(Void result):
    This function performs any required action after background communication. In this application, we will do nothing in post execution.
Here is the source code of PredictionActivity.java file.
Code:

package com.example.predictiontest;

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.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;

public class PredictionActivity extends Activity {

    private String URL_NEW_PREDICTION = "http://10.0.2.2/tech/new_predict.php";
    private Button btnAddPrediction;

    String numOfGoal = "1";
    String numOfCard = "1";
    String diffOfPos = "1";

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

        RadioGroup goal = (RadioGroup) findViewById(R.id.answer1);

        goal.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub

                switch (checkedId) {
                case R.id.answer1A:
                    numOfGoal = "1";
                    break;
                case R.id.answer1B:
                    numOfGoal = "2";
                    break;
                case R.id.answer1C:
                    numOfGoal = "3";
                    break;

                }

            }
        });

        RadioGroup card = (RadioGroup) findViewById(R.id.answer2);

        card.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub

                switch (checkedId) {
                case R.id.answer2A:
                    numOfCard = "1";
                    break;
                case R.id.answer2B:
                    numOfCard = "2";
                    break;
                case R.id.answer2C:
                    numOfCard = "3";
                    break;

                }
            }
        });

        RadioGroup pos = (RadioGroup) findViewById(R.id.answer3);

        pos.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            public void onCheckedChanged(RadioGroup group, int checkedId) {
                // TODO Auto-generated method stub
                switch (checkedId) {
                case R.id.answer3A:
                    diffOfPos = "1";
                    break;
                case R.id.answer3B:
                    diffOfPos = "2";
                    break;
                case R.id.answer3C:
                    diffOfPos = "3";
                    break;

                }

            }
        });

        btnAddPrediction = (Button) findViewById(R.id.submit);

        btnAddPrediction.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub

                new AddNewPrediction().execute(numOfGoal, numOfCard, diffOfPos);
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_prediction, menu);
        return true;
    }

    private class AddNewPrediction extends AsyncTask<String, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected Void doInBackground(String... arg) {
            // TODO Auto-generated method stub
            String goalNo = arg[0];
            String cardNo = arg[1];
            String posDiff = arg[2];

            // Preparing post params
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("goalNo", goalNo));
            params.add(new BasicNameValuePair("cardNo", cardNo));
            params.add(new BasicNameValuePair("posDiff", posDiff));

            ServiceHandler serviceClient = new ServiceHandler();

            String json = serviceClient.makeServiceCall(URL_NEW_PREDICTION,
                    ServiceHandler.POST, params);

            Log.d("Create Prediction Request: ", "> " + json);

            if (json != null) {
                try {
                    JSONObject jsonObj = new JSONObject(json);
                    boolean error = jsonObj.getBoolean("error");
                    // checking for error node in json
                    if (!error) {
                        // new category created successfully
                        Log.e("Prediction added successfully ",
                                "> " + jsonObj.getString("message"));
                    } else {
                        Log.e("Add Prediction Error: ",
                                "> " + jsonObj.getString("message"));
                    }

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

            } else {
                Log.e("JSON Data", "JSON data error!");
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
        }
    }
}

Receive the client data using server script:

I guess that you know well about wamp or xamp server and have the knowledge how to use PHPMyadmin to create database.
  • Create a database named wcdb using PHPMyadmin.
  • Create a table named prediction with 3 columns :
  • goalNum: Type varchar.
  • cardNum: Type varchar
  • posDiff: Type varchar.

The table will look like this:

http://imgs.g4estatic.com/android/cl...bstructure.png

When user selects the options and submit; the data will be stored in this table. The stored data will be option number, rather than the option value. For example, if the user selects first option for all questions, the stored data will be 1,1,1 for the three column, rather than value of the selected options.

http://imgs.g4estatic.com/android/cl...ion/dbdata.png

Now we will write 3 php files to create json formatted data from the table. Create a folder named tech in your wamp or xamp root script folder (for me, the directory is : C:\wamp\www) and create 3 files here:
  • Config.php
  • DbConnect.php
  • getFixture.php

Config.php:

In this file, we will set the database username, password, host name and database name. As you are using localhost for now, set the default value username, password and host name. Then set the database name which you have created.
Code:

<?php
 // Database configuration
    define('DB_USERNAME', 'root');
    define('DB_PASSWORD', '');
    define('DB_HOST', 'localhost');
    define('DB_NAME', 'wcdb');
?>

DbConnect.php :
This file is required for establishing and closing connection with your database.
Code:

<?php
class DbConnect { 
        private $conn;       
        function __construct() {       
        // connecting to database
        $this->connect();
        }       
        function __destruct() {       
        $this->close();
        }       
        function connect() {       
        include_once dirname(__FILE__) . './Config.php';                 
        $this->conn = mysql_connect(DB_HOST, DB_USERNAME, DB_PASSWORD) or die(mysql_error());       
        mysql_select_db(DB_NAME) or die(mysql_error());       
        // returing connection resource
        return $this->conn;
        }       
        // Close function         
        function close() {
        // close db connection
        mysql_close($this->conn);
        }
}
?>

new_predict.php:

This file communicates between our application and database. First, it creates connection with database. Then it receives data from our application. Next, it stores the data into appropriate fields of the table (here, the table name is prediction) of database (wcdb).

Code:

<?php
include_once './DbConnect.php';
function createNewPrediction() {
        $response = array();
        $goalNum = $_POST["goalNo"];
        $cardNum = $_POST["cardNo"];
        $posDiff = $_POST["posDiff"];
                $db = new DbConnect();
      // mysql query
        $query = "INSERT INTO prediction(goalNum,cardNum,posDiff) VALUES('$goalNum','$cardNum','$posDiff')";
        $result = mysql_query($query) or die(mysql_error());
        if ($result) {
            $response["error"] = false;
            $response["message"] = "Prediction added successfully!";
        } else {
            $response["error"] = true;
            $response["message"] = "Failed to add prediction!";
        }
      // echo json response
    echo json_encode($response);
}
createNewPrediction();
?>

Screenshot of the output:

Here are sample screenshot's of the output from the application.

http://imgs.g4estatic.com/android/cl...on/output1.png

http://imgs.g4estatic.com/android/cl...on/output2.png


All times are GMT +5.5. The time now is 01:58.