Android with Yii 2 Restful API Example

In this tutorial, we are going to learn how to use android with Yii 2 Php framework Restful API for data storage in android application.

In most large scale android applications, the data source is usually fetch from API endpoints and this make it easier for different platforms to share the same data. In this way, the back-end data can be managed smoothly without affect the client applications connected to it.

If you have not heard about Yii 2 Php framework, you can find more information about this framework here. While on it, I will suggest to read the documentation on Restful API.

First we are going to install a local server if you do you have one running. We will use a WAMP server.

Thereafter, you will also setup composer if you do have it in your system already. We will use composer to install yii 2 in the wamp server public folder.

android composer

Create a folder inside your server public folder and name it myyii. Open your command line change to this directory and execute the command below.

composer create-project –prefer-dist –stability=dev yiisoft/yii2-app-basic basic

Open the folder in you development environment. You can see the directory folder as shown below.

directory structure

Now, let go to the db.php file located here Basic – config – db.php to add our database connection credentials.

<string name="app_name">Android RecyclerView With Yii</string>
<?php

return [

'class' => 'yii\db\Connection',

'dsn' => 'mysql:host=localhost;dbname= ',

'username' => ' ',

'password' => ' ',

'charset' => 'utf8',

];

In WAMP, open the PhpMyAdmin and create a database called Users. Inside the database, we will create a table and it countries. Go to the quuey section and run the following code.

CREATE TABLE IF NOT EXISTS `countries` (

`id` int(20) NOT NULL AUTO_INCREMENT,

`name` varchar(300) NOT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

After we have created the table countries, we will insert some data inside the table. Run this query against the table.

INSERT INTO `countries` (`id`, `name`) VALUES

(1, 'Afghanistan'),

(2, 'Albania'),

(3, 'Algeria'),

(4, 'Angola'),

(5, 'Argentina'),

(6, 'Armenia'),

(7, 'Australia'),

(8, 'Austria'),

(9, 'Bangladesh'),

(10, 'Barbados');

With the database and table created, go to the models folder and create a new file, name it Countries.php. Add the below code inside the class.
<?php

namespace app\models;

use Yii;

/**
* This is the model class for table "countries".
*
* @property integer $id
* @property string $name
*/

class Countries extends \yii\db\ActiveRecord{
/**
* @inheritdoc
*/
public static function tableName(){
return 'countries';
}
/**
* @inheritdoc
*/
public function rules(){
return [
[['name'], 'required'],
[['name'], 'string', 'max' => 300],
[['name'], 'unique'],
];
}
/**
* @inheritdoc
*/
public function attributeLabels(){
return [
'id' => 'ID',
'name' => 'Name',
];
}
}

We are going to create our controller class. Open the controllers folder and create a file, name the file CountriesController and let it extends the \yii\rest\ActiveController. Add the following code to this class.

<?php

namespace app\controllers;

use app\models\Countries;

class CountriesController extends \yii\rest\ActiveController{

public $modelClass = 'app\models\Countries';

public function actionIndex(){

}

public function actionView(){

}

public function actionCreate(){

}

public function actionUpdate(){

}

public function actionDelete(){

}

public function actionOptions(){

}

}

The following action methods will map to the corresponding API end points. Now, when you enter the url and append countries to it, it will return all the country names stored in the database.

Android Client App

As we have finished with our back-end API, we will proceed to create an android client app. The app will be simple, we will just retrieve all the countries stored in our database and display it on Android RecyclerView.

Before we dive into more details, it is important for us to understand what we are planning to achieve. Below is the screen-shot of the application we will be creating.

android yii Api

Lets start to soil our hands in code. Start up your IDE. For this tutorial, I am using the following tools and environment, feel free to use what works for you.

Windows 7

Android Studio

Sony Xperia ZL

Min SDK 14

Target SDK 23

To create a new android application project, follow the steps as stipulated below.

Go to File menu

Click on New menu

Click on Android Application

Enter Project name: AndroidYii

Package: com.inducesmile.androidyii

Select Blank Activity

Name your activity : MainActivity

Keep other default selections

Continue to click on next button until Finish button is active, then click on Finish Button.

Strings.xml

We are going to update our project strings.xml file located in the values folder inside the res folder. Open the file and add the code below to it.

<resources>
    <string name="app_name">Android RecyclerView With Yii</string>
    <string name="no_country">No country has been added</string>
</resources>

Colors.xml

Open the colors.xml file in the same location as the strings.xml file and add the code below to the file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="divider">#dddfe0</color>
</resources>

Manifest.xml

Since we are going to make some internet call, we will add internet permission. Open the Manifest.xml and add the code below.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.inducesmile.androidrecyclerviewwithyii">
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

line_divider.xml

Go to the drawable folder, right click and select create a file and name the file line_divider.xml. Open the file and add the following code inside it.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size
        android:width="1dp"
        android:height="1dp" />
    <solid android:color="@color/divider" />
</shape>

activity_main.xml

Lets move over to the main layout file and add a RecyclerView. This RecyclerView will display all the countries names stored in database.

Open the activity_main.xml file and add the code below.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.inducesmile.androidrecyclerviewwithyii.MainActivity">
    <android.support.v7.widget.RecyclerView
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/country_lists"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        android:orientation="vertical"/>
</RelativeLayout>

RecyclerView Adapter

We need to create an adapter which we will use to bind our data source to the RecyclerView. Go to the package folder , right click on the folder and choose create a new java file. Name the java file RecyclerViewAdapter. Add the code below to the file.

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders>{
    private List<ItemObject> itemList;
    private Context context;
    public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
        this.itemList = itemList;
        this.context = context;
    }
    @Override
    public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
        RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
        return rcv;
    }
    @Override
    public void onBindViewHolder(RecyclerViewHolders holder, int position) {
        holder.countries.setText(itemList.get(position).getCountries());
    }
    @Override
    public int getItemCount() {
        return this.itemList.size();
    }
}

list_item.xml

You can that we inflate a layout file in our RecyclerView Adapter name list_item.xml. Create a file with this name in the layout folder. Open the file and add the code below.

<?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">
    <TextView
        android:id="@+id/country_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:text="@string/app_name"/>
</LinearLayout>

RecycrViewHolder.java

We are going to create a View Holder pattern class which the RecycerView will use. Create a java file and name it RecyclerViewHolder.java. Add the following code to the file.

import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.TextView;
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
    public TextView countries;
    private SparseBooleanArray selectedItems = new SparseBooleanArray();
    public RecyclerViewHolders(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        countries = (TextView)itemView.findViewById(R.id.country_name);
    }
    @Override
    public void onClick(View view) {
    }
}

MainActivity.Java

In the MainActivity class, we will obtain the instance of the RecyclerView widget. Since we will make an internet call to retrieve all the country names stored in our remote database, we will create a method name requestRemoteDatabase(). We will pass the path to our web server side to this method and call it in the onCreate() method of the Activity class.

Open the MainActivity class and add the following code inside the class.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
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.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private RecyclerView recyclerView;
    private LinearLayoutManager layoutManager;
    private List<ItemObject> countryList;
    private RecyclerViewAdapter adapter;
    private static final String API_SERVER_PATH ="Path_to_server";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView)findViewById(R.id.country_lists);
        recyclerView.addItemDecoration(new SimpleDividerItemDecoration(this));
        layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setVisibility(View.GONE);
        requestRemoteDatabase();
    }
    private void requestRemoteDatabase(){
        RequestQueue queue = Volley.newRequestQueue(this);
        StringRequest stringRequest = new StringRequest(Request.Method.GET, API_SERVER_PATH, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Response " + response);
                GsonBuilder builder = new GsonBuilder();
                Gson gson = builder.create();
                countryList = Arrays.asList(gson.fromJson(response, ItemObject[].class));
                //display first question to the user
                if(null == countryList){
                    Toast.makeText(MainActivity.this, getResources().getString(R.string.no_country),Toast.LENGTH_LONG).show();
                    return;
                }
                recyclerView.setVisibility(View.VISIBLE);
                adapter = new RecyclerViewAdapter(MainActivity.this, countryList);
                recyclerView.setAdapter(adapter);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d(TAG, "Error " + error.getMessage());
            }
        });
        queue.add(stringRequest);
    }
}

ItemObject.java

The last it to do is to add a ItemObject class which will wrap the country names we will retrieve from the database.

import com.google.gson.annotations.SerializedName;
public class ItemObject {
    @SerializedName("name")
    private String countries;
    public ItemObject(String countries) {
        this.countries = countries;
    }
    public String getCountries() {
        return countries;
    }
    public void setCountries(String countries) {
        this.countries = countries;
    }
}

This brings us to the end of this tutorial. I hope that you have learn something. Run your app to see for yourself.

You can download the code for this tutorial below. If you are having hard time downloading the tutorials, kindly contact me.

Remember to subscribe with your email address so that you will be among the first to receive my new android blog post once it is published.

Please if you love this tutorial, kindly download my android app – Complete Mathematics – in Google Play Store and let me know what you think about it.

Add a Comment