Simple app using cordova and ratchet 2.

Download the required software packages

Download and install Eclipse Neon and Xcode 7 (if you using Mac for mobile development).

Eclipse Neon – http://www.eclipse.org/neon/
JDK 1.8 – http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Xcode 7 – https://developer.apple.com/xcode/downloads/
Sublime Text – https://www.sublimetext.com/3

Setup ADT and Android SDK into your eclipse. Then you need to setup cordova using NPM (node package manager) from that link.  Download Node.js (https://nodejs.org/en/) and install cordova after that. Open terminal/command line and type this command to install cordova into your machine.

npm install -g cordova

Download Jquery and Ratchet from their official website. You should unzip it to proper location. For this tutorial, we using Jquery 3.1.1 and Ratchet 2.0.2.

Setting up your development environment

Create a cordova project using command below in your terminal/cmd:

cordova create com.intellij.cordova.todolist.v2

Open config.xml inside com.intellij.cordova.todolist.v2 folder and replace with this code.

config.xml

config.xml

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.intellij.cordova.todolist.v2" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>ToDoList</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>

Add platform for iOS and android.

cordova platform add ios
cordova platform add android
cordova platform add android

cordova platform add android

 

cordova platform add ios

cordova platform add ios

Preview your app (android)

Import android project into your eclipse.

import cordova project

import cordova project

Select AndroidExisting Android Code Into Workspace.

import existing android code into workspace

import existing android code into workspace

Browse your project and click Finish.

import android project

import android project

Run android app in your mobile device.

Preview your app (ios)

Go to your project directory and browse for xcode project, platforms > ios > CordovaRatchet.xcodeproj then run xcode project. Click Play on top left side to preview the app on your simulator.

xcode project

xcode project

Learning client side API and building a multi page application

Open cordova project in Sublime Text editor. Right click js folder on your project. Select New File.

New Javascript File

Add New Javascript File

Create 4 javascript files.

  • main.js – initialize function.
  • AddPage.js – to add user details.
  • ListPage.js – to retrieve user list.
  • DetailPage.js – to retrieve user details.

Right click www folder and select New Folder to create a new folder. Name it pages and save it.

Add New Folder

Add New Folder

Then create a few of html pages inside page folder that we already created just now. Right click pages folder and select New File.

Add New HTML File

Add New HTML File

Create 3 html files and click Finish. Repeat.

  • AddPage.html – to add user details.
  • ListPage.html – to retrieve user list.
  • DetailPage.html – to retrieve user details.

Copy Jquery javascript files that you already extract from proper location into js folder. Go to extracted Ratchet directory and select/copy all folders inside ratchet-2.0.2 > dist. Then paste it inside www folder.

latest cordova project directory

latest cordova project directory

Open your index.html and replace with this code.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
 
    <!-- Sets initial viewport load and disables zooming -->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
 
    <!-- Makes your prototype chrome-less once bookmarked to your phone's home screen -->
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
 
    <!-- Include the compiled Ratchet CSS -->
    <link href="css/ratchet.css" rel="stylesheet">
    <script src="cordova.js" type="text/javascript"></script>
    <script src="js/jquery-3.1.1.min.js"></script>
    <script src="js/ratchet.js"></script>
    <script src="js/main.js"></script>
  </head>
  <body onload="init()">
 
  </body>
</html>

Replace all codes with given codes for each javascript files.

AddPage.js

currentPage={};

currentPage.init = function() {
    console.log("AddPage :: init");
};

currentPage.back = function(){
    console.log("AddPage :: back");
    $("body").load(path + "pages/ListPage.html", function(){
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};

DetailPage.js

currentPage={};

currentPage.init = function() {
    console.log("DetailPage :: init");
};

currentPage.back = function(){
    console.log("DetailPage :: back");
    $("body").load(path + "pages/ListPage.html", function(){
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};

ListPage.js

currentPage = {};

currentPage.init = function(){
    console.log("ListPage :: init");
};

currentPage.loadPage = function(pageIndex){
    console.log("ListPage :: loadPage :: pageIndex: " + pageIndex);
    $("body").load(path + "pages/" + pageIndex + ".html");
    $.getScript(path + "js/" + pageIndex +".js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};

main.js

var pagesHistory = [];
var currentPage = {};
var path = "";

function init(){

    $("body").load(path + "pages/ListPage.html", function(){
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });

}

Replace all codes with given codes for each html files.

AddPage.html

<script>
    $.getScript(path + "js/AddPage.js");
</script>

<header class="bar bar-nav">
	<a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>
  	<h1 class="title">AddPage</h1>
</header>

DetailPage.html

<script>
    $.getScript(path + "js/DetailPage.js");
</script>

<header class="bar bar-nav">
	<a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>
  	<h1 class="title">DetailPage</h1>
</header>

ListPage.html

<script>
    $.getScript(path + "js/ListPage.js");
</script>

<header class="bar bar-nav">
	<button id="LoadAddButton" class="btn pull-right" onclick="currentPage.loadPage('AddPage');">Load Add.html</button>
  	<h1 class="title">ListPage</h1>
</header>

<div class="content">
<div class="content-padded">
    <button id="LoadDetailButton" class="btn btn-positive btn-block" onclick="currentPage.loadPage('DetailPage');">Load Detail.html</button>
</div>
</div>

Preview your app using previous steps.

Now we want to integrate API with app. You need to replace all html files and js files so we can invoke API from there.

AddPage.js

currentPage = {};
currentPage.init = function() {
    console.log("AddPage :: init");
};
currentPage.back = function() {
    console.log("AddPage :: back");
    $("body").load(path + "pages/ListPage.html", function() {
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};
currentPage.add = function() {
    console.log("AddPage :: add");
    var name = $("#name").val();
    var description = $("#description").val();
    formData = {
        name: $("#name").val(),
        description: $("#description").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (description == "") {
        alert("Please enter description");
    } else {
        $.ajax({
            type: "post",
            url: "http://demo.revivalx.com/todolist-api/create_task.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Add task success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Add task failure");
            }
        });
    }
};

DetailPage.js

currentPage = {};
currentPage.init = function() {
    console.log("DetailPage :: init");
    detailTask();
};
currentPage.back = function() {
    console.log("DetailPage :: back");
    $("body").load(path + "pages/ListPage.html", function() {
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};
currentPage.edit = function() {
    console.log("DetailPage :: edit");
    var taskId = sessionStorage.taskId;
    var name = $("#name").val();
    var description = $("#description").val();
    formData = {
        taskId: sessionStorage.taskId,
        name: $("#name").val(),
        description: $("#description").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (description == "") {
        alert("Please enter description");
    } else {
        $.ajax({
            type: "post",
            url: "http://demo.revivalx.com/todolist-api/update_task.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Edit task success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Edit task failure");
            }
        });
    }
};

function detailTask() {
    formData = {
        taskId: sessionStorage.taskId
    }
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/todolist-api/get_task_details.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            $('#name').val(data.task[0].name);
            $('#description').val(data.task[0].description);
        },
        error: function() {
            alert("Detail task failure");
        }
    });
}
currentPage.remove = function() {
    console.log("DetailPage :: delete");
    deleteTask();
};

function deleteTask() {
    formData = {
        taskId: sessionStorage.taskId
    }
    $.ajax({
        type: "post",
        url: "http://demo.revivalx.com/todolist-api/delete_task.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            alert("Delete task success");
            $("body").load(path + "pages/ListPage.html", function() {
                $.getScript(path + "js/ListPage.js", function() {
                    if (currentPage.init) {
                        currentPage.init();
                    }
                });
            });
        },
        error: function() {
            alert("Delete task failure");
        }
    });
}

ListPage.js

currentPage = {};
currentPage.init = function() {
    console.log("ListPage :: init");
    listTasks();
};
currentPage.loadPage = function(pageIndex) {
    console.log("ListPage :: loadPage :: pageIndex: " + pageIndex);
    $("body").load(path + "pages/" + pageIndex + ".html");
    $.getScript(path + "js/" + pageIndex + ".js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};
currentPage.detailPage = function(taskId) {
    sessionStorage.setItem("taskId", taskId);
    $("body").load(path + "pages/DetailPage.html");
    $.getScript(path + "js/DetailPage.js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};

function listTasks() {
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/todolist-api/get_all_tasks.php",
        dataType: "json",
        success: function(data) {
            var ul = $('#taskList');
            var html = '';
            $.each(data.tasks, function(index, item) {
                html += '<li class="table-view-cell">';
                html += '<a class="navigate-right" onclick="currentPage.detailPage(' + item.taskId + ');" >';
                html += item.name;
                html += '</a></li>';
            });
            ul.append(html);
        },
        error: function() {
            alert("List task failure");
        }
    });
}

AddPage.html

<script>
    $.getScript(path + "js/AddPage.js");
</script>
  
<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>
    <h1 class="title">AddPage</h1>
</header>
<div class="content">
	<div class="card">
    <ul class="table-view">
        <li class="table-view-cell table-view-divider">Name:</li>
 
        <li class="table-view-cell"><input id="name" name="name" type="text"></li>
 
        <li class="table-view-cell table-view-divider">Description:</li>
 
        <li class="table-view-cell"><input id="description" name="description" type="text"></li>
 
        <li class="table-view-cell"></li>
    </ul>
   </div>
    <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.add();">ADD TASK</button>
    </div>
</div>

DetailPage.html

<script>
    $.getScript(path + "js/DetailPage.js");
</script>
 
<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>
    <h1 class="title">DetailPage</h1>
</header>
 
<div class="content">
	<div class="card">
    <ul class="table-view">
        <li class="table-view-cell table-view-divider">Name:</li>
 
        <li class="table-view-cell"><input id="name" name="name" type="text"></li>
 
        <li class="table-view-cell table-view-divider">Description:</li>
 
        <li class="table-view-cell"><input id="description" name="description" type="text"></li>
 
    </ul>
   </div>
   <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.edit();">EDIT TASK</button>
   </div>
   <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-negative btn-block" onclick="currentPage.remove();">REMOVE TASK</button>
   </div> 
</div>

ListPage.html

<script>
    $.getScript(path + "js/ListPage.js");
</script>

<header class="bar bar-nav">
	<button id="LoadAddButton" class="btn pull-right" onclick="currentPage.loadPage('AddPage');">Add</button>
  	<h1 class="title">ListPage</h1>
</header>

<div class="content">
	<ul id="userList" class="table-view"></ul>
</div>

Build and run your app. You can find the source code here: https://github.com/IntellijSys/com.intellij.cordova.todolist.v2

Building a Hybrid Mobile app using Ionic Framework

Getting started with Ionic Framework. This tutorial show you how to do simple CRUD operation using Ionic Framework. What you need for this tutorial are

Outline that cover for this tutorial:

  • Set up your development environment
  • Preview your app
  • Learn client side API
  • Build a multi page application
  • Integration with server side API

Setting up your development environment

After that, install node.js to use npm for package manager. If you not install node.js, you should not be able to invoke node or npm on your command line to install Ionic Framework. Then install Ionic Framework using terminal or command prompt.

npm install -g cordova ionic

After you finish install the Ionic Framework. You can start create your project using Ionic command. Open your terminal/command prompt, type these command.

ionic start IonicToDoList tabs
ionic start IonicToDoList tabs

ionic start IonicToDoList tabs

Open Ionic project with Sublime.

Ionic project with Sublime Text

Ionic project with Sublime Text

Open config.xml and replace with this id.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<widget id="com.ionicframework.ionictodolist" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
  <name>IonicToDoList</name>
  <description>
        An Ionic Framework and Cordova project.
    </description>
  <author email="you@example.com" href="http://example.com.com/">
      Your Name Here
    </author>
  <content src="index.html"/>
  <access origin="*"/>
  <preference name="webviewbounce" value="false"/>
  <preference name="UIWebViewBounce" value="false"/>
  <preference name="DisallowOverscroll" value="true"/>
  <preference name="SplashScreenDelay" value="2000"/>
  <preference name="FadeSplashScreenDuration" value="2000"/>
  <preference name="android-minSdkVersion" value="16"/>
  <preference name="BackupWebStorage" value="none"/>
  <preference name="SplashScreen" value="screen"/>
  <feature name="StatusBar">
    <param name="ios-package" value="CDVStatusBar" onload="true"/>
  </feature>
</widget>

Build android and iOS app using this command.

cd IonicToDoList
ionic platform add android
ionic platform add ios
sudo ionic platform add android

sudo ionic platform add android

Preview your app (android)

Open your eclipse. Select File > Import.

import android project

import android project

Select Existing Android Code Into Workspace. Click Next.

import android project

import android project

Click Browse to select android project and click Finish.

import android project

import android project

Run android app in android simulator.

Preview your app (iOS)

Open your Xcode. Right click on iphone folder and go to Run AsXcode Project.

Xcode

Xcode

Open app.js file in www/js folder. Replace with this code.

angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])

.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    if (window.cordova &amp;&amp; window.cordova.plugins &amp;&amp; window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.disableScroll(true);

    }
    if (window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
})

.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
  $stateProvider

    .state('tab', {
    url: '/tab',
    abstract: true,
    templateUrl: 'templates/tabs.html'
  })

  .state('tab.list', {
      url: '/list',
      views: {
        'tab-list': {
          templateUrl: 'templates/list.html',
          controller: 'ListCtrl'
        }
      }
    })
    .state('tab.detail', {
      url: '/detail/:taskId',
      views: {
        'tab-detail': {
          templateUrl: 'templates/detail.html',
          controller: 'DetailCtrl'
        }
      }
    })

  .state('tab.add', {
    url: '/add',
    views: {
      'tab-add': {
        templateUrl: 'templates/add.html',
        controller: 'AddCtrl'
      }
    }
  });

  $urlRouterProvider.otherwise('/tab/list');

})

.directive("initFromForm", function ($parse) {
    return {
        link: function (scope, element, attrs) {
            var attr = attrs.initFromForm || attrs.ngModel || element.attrs('name'),
            val = attrs.value;
            $parse(attr).assign(scope, val);
        }
    };
});

Open services.js file in www/js folder. Replace with this code.

angular.module('starter.services', [])

.factory('todoService', function($http) {
    var baseUrl = 'http://demo.revivalx.com/todolist-api/';
    return {
        getAll: function() {
            return $http.get(baseUrl+'get_all_tasks.php');
        },
        getId: function (taskId){
            return $http.get(baseUrl+'get_task_details.php?taskId='+taskId); 
        },
        create: function (data){
            return $http.post(baseUrl+'create_task.php',data,{
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
                }
            });
        },
        update: function (data){
            return $http.post(baseUrl+'update_task.php',data,{
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
                }
            });
        },
        delete: function  (taskId){
            return $http.get(baseUrl+'delete_task.php?id='+taskId);
        }
    };
    
});

Open controllers.js file in www/js folder. Replace with this code.

angular.module('starter.controllers', [])

.controller('tabCtrl', function($scope){
})

.controller('ListCtrl', function($scope,$state, todoService){
    $scope.showData = function() {
      todoService.getAll().success(function(data) {
            $scope.datatodos = data;
        }).finally(function() {
            $scope.$broadcast('scroll.refreshComplete');
        });
    };
    $scope.showData();
    
    $scope.reload = function (){
        $state.go('tab.list');
    };
    
    $scope.delete = function (datatodo){
        todoService.delete(datatodo.taskId);
        $scope.datatodos.splice($scope.datatodos.indexOf(datatodo),1);
    };
})

.controller('AddCtrl', function($scope,$ionicPopup,todoService){
    $scope.showAlert = function(msg) {
      $ionicPopup.alert({
          title: msg.title,
          template: msg.message,
          okText: 'Ok',
          okType: 'button-positive'
      });
    };
    
    $scope.datatodo={};
    $scope.save = function (){
        if (!$scope.datatodo.name){
            $scope.showAlert({
                title: "Information",
                message: "Name is required"
            });
        }else if (!$scope.datatodo.description){
            $scope.showAlert({
                title: "Information",
                message: "Description is required"
            });
        }else{
            todoService.create({
                name: $scope.datatodo.name,
                description: $scope.datatodo.description,
            }).success(function(data){
                $scope.showAlert({
                    title: "Information",
                    message: "Successfully recorded"
                });
            });
        }
        
    };
       
})

.controller('DetailCtrl', function($scope,$stateParams,$ionicPopup,$ionicModal,$state,todoService){
        
    $scope.showDataId = function() {
      todoService.getId($stateParams.taskId).success(function(datatodo) {
            $scope.datatodo = datatodo;
        });
        
    };
    $scope.showDataId();
    
    $scope.back = function (){
        $state.go('tab.list');
    };
    
    $ionicModal.fromTemplateUrl('edit.html', function(modal){
        $scope.taskModal = modal;
  }, {
            scope : $scope,
            animation : 'slide-in-up' 
  });
        
        $scope.showAlert = function(msg) {
            $ionicPopup.alert({
                title: msg.title,
                template: msg.message,
                okText: 'Ok',
                okType: 'button-positive'
            });
          };
  
  $scope.editModal = function(){
            $scope.taskModal.show();
  };
  
  $scope.cancel = function(){
            $scope.taskModal.hide();
            $scope.showDataId();
  };
        
  $scope.edit = function(taskId,name,description){
            if (!taskId){
                $scope.showAlert({
                    title: "Information",
                    message: "Id is required"
                });
            }else if (!name){
                $scope.showAlert({
                    title: "Information",
                    message: "Name is required"
                });
            }else if(!description){
                $scope.showAlert({
                    title: "Information",
                    message: "Description is required"
                });
            }else{
                $scope.id = id;
                $scope.name = name;
                $scope.description = description;
                todoService.update({
                    'id' : id,
                    'name': name,
                    'description': description,
                }).then(function(resp) {
                  console.log('Success', resp);
                  $scope.showAlert({
                        title: "Information",
                        message: "Successfully updated"
                    });
                },function(err) {
                  console.error('Error', err);
                }); 
            }
  };
  
});

Delete all the html files in www/templates and create these all 4 files.

  1. add.html.
  2. detail.html.
  3. list.html.
  4. tabs.html.

Replace all codes with given codes for each html files.

tabs.html

<ion-tabs class="tabs-icon-top tabs-color-active-positive">

  <ion-tab title="Status" icon-off="ios-list" icon-on="ion-ios-pulse-strong" href="#/tab/list">
    <ion-nav-view name="tab-list"></ion-nav-view>
  </ion-tab>

  <ion-tab title="Status" icon-off="ios-add" icon-on="ion-ios-pulse-strong" href="#/tab/add">
    <ion-nav-view name="tab-add"></ion-nav-view>
  </ion-tab>

</ion-tabs>

list.html

<ion-header-bar class="bar-positive">
        <button class="button button-icon icon ion-ios7-minus-outline" ng-click="data.showDelete = 
        !data.showDelete; data.showReorder=false"></button>
        <h1 class="title">ToDo List</h1>
        <button class="button button-icon icon ion-ios7-loop" ng-click="reload()"></button>
</ion-header-bar>
<ion-view>
    <ion-content padding="false" class="has-header">
        <ion-refresher
            pulling-text="Pull to refresh..."
            on-refresh="showData()">
          </ion-refresher>
        <ion-list show-Delete = "data.showDelete" show-Reorder = "data.showReorder">
            <ion-item class="item-avatar item-icon-right" ng-repeat="datatodo in datatodos" type="item-text-wrap" href="#/tab/detail/{{datatodo.taskId}}">
                <i class="icon ion-ios7-arrow-right"></i>
                <h2>{{datatodo.name}}
                    <br> 
                    <font size="2" color="gray" >Description : {{datatodo.description}}</font>
                </h2>
                <ion-delete-button class="ion-minus-circled" ng-click="delete(datatodo);"></ion-delete-button>
            </ion-item>
        </ion-list>
    </ion-content>
</ion-view>

add.html

<ion-header-bar class="bar-positive">
        <h1 class="title">Add Task</h1>
</ion-header-bar>
<ion-content class="padding">
      <form>
        <ion-list>
            <label class="item item-input">
                <input type="text" ng-model="datatodo.name" placeholder="Name">
            </label>
            <label class="item item-input">
                <input type="text" ng-model="datatodo.description" placeholder="Description">
            </label>
        </ion-list>
        <div class="spacer" style="height: 5px;"></div>
        <button class="button icon ion-person-stalker button-balanced button-block" ng-click="save();"> Save</button>
    </form>
</ion-content>

detail.html

<ion-header-bar class="bar-positive">
        <button class="button button-icon icon ion-ios7-arrow-left" ng-click="back();">Back</button>
        <h1 class="title">Task Detail</h1>
</ion-header-bar>
<ion-content class="padding" ng-repeat="datatodo in datatodo">
    <h3>Detail :</h3>
    <p>
        <font size="2" color="gray" >Nama : {{datatodo.name}}</font>
    <br>
        <font size="2" color="gray" >Description : {{datatodo.description}}</font>
    </p>
    <button class="button button-balanced button-block" ng-click="editModal()">Edit Task</button>
</ion-content>
<script id="edit.html" type="text/ng-template">
        <div class="modal">
            <ion-header-bar class="bar-stable">
                <button class="button button-icon icon ion-ios7-close-outline" ng-click="cancel()"></button>
                <h1 class="title"> Edit Task</h1>
            </ion-header-bar>
            <ion-content ng-repeat="datatodo in datatodo">
                <form>
                    <div class="list">
                        <label class="item item-input">
                        <span class="input-label">ID :</span>
                            <input type="text" placeholder="{{datatodo.taskId}}" ng-model="id" value="{{datatodo.id}}" init-from-form>
                            <p>{{datatodo.taskId}}</p>
                        </label>
                        <label class="item item-input">
                        <span class="input-label">Name :</span>
                            <input type="text" placeholder="{{datatodo.name}}" ng-model="name" value="{{datatodo.name}}" init-from-form>
                        </label>
                        <label class="item item-input">
                        <span class="input-label">Description :</span>
                            <input type="text" placeholder="{{datatodo.description}}" ng-model="description" value="{{datatodo.description}}" init-from-form>
                        </label>
                        <button class="button button-positive button-block" ng-click="edit(taskId,name,description);">
                            Save
                        </button>
                    </div>
                </form>
        </ion-content>
        </div>
</script>

Build your project using this command and run the app.

ionic build ios
ionic build android

Swift iOS 9 iPhone Accelerator Application

Open Xcode and select Create a new Xcode project.

Welcome to Xcode

Welcome to Xcode

Select Single View Application and click Next.

Single View Application

Single View Application

For product name, use IntellijSwiftAccelerator and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and make sure only iPhone is selected in Devices. Click Next.

P.S: Don’t forget to untick Include Unit Tests and Include UI Tests.

Open Main.storyboard. Set to Compact Width | Any Height.

Compact Width | Any Height

Compact Width | Any Height

Ctrl + Drag from the Label to the File’s Owner and make the connection with the corresponding properties.

Accelerator ViewController

Accelerator ViewController

Create a new ViewController.

Cocoa Touch Class

Cocoa Touch Class

UIViewController

UIViewController

Then make sure you attach this file into view controller in Identity inspector.

Identity inspector -UIViewController

Identity inspector -UIViewController

The other properties are needed to update the Labels with the axes values. Go to ViewController.swift and add 3 UILabels to the main View.

Outlet – xAxis

Outlet – xAxis

Outlet – yAxis

Outlet – yAxis

Outlet – zAxis

Outlet – zAxis

Open AcceleratorViewController.swift and update the with this code.

import UIKit
import CoreMotion

class AccelerometerViewController: UIViewController {

    var motionManager: CMMotionManager = CMMotionManager()
    @IBOutlet weak var xAxis: UILabel!
    @IBOutlet weak var yAxis: UILabel!
    @IBOutlet weak var zAxis: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.motionManager.accelerometerUpdateInterval = 1;
        
        if (self.motionManager.accelerometerAvailable)
        {
            self.motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue()) {
                (data, error) in
                dispatch_async(dispatch_get_main_queue()) {
                    self.xAxis.text = String(data!.acceleration.x)
                    self.yAxis.text = String(data!.acceleration.y)
                    self.zAxis.text = String(data!.acceleration.z)
                }
            }
            
        } else {
            print("not active")
        }
    }
}

Swift iOS 9 iPhone Camera Application

Open Xcode and select Create a new Xcode project.

Welcome to Xcode

Welcome to Xcode

Select Single View Application and click Next.

Single View Application

Single View Application

For product name, use IntellijSwiftCamera and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and make sure only iPhone is selected in Devices. Click Next.

P.S: Don’t forget to untick Include Unit Tests and Include UI Tests.

Open Main.storyboard. Set to Compact Width | Any Height.

Compact Width | Any Height

Compact Width | Any Height

This is a very simple user interface consisting of an image view, a toolbar and two bar button items. (Don’t forget to set AutoLayout).

Camera ViewController

Camera ViewController

Create a new ViewController.

Cocoa Touch Class

Cocoa Touch Class

 

UIViewController

UIViewController

Then make sure you attach this file into view controller in Identity inspector.

Identity inspector -UIViewController

Identity inspector -UIViewController

Select the image view object in the view canvas, display the Assistant Editor panel. Ctrl-click on the image view object and drag to a position just below the class declaration line in the Assistant Editor. Release the line, and, in the resulting connection dialog, establish an outlet connection named imageView.

Outlet - imageView

Outlet – imageView

Open CameraViewController.swift and update the with this code.

import UIKit
import MobileCoreServices

class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet weak var imageView: UIImageView!
    var newMedia: Bool?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

With the Assistant Editor still visible, establish action connections for the two buttons to methods named useCamera and useCameraRoll respectively (keeping mind that it may be necessary to click twice on each button to select it since the first click will typically select the toolbar parent object).

Action - userCamera

Action – userCamera

 

Action - useCameraRoll

Action – useCameraRoll

Open CameraViewController.swift and update the with this code for useCamera and useCameraRoll functions.

    @IBAction func useCamera(sender: AnyObject) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.Camera) {
            
            let imagePicker = UIImagePickerController()
            
            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerControllerSourceType.Camera
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = false
            
            self.presentViewController(imagePicker, animated: true, completion: nil)
            newMedia = true
        }
    }
    
    @IBAction func useCameraRoll(sender: AnyObject) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.SavedPhotosAlbum) {
            let imagePicker = UIImagePickerController()
            
            imagePicker.delegate = self
            imagePicker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
            imagePicker.mediaTypes = [kUTTypeImage as String]
            imagePicker.allowsEditing = false
            self.presentViewController(imagePicker, animated: true, completion: nil)
            newMedia = false
        }
    }

Writing the Delegate methods in CameraViewController.

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        let mediaType = info[UIImagePickerControllerMediaType] as! String
        
        self.dismissViewControllerAnimated(true, completion: nil)
        
        if mediaType == kUTTypeImage as String {
            let image = info[UIImagePickerControllerOriginalImage] as! UIImage
            
            imageView.image = image
            
            if (newMedia == true) {
                UIImageWriteToSavedPhotosAlbum(image, self, #selector(CameraViewController.image(_:didFinishSavingWithError:contextInfo:)), nil)
            }
        }

    }
    
    func image(image: UIImage, didFinishSavingWithError error: NSErrorPointer, contextInfo:UnsafePointer&lt;Void&gt;) {
        
        if error != nil {
            let alert = UIAlertController(title: "Save Failed",
                                          message: "Failed to save image",
                                          preferredStyle: UIAlertControllerStyle.Alert)
            
            let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
            
            alert.addAction(cancelAction)
            self.presentViewController(alert, animated: true, completion: nil)
        }
    }

    func imagePickerControllerDidCancel(picker: UIImagePickerController) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }

Results.

Screenshot 1

Screenshot 1

 

Screenshot 2

Screenshot 2

Building a To Do List iOS Mobile App – Part 2

In the first part of the simple iOS mobile app (toDoList) tutorial series, you covered the basics of setting environment and user interface.

We’ll start where we left off last tutorial, so open your project from last time, or go through the previous tutorial first. http://intellij.my/2016/09/03/building-a-to-do-list-ios-mobile-app-part-1/

Select UITableViewController in Main.Storyboard and edit Attribute Inspector according to this setting:

Style: Basic
Identifier: TaskCell
Accessory: Disclosure Indicator

Attribute Inspector.

Attribute Inspector.

 

UiTableViewController

UiTableViewController

Go to UIViewController and make sure the user interface is similar like this one. Don’t forget to set constraints for each elements. If you don’t know how to do it, feel free to refer it here, https://developer.apple.com/library/ios/referencelibrary/GettingStarted/RoadMapiOS/DesigningaUserInterface.html.

UIViewController

UIViewController

Create two Cocoa Touch Class. One is TableViewController.swift(UITableViewController) and the other one is ViewController.swift(UIViewController).

Xcode 7.3.1 – New File

Xcode 7.3.1 – New File

 

Cocoa Touch Class

Cocoa Touch Class

 

UITableViewController

UITableViewController

 

UIViewController

UIViewController

Then make sure you attach both files into each controllers in Identity inspector.

Identity inspector – UITableViewController

Identity inspector – UITableViewController

 

Identity inspector -UIViewController

Identity inspector -UIViewController

Open Info.plist and add these code at the end third last line of code before tag.

...
</array>
<key>NSAppTransportSecurity</key>
	<dict>
	<key>NSAllowsArbitraryLoads</key>
	<true/>
	</dict>
</dict>
</plist>

Open TableViewController.swift and update the with this code.

import UIKit
import Alamofire
import SwiftyJSON

class TableViewController: UITableViewController {

    var id: String!
    var name: String!
    var descriptions: String!
    var tasks:[JSON] = []
    
    @IBAction func addNewTask(sender: AnyObject) {
        self.id = nil
        self.performSegueWithIdentifier("MySegue", sender: self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        loadData()
    }
    
    override func viewWillAppear(animated: Bool) {
        loadData()
    }
    
    func loadData() {
        Alamofire.request(.GET , "http://demo.revivalx.com/todolist-api/get_all_tasks.php", parameters: [:])
            .responseJSON { response in
                if response.result.isSuccess {
                    var jsonObj = JSON(response.result.value!)
                    if let data = jsonObj["tasks"].arrayValue as [JSON]?{
                        self.tasks = data
                        self.tableView.reloadData()
                    }
                }
        }
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tasks.count
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath)
        let task = tasks[indexPath.row]
        cell.textLabel?.text = task["name"].stringValue
        return cell
    }
    
    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            let task = tasks[indexPath.row]
            Alamofire.request(.GET , "http://demo.revivalx.com/todolist-api/delete_task.php", parameters: ["taskId":task["taskId"].stringValue])
                .responseJSON { response in
                    if response.result.isSuccess {
                        self.loadData()
                    }
            }
        }
    }
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let task = tasks[indexPath.row]
        id = task["taskId"].stringValue
        name = task["name"].stringValue
        descriptions = task["description"].stringValue
        self.performSegueWithIdentifier("MySegue", sender: self)
    }
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "MySegue" {
            let viewController: ViewController = segue.destinationViewController as! ViewController
            viewController.id = id
            viewController.name = name
            viewController.descriptions = descriptions
        }
    }
}

Open ViewController.swift and replace the with this code.

import UIKit
import Alamofire
import SwiftyJSON

class ViewController: UIViewController {

    @IBOutlet weak var txtName: UITextField!
    @IBOutlet weak var txtDescription: UITextField!
    var id: String!
    var name: String!
    var descriptions: String!
    var tasks:[JSON] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()

        if id != nil {
            txtName.text = name
            txtDescription.text = descriptions
        }
    }

    @IBAction func btnSubmit(sender: AnyObject) {
        if id != nil {
            Alamofire.request(.POST , "http://demo.revivalx.com/todolist-api/update_task.php", parameters: ["taskId":id,"name":txtName.text!,"description":txtDescription.text!])
                .responseJSON { response in
                    if response.result.isSuccess {
                        self.navigationController?.popViewControllerAnimated(true)
                    }
            }
        } else {
            Alamofire.request(.POST , "http://demo.revivalx.com/todolist-api/create_task.php", parameters: ["name":txtName.text!,"description":txtDescription.text!])
                .responseJSON { response in
                    if response.result.isSuccess {
                        self.navigationController?.popViewControllerAnimated(true)
                    }
            }
        }
    }
}

Building a To Do List iOS Mobile App – Part 1

Swift is an innovative new programming language for Cocoa and Cocoa Touch. Writing code is interactive and fun, the syntax is concise yet expressive, and apps run lightning-fast. Swift is ready for your next iOS and OS X project — or for addition into your current app — because Swift code works side-by-side with Objective-C.

swift programming language

swift programming language

Here are some of features:

  1. Modern
  2. Designed for Safety
  3. Fast and Powerful
  4. Interactive Playgrounds
  5. Ready Today
  6. Read-Eval-Print-Loop (REPL)

Reference: https://developer.apple.com/swift/

Getting Started.

Before we start this tutorial, make sure you already setup your machine (mac) with these tools:

  1. Xcode 7.3.1 – https://developer.apple.com/xcode/downloads/

Open Xcode and select Create a new Xcode project.

Welcome to Xcode

Welcome to Xcode

Select Single View Application and click Next.

Single View Application

Single View Application

For product name, use IntellijSwiftToDoList and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and make sure only iPhone is selected in Devices. Click Next.

P.S: Don’t forget to untick Include Unit Tests and Include UI Tests.

IntellijSwiftToDoList

IntellijSwiftToDoList

Install CocoaPods using terminal. What is CocoaPods?

CocoaPods manages library dependencies for your Xcode projects.

The dependencies for your projects are specified in a single text file called a Podfile. CocoaPods will resolve dependencies between libraries, fetch the resulting source code, then link it together in an Xcode workspace to build your project.

Ultimately the goal is to improve discoverability of, and engagement in, third party open-source libraries by creating a more centralised ecosystem.

Reference: https://guides.cocoapods.org/using/getting-started.html

Open your terminal and type this command.

sudo gem install cocoapods

Go to your directory and initialize your pod using this command.

cd /Users/MNurdin/Documents/iOS/IntellijSwiftToDoList
pod init

Open your finder and edit pod file (Podfile) with these one.

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'

use_frameworks!

target 'IntellijSwiftToDoList' do
	pod 'Alamofire', '~> 3.4'
end

Go back to your terminal and run pod install to install all the dependencies. It takes a few of minutes to download.

pod install

After finish downloading, open IntellijSwiftToDoList.xcworkspace file, not IntellijSwiftToDoList.xcodeproj because we want to use the pod.

Storyboards and interface builder

Set to Compact Width | Any Height.

Compact Width | Any Height

Compact Width | Any Height

Delete ViewController.swift and ViewController on the Main.Storyboard. Drag a Table View Controller and View Controller to Main.Storyboard.

Main.Storyboard

Main.Storyboard

Select Table View Controller and navigate to Attributes inspector. Tick Is Initial View Controller.

Attributes inspector

Attributes inspector

Select the Table View Controller again and in the menu go to Editor > Embed In >Navigation Controller. This adds a Navigation Controller to the storyboard with an initial scene.

Editor > Embed In > Navigation Controller

Editor > Embed In > Navigation Controller

Select the Navigation Item under the Table View Controller, and in the Attributes Inspector type To Do List as the Title.

Navigation Item

Navigation Item

From the Object Library, drag a Bar Button Item to the right of the navigation bar on the Table View Controller. Select the Bar Button Item (which has a default value of “Item”) and in the Attributes Inspector, in the Identifier option, choose Add. This will change the button to the add symbol (+).

Bar Button Item

Bar Button Item

Select the Table View Controller, press control button and drag to View Controller like image below. We added a segue. Name it MySegue in Show the Attributes Inspector > Identifier.

Next tutorial, part 2 here http://intellij.my/2016/09/20/building-a-to-do-list-ios-mobile-app-part-2/

Guideline upload APK file into Google Play from A – Z

Open up your Android Studio. Go to menu, choose Generate Signed APK and click Next.

Generate Signed APK

Generate Signed APK

 

Generate Signed APK

Generate Signed APK

Click Create new.

Generate Signed APK

Generate Signed APK

Enter all the details (all fields are mandatory) below and click Ok.

New Key Store.

New Key Store.

Enter the following details and click Next.

Generate Signed APK

Generate Signed APK

Enter Master Password and click Ok.

Enter Master Password

Enter Master Password

Click Finish.

Generate Signed APK

Generate Signed APK

Open your browser and enter this URL, https://play.google.com/apps/publish/ . (I assume you already have google play developer account). Click Add new application.

google play developer - all applications

google play developer – all applications

Enter Title and click Upload APK.

google play developer - APK

google play developer – APK

Click Upload new APK to Production.

google play developer - APK

google play developer – APK

Click Browse. Select ***.apk file and click Open.

google play developer - APK

google play developer – APK

Wait until it finish uploading.

google developer account - APK

google developer account – APK

Go to Store Listing and enter all details for store listing.

Mandatory

Title: <your_title>
Description: <your_description>

Scroll down.

google developer account - store listing

google developer account – store listing

Insert screenshots at least 2 screenshots. Maximum is 8 screenshots. JPEG or 24-bit PNG (no alpha). Min length for any side: 320px. Max length for any side: 3840px.

google developer account - store listing

google developer account – store listing

Insert your Hi-res icon and Feature Graphic. Your icon size must be 512px x 512px and Feature Graphic must be 1024px x 500px.

google developer account - store listing

google developer account – store listing

Select Application type, Category and Content rating in Categorization section. Then enter all details for Website, Email, Phone and Privacy Policy. Save draft.

google developer account - store listing

google developer account – store listing

Go to Content Rating. Click Continue.

google developer account - content rating

google developer account – content rating

Enter Email address and Confirm email address. Then select your app category. Select UTILITY, PRODUCTIVITY, COMMUNICATION, OR OTHER.

google developer account - content rating

google developer account – content rating

Answer all questionnaire and click Saved questionnaires. Then click Calculate rating.

google developer account - content rating

google developer account – content rating

Click Apply rating.

google developer account - content rating

google developer account – content rating

 

google developer account - content rating

google developer account – content rating

Go to Pricing & Distribution. Choose Free. Then Malaysia in country section. In CONTAINS ADS section, choose No, it has no ads. In CONSENT section, select Content guidelines and US export laws. Scroll up and click Save draft. Then click Publish app.

google developer account - pricing & distribution

google developer account – pricing & distribution

 

Building a To Do List Android Mobile App – Part 2

In the first part of the simple android mobile app (toDoList) tutorial series, you covered the basics of setting environment and user interface.

In this second and final part of the tutorial series, we’ll cover API integration for each activity classes.

We’ll start where we left off last tutorial, so open your project from last time, or go through the previous tutorial first. http://intellij.my/2016/08/11/building-a-to-do-list-android-mobile-app-part-1/

Create a new java class. Right click on my.intellij.androidtodolist package > New >Activity > Java Class.

Create a new java class.

Create a new java class.

Name it as App and click Ok.

Create New Class

Create New Class

Then replace with this code in App.java.

package my.intellij.androidtodolist;

public class App {

    public static final String URL_CREATE="http://demo.revivalx.com/todolist-api/create_task.php";
    public static final String URL_GET_ALL = "http://demo.revivalx.com/todolist-api/get_all_tasks.php";
    public static final String URL_GET_DETAIL = "http://demo.revivalx.com/todolist-api/get_task_details.php?taskId=";
    public static final String URL_UPDATE = "http://demo.revivalx.com/todolist-api/update_task.php?taskId=";
    public static final String URL_DELETE = "http://demo.revivalx.com/todolist-api/delete_task.php?taskId=";

    public static final String KEY_ID = "taskId";
    public static final String KEY_NAME = "name";
    public static final String KEY_DESCRIPTION = "description";

    public static final String TAG_JSON_ARRAY="tasks";
    public static final String TAG_JSON_DETAIL="task";
    public static final String TAG_ID = "taskId";
    public static final String TAG_NAME = "name";
    public static final String TAG_DESCRIPTION = "description";

    public static final String ID = "taskId";
}

Create another java class. Right click on my.intellij.androidtodolist package > New >Activity > Java Class name it as RequestHandler. After that replace with this code.

package my.intellij.androidtodolist;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;

public class RequestHandler {

    //Method to send httpPostRequest
    //This method is taking two arguments
    //First argument is the URL of the script to which we will send the request
    //Other is an HashMap with name value pairs containing the data to be send with the request
    public String sendPostRequest(String requestURL,
                                  HashMap<String, String> postDataParams) {
        URL url;

        //StringBuilder object to store the message retrieved from the server
        StringBuilder sb = new StringBuilder();
        try {
            //Initializing Url
            url = new URL(requestURL);

            //Creating an httmlurl connection
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            //Configuring connection properties
            conn.setReadTimeout(15000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("POST");
            conn.setDoInput(true);
            conn.setDoOutput(true);

            //Creating an output stream
            OutputStream os = conn.getOutputStream();

            //Writing parameters to the request
            //We are using a method getPostDataString which is defined below
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getPostDataString(postDataParams));

            writer.flush();
            writer.close();
            os.close();
            int responseCode = conn.getResponseCode();

            if (responseCode == HttpsURLConnection.HTTP_OK) {

                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                sb = new StringBuilder();
                String response;
                //Reading server response
                while ((response = br.readLine()) != null){
                    sb.append(response);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public String sendGetRequest(String requestURL){
        StringBuilder sb =new StringBuilder();
        try {
            URL url = new URL(requestURL);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));

            String s;
            while((s=bufferedReader.readLine())!=null){
                sb.append(s+"\n");
            }
        }catch(Exception e){
        }
        return sb.toString();
    }

    public String sendGetRequestParam(String requestURL, String id){
        StringBuilder sb =new StringBuilder();
        try {
            URL url = new URL(requestURL+id);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));

            String s;
            while((s=bufferedReader.readLine())!=null){
                sb.append(s+"\n");
            }
        }catch(Exception e){
        }
        return sb.toString();
    }

    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, String>entry : params.entrySet()) {
            if (first)
                first = false;
            else
                result.append("&");

            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        return result.toString();
    }
}

Open activity_list.xml in app > layout >activity_list.xml. Update activity_list.xml with this one.

<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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="my.intellij.androidtodolist.ListActivity">

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Create Task"
        android:id="@+id/btnCreate"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/lv_task"
        android:layout_below="@+id/btnCreate"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

ListActivity.java

package my.intellij.androidtodolist;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

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

import java.util.ArrayList;
import java.util.HashMap;

public class ListActivity extends AppCompatActivity implements ListView.OnItemClickListener {

    private ListView listView;

    private String JSON_STRING;

    private Button buttonAdd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list);
        listView = (ListView) findViewById(R.id.lv_task);
        listView.setOnItemClickListener(this);
        getJSON();

        buttonAdd = (Button) findViewById(R.id.btnCreate);
        buttonAdd.setOnClickListener(new View.OnClickListener() {

            public void onClick(View arg0) {

                Intent createActivity = new Intent(getApplicationContext(), CreateActivity.class);
                startActivity(createActivity);

            }
        });
    }


    private void showTask(){
        JSONObject jsonObject = null;
        ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
        try {
            jsonObject = new JSONObject(JSON_STRING);
            JSONArray result = jsonObject.getJSONArray(App.TAG_JSON_ARRAY);

            for(int i = 0; i<result.length(); i++){
                JSONObject jo = result.getJSONObject(i);
                String id = jo.getString(App.TAG_ID);
                String name = jo.getString(App.TAG_NAME);

                HashMap<String,String> tasks = new HashMap<>();
                tasks.put(App.TAG_ID,id);
                tasks.put(App.TAG_NAME,name);
                list.add(tasks);
            }

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

        ListAdapter adapter = new SimpleAdapter(
                ListActivity.this, list, R.layout.list_item,
                new String[]{App.TAG_NAME},
                new int[]{R.id.name});

        listView.setAdapter(adapter);
    }

    private void getJSON(){
        class GetJSON extends AsyncTask<Void,Void,String> {

            ProgressDialog loading;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loading = ProgressDialog.show(ListActivity.this,"Fetching Data","Wait...",false,false);
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                loading.dismiss();
                JSON_STRING = s;
                showTask();
            }

            @Override
            protected String doInBackground(Void... params) {
                RequestHandler rh = new RequestHandler();
                String s = rh.sendGetRequest(App.URL_GET_ALL);
                return s;
            }
        }
        GetJSON gj = new GetJSON();
        gj.execute();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Intent intent = new Intent(this, UpdateActivity.class);
        HashMap<String,String> map =(HashMap)parent.getItemAtPosition(position);
        String taskId = map.get(App.TAG_ID).toString();
        intent.putExtra(App.ID,taskId);
        startActivity(intent);
    }
}

CreateActivity.java

package my.intellij.androidtodolist;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.util.HashMap;

public class CreateActivity extends AppCompatActivity implements View.OnClickListener{

    //Defining views
    private EditText editTextName;
    private EditText editTextDesription;

    private Button buttonAdd;
    private Button buttonView;

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

        //Initializing views
        editTextName = (EditText) findViewById(R.id.txtName);
        editTextDesription = (EditText) findViewById(R.id.txtDescription);

        buttonAdd = (Button) findViewById(R.id.btnCreate);
        buttonView = (Button) findViewById(R.id.btnBack);

        //Setting listeners to button
        buttonAdd.setOnClickListener(this);
        buttonView.setOnClickListener(this);
    }


    //Adding a task
    private void addTask(){

        final String name = editTextName.getText().toString().trim();
        final String description = editTextDesription.getText().toString().trim();

        class AddTask extends AsyncTask<Void,Void,String> {

            ProgressDialog loading;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loading = ProgressDialog.show(CreateActivity.this,"Adding...","Wait...",false,false);
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                loading.dismiss();
                Toast.makeText(CreateActivity.this,s,Toast.LENGTH_LONG).show();
            }

            @Override
            protected String doInBackground(Void... v) {
                HashMap<String,String> params = new HashMap<>();
                params.put(App.KEY_NAME,name);
                params.put(App.KEY_DESCRIPTION,description);

                RequestHandler rh = new RequestHandler();
                String res = rh.sendPostRequest(App.URL_CREATE, params);
                return res;
            }
        }

        AddTask ae = new AddTask();
        ae.execute();
    }

    @Override
    public void onClick(View v) {
        if(v == buttonAdd){
            addTask();
            startActivity(new Intent(CreateActivity.this,ListActivity.class));
        }

        if(v == buttonView){
            startActivity(new Intent(this,ListActivity.class));
        }
    }
}

Open activity_update.xml in app > layout >activity_update.xml. Update activity_update.xml with this one.

<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" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="my.intellij.androidtodolist.UpdateActivity">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtName"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:hint="Name"/>

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/txtDescription"
        android:layout_below="@+id/txtName"
        android:layout_centerHorizontal="true"
        android:hint="Description"/>

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Update Task"
        android:id="@+id/btnUpdate"
        android:layout_below="@+id/txtDescription"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Delete Task"
        android:id="@+id/btnDelete"
        android:layout_below="@+id/btnUpdate"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Back"
        android:id="@+id/btnBack"
        android:layout_below="@+id/btnDelete"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

UpdateActivity.java

package my.intellij.androidtodolist;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

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

import java.util.HashMap;

public class UpdateActivity extends AppCompatActivity implements View.OnClickListener {

    private EditText editTextName;
    private EditText editTextDescription;

    private Button buttonUpdate;
    private Button buttonDelete;
    private Button buttonView;

    private String id;

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

        Intent intent = getIntent();

        id = getIntent().getExtras().getString(App.ID);

        editTextName = (EditText) findViewById(R.id.txtName);
        editTextDescription = (EditText) findViewById(R.id.txtDescription);

        buttonUpdate = (Button) findViewById(R.id.btnUpdate);
        buttonDelete = (Button) findViewById(R.id.btnDelete);
        buttonView = (Button) findViewById(R.id.btnBack);

        buttonUpdate.setOnClickListener(this);
        buttonDelete.setOnClickListener(this);
        buttonView.setOnClickListener(this);

        getTask();
    }

    private void getTask(){
        class GetTask extends AsyncTask<Void,Void,String> {
            ProgressDialog loading;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loading = ProgressDialog.show(UpdateActivity.this,"Fetching...","Wait...",false,false);
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                loading.dismiss();
                showTask(s);
            }

            @Override
            protected String doInBackground(Void... params) {
                RequestHandler rh = new RequestHandler();
                String s = rh.sendGetRequestParam(App.URL_GET_DETAIL,id);
                return s;
            }
        }
        GetTask gt = new GetTask();
        gt.execute();
    }

    private void showTask(String json){
        try {
            JSONObject jsonObject = new JSONObject(json);
            JSONArray result = jsonObject.getJSONArray(App.TAG_JSON_DETAIL);
            JSONObject c = result.getJSONObject(0);
            String name = c.getString(App.TAG_NAME);
            String description = c.getString(App.TAG_DESCRIPTION);

            editTextName.setText(name);
            editTextDescription.setText(description);

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


    private void updateTask(){
        final String name = editTextName.getText().toString().trim();
        final String description = editTextDescription.getText().toString().trim();

        class UpdateTask extends AsyncTask<Void,Void,String>{
            ProgressDialog loading;
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loading = ProgressDialog.show(UpdateActivity.this,"Updating...","Wait...",false,false);
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                loading.dismiss();
                Toast.makeText(UpdateActivity.this,s,Toast.LENGTH_LONG).show();
            }

            @Override
            protected String doInBackground(Void... params) {
                HashMap<String,String> hashMap = new HashMap<>();
                hashMap.put(App.KEY_ID,id);
                hashMap.put(App.KEY_NAME,name);
                hashMap.put(App.KEY_DESCRIPTION,description);

                RequestHandler rh = new RequestHandler();

                String s = rh.sendPostRequest(App.URL_UPDATE,hashMap);

                return s;
            }
        }

        UpdateTask ut = new UpdateTask();
        ut.execute();
    }

    private void deleteTask(){
        class DeleteTask extends AsyncTask<Void,Void,String> {
            ProgressDialog loading;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                loading = ProgressDialog.show(UpdateActivity.this, "Updating...", "Wait...", false, false);
            }

            @Override
            protected void onPostExecute(String s) {
                super.onPostExecute(s);
                loading.dismiss();
                Toast.makeText(UpdateActivity.this, s, Toast.LENGTH_LONG).show();
            }

            @Override
            protected String doInBackground(Void... params) {
                RequestHandler rh = new RequestHandler();
                String s = rh.sendGetRequestParam(App.URL_DELETE, id);
                return s;
            }
        }

        DeleteTask dt = new DeleteTask();
        dt.execute();
    }

    private void confirmDeleteTask(){
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setMessage("Are you sure you want to delete this task?");

        alertDialogBuilder.setPositiveButton("Yes",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        deleteTask();
                        startActivity(new Intent(UpdateActivity.this,ListActivity.class));
                    }
                });

        alertDialogBuilder.setNegativeButton("No",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {

                    }
                });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();
    }

    @Override
    public void onClick(View v) {
        if(v == buttonUpdate){
            updateTask();
        }

        if(v == buttonDelete){
            confirmDeleteTask();
        }

        if(v == buttonView){
            startActivity(new Intent(this,ListActivity.class));
        }
    }
}

Now try running your application.