Thursday, January 26, 2017

Retrofit Android Insert Data To Database (Server Using : PHP + MySQL)

In previous posts, I have created a tutorial that show process input data to server using dummy server (apiary), means there is no data that inserted do server. Apiary was used just for testing the process of the application.



I my previous tutorial that I created using apiary as server just focused to explain about method GET and POST on Retrofit, how to send data using method GET or POST. There is no PHP file.

But, today I going to write article about how to input data to database from android application. The database using MySQL (Localhost/phpMyAdmin) and the server made from PHP.

To transfer data to server, on Android I using external library call retrofit 2.0. Retrofit will helps us to send data to database.

In PHP file, I uses PDO as the way to connecting between PHP and database (MySQL)

Creating Database MySQL


The first thing that we have to do is creating database. You can create the database MySQL from anywhere, from example from HeidiSQL, MySQL Server or PhphMyAdmin. In this case I uses PhpMyAdmin to creating database.

Recommeded : Android Create, Read, Update, Delete data in Firebase Firestore

1. Open localhost/phpmyadmin (make sure your xampp has been on)

2. Then you will redirected to the page that looks like the following Figure 1. To create database, choose New (menu in Yellow)

Figure 1

3. After that, write your database name and choose the type of the database. Take a look at the following Figure 2

Figure 2

Create database name as : loginphpandroid
Choose the type : utf8_general_ci

4. After your database done, now create the Table. To create the Table click menu new below your database name. Take a look at Figure 3 below

Figure 3
After you click the menu new (menu in yellow), the you will redirecting to the page where you can write your Table's name.

5. To create name of your Table, please take a look at the Figure 4

Figure 4
Guidelines of  Figure 4 :
  • Give the name of the Table as : Food
  • Choose number of row in table Food
  • Then choose Go

6.  After the table has done, now create the attributes/row in Table Food. Take a look at the following Figure 4.

Figure 5

Guideline of Figure 5 :
  • Give name for the first attribute as idfood, its type :  INT
  • Set idfood as Primary Key
  • Because the attribute idfood is primary key, then checklist A_I (Auto Increment).
  • Give name for the second attribute as foodname, its type VARCHAR
  • Give name for the third attribute as foodqty, its type INT
  • If done, then choose Save

Oke the database is ready to use. Now time to configure code of the PHP and Android project.

PHP Code


Recommended : Create rating and review look like Google Play Store Android

On PHP project that I created contains several PHP classes. Among that PHP files, I placed on different package. For clearly about the folder structure of the project, just take a look at the following figure 6

Figure 6


1. Connection.php

This file used to connecting php project that created to the database. If connected, then we allowed to input data either from Mobile or Form HTML. Below is the full code of Connection.php  :

<?php
/**
* Created by PhpStorm.
* User: putuguna
* Date: 1/24/2017
* Time: 10:13 AM
*/
class Connection{
function getConnection(){
$host = "localhost";
$username = "root";
$password = "";
$dbname = "loginphpandroid";
try{
$conn = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}catch (PDOException $e){
echo "ERROR CONNECTIONF : " . $e->getMessage();
}
}
}
view raw Connection.php hosted with ❤ by GitHub
2. InsertFood.php

This file used to insert data that get from users to the database. In this data gotten from Mobile Android. Below is the full code of InsertFood.php :

<?php
/**
* Created by PhpStorm.
* User: putuguna
* Date: 1/24/2017
* Time: 10:54 AM
*/
require_once("../db/Connection.php");
class InsertFood{
function startInsertFood(){
$connection = new Connection();
$conn = $connection->getConnection();
//array for json response
$response = array();
$foodName = $_POST['foodname'];
$foodQty = $_POST['foodqty'];
try{
if(isset($foodName) && isset($foodQty)){
$sqlInsert = "INSERT INTO food (foodname, foodqty) VALUES ('$foodName', '$foodQty')";
$conn->exec($sqlInsert);
}
}catch (PDOException $e){
echo "Error while inserting ".$e->getMessage();
}
//cek is the row was inserted or not
if($sqlInsert){
//success inserted
$response["success"] = 1;
$response["message"] = "Food successful inserted!";
echo json_encode($response);
}else{
//failed inserted
$response["success"] = 0;
$response["message"] = "Failed while insert data";
echo json_encode($response);
}
}
}
$insert = new InsertFood();
$insert->startInsertFood();;
view raw InsertFood.php hosted with ❤ by GitHub
Attention! There are several codes that I have to explain:

$response = array()

The code above created for save the response in json form.

//cek is the row was inserted or not 
if($sqlInsert){     
    //success inserted     
    $response["success"] = 1;     
    $response["message"] = "Food successful inserted!";
    echo json_encode($response);
}else{     
    //failed inserted     
    $response["success"] = 0;     
    $response["message"] = "Failed while insert data";
    echo json_encode($response);}

The code above will do checking. Is the input process has success or not. If success the response will like the follows :
  • success = 1
  • message = Food successful inserted!
When program do echo json_encode($rensponse), then it will displaying output json like the follows :

{"success":1,"message":"Food successful inserted!"}

If the process if falied, the the response that will like the follows :
  • success = 0
  • message = "Failed while insert data"
So when program do echo json_encode($response), the output json will display like the follows :

{"success":0,"message":"Failed while insert data"}

That json response will used in mobile, and will displaying on the Toast message.

Android Code


Recommended : Simply Login Using Firebase UI (No need API anymore)

In this project I using Retrofit 2.0 to help this project send or receive data from android to server.

1. Library

As always the first thing you do before continue project is compile the libraries that needed in the project. In this project compile the following libraries :

//add the following libraries 
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.0.2' 
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

2. Android Manifest

On AndroidManifest add user permission for internet, look like the follows :

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

3. Layout

There are several layout that used in this project :
  • activity_main.xml
  • popup_insert_food.xml
Create layout activity_main.xml, then paste the following code :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.putuguna.androidphplogin.MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_blue_bright">
<Button
android:id="@+id/button_insert_food"
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:text="Insert Food"
android:textColor="@android:color/white"/>
</FrameLayout>
</LinearLayout>
Next create layout popup_insert_food.xml. This layout contains two Edit Text for foodName dan foodQty. In its process this layout will appears on the popup. Paste the following code :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:padding="@dimen/activity_horizontal_margin"
android:layout_height="match_parent">
<EditText
android:id="@+id/edit_text_food_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Food name"/>
<EditText
android:id="@+id/edit_text_food_quantity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Food quantity"/>
</LinearLayout>

4. Java classes

There are several java classes that need in order to do insert data to the database, there are :
  • ApiService.java
  • ApiClient.java
  • LoggingInterceptors.java
  • InsertFoodResponseModel.java
  • MainActivity.java
This interface contains method that used to send data to server. Paste the following code :

package com.putuguna.androidphplogin.apiservices;
import com.putuguna.androidphplogin.models.InsertFoodResponseModel;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* Created by putuguna on 1/24/2017.
*/
public interface ApiService {
@FormUrlEncoded
@POST("food/InsertFood.php")
Call<InsertFoodResponseModel> insertFood(@Field("foodname") String foodName, @Field("foodqty") String foodQty);
}
view raw ApiService.java hosted with ❤ by GitHub
This class contains the URL that used in this project. And also in this class contains initialized of the retrofit. Paste the following code :


package com.putuguna.androidphplogin.clients;
import com.putuguna.androidphplogin.utils.LoggingInterceptor;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by putuguna on 1/24/2017.
*/
public class ApiClient {
public static final String URL = "http://192.168.43.147/AndroidPhpLogin/";
public static Retrofit RETROFIT = null;
public static Retrofit getClient(){
if(RETROFIT==null){
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.build();
RETROFIT = new Retrofit.Builder()
.baseUrl(URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return RETROFIT;
}
}
view raw ApiClient.java hosted with ❤ by GitHub
Take a look at the URL. 192.168.43.147 is IP from my computer. And AndroidPhpLogin my project folder that located in localhost (htdocs). Change the IP/URL and the project folder name with your own.

This class used to save the response of the json from server (Take a look that the json that i have explained above in php code). Paste the following code :

package com.putuguna.androidphplogin.models;
import com.google.gson.annotations.SerializedName;
/**
* Created by putuguna on 1/24/2017.
*/
public class InsertFoodResponseModel {
@SerializedName("success")
private int status;
@SerializedName("message")
private String message;
public InsertFoodResponseModel(int status, String message) {
this.status = status;
this.message = message;
}
public InsertFoodResponseModel() {
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Create class LoggingInterceptors.java. This class used to see the output of the input process to the server.

Why use this class? Because in retrofit we will face a little bit difficulty to see the result, especially the URL and the JSON. You can see the result on logcat. The full code on LoggingInterceptor.java is like the follows  :

package com.putuguna.androidphplogin.utils;
import android.util.Log;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
/**
* Created by putuguna on 1/24/2017.
*/
public class LoggingInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
String requestLog = String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers());
//YLog.d(String.format("Sending request %s on %s%n%s",
// request.url(), chain.connection(), request.headers()));
if (request.method().compareToIgnoreCase("post") == 0) {
requestLog = "\n" + requestLog + "\n" + bodyToString(request);
}
Log.d("TAG", "request" + "\n" + requestLog);
Response response = chain.proceed(request);
long t2 = System.nanoTime();
String responseLog = String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers());
String bodyString = response.body().string();
Log.d("TAG", "response" + "\n" + responseLog + "\n" + bodyString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), bodyString))
.build();
}
public static String bodyToString(final Request request) {
try {
final Request copy = request.newBuilder().build();
final Buffer buffer = new Buffer();
copy.body().writeTo(buffer);
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}
}
Last is MainActivity.java. All the process and above classes will unite in this class. The full code of MainActivity.java is like the follows :

package com.putuguna.androidphplogin;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.putuguna.androidphplogin.apiservices.ApiService;
import com.putuguna.androidphplogin.clients.ApiClient;
import com.putuguna.androidphplogin.models.InsertFoodResponseModel;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
private Button btnInsert;
private ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnInsert = (Button) findViewById(R.id.button_insert_food);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Inserting");
progressDialog.setMessage("Please wait ....");
btnInsert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
popupInsertFood();
}
});
}
/**
* this method used to open popup
*/
private void popupInsertFood(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.popup_insert_food,null);
builder.setView(view);
final EditText etFoodName = (EditText) view.findViewById(R.id.edit_text_food_name);
final EditText etFoodQty = (EditText) view.findViewById(R.id.edit_text_food_quantity);
progressDialog.show();
builder.setPositiveButton("Insert", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
String foodName = etFoodName.getText().toString();
String foodQty = etFoodQty.getText().toString();
if(TextUtils.isEmpty(foodName)){
Toast.makeText(MainActivity.this, "Food Name is required", Toast.LENGTH_SHORT).show();
}else if(TextUtils.isEmpty(foodQty)){
Toast.makeText(MainActivity.this, "Food Quantity is required", Toast.LENGTH_SHORT).show();
}else{
insertData(foodName,foodQty);
}
}
});
builder.show();
}
/**
* this method used to send data to server or our local server
* @param foodName
* @param foodQty
*/
private void insertData(String foodName, String foodQty){
ApiService apiService = ApiClient.getClient().create(ApiService.class);
Call<InsertFoodResponseModel> call = apiService.insertFood(foodName, foodQty);
call.enqueue(new Callback<InsertFoodResponseModel>() {
@Override
public void onResponse(Call<InsertFoodResponseModel> call, Response<InsertFoodResponseModel> response) {
InsertFoodResponseModel insertFoodResponseModel = response.body();
//check the status code
if(insertFoodResponseModel.getStatus()==1){
Toast.makeText(MainActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}else{
Toast.makeText(MainActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
}
@Override
public void onFailure(Call<InsertFoodResponseModel> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
});
}
}
Demikian beberapa langkah yang dapat saya sampaikan tentang cara meng input data dari Android ke Database menggunakan Server yang dibuat dari Native PHP.
That's all about the steps how to input data from android to server made from PHP and MySQL.

If there are unclear about the steps above, feel-free to asked me. Thank you.

Download the project by clicking the following image


Related Posts

1 komentar so far

getting null reference on getstatus();


EmoticonEmoticon

:)
:(
hihi
:-)
:D
=D
:-d
;(
;-(
@-)
:o
:>)
(o)
:p
:-?
(p)
:-s
8-)
:-t
:-b
b-(
(y)
x-)
(h)