Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

Redesigning Facebook FeedView in Ionic and angular

Facebook feed view in angular.js and ionic

Making Time: Redesigning Concept Facebook Feed For Android with Ionic and angular.js


In UX design, few things are more intricate than time and personal time management — only a good arsenal of mobile design patterns and information architecture principles can save you. This is the story of redesigning the UX for a popular social networking app the Facebook Android app.

Before we get started  redesigning the news feed  we were already checked for what

Disclaimer: This app is not intended to be a fully-featured facebook news feed but rather I want to demonstrate how to implement the same UI/UX method in ionic applications.

This was a weekend project which we coded .
What we took as reference to build is the Android app for facebook



Create a new tab project in ionic
Ionic start facebook_feed tabs

Once the projects gets created move to project directory and  launch the application by providing the command.

Ionic serve


So,Let get Started!
Setting up and Creating a new Blank Project in Ionic:
Now let's create an app. From the terminal, go to your project folder.
Finally navigate to the project directory and add iOS and/or Android platforms to Ionic and test the app.
cd facebook_feed
ionic platform add ios/Android
ionic build ios/Android
ionic emulate ios/android

To complete the app we need to:

  1. Define the front end views

  2. Define controllers that provide data

  3. Define routes to tie the views to the controllers


Since we created a blank apps ,create a template folder and  Navigate to the folder www/templates from your application root directory. This folder contains template files that will be rendered for the app.

Creating Template Files
which we will use for  tabs and fetching and showing feed details  using json data.

A)Create new template/friends-details.html  file and paste the below code to it.
<ion-view title="{{friend.name}}">
<ion-content has-header="true" padding="true">
</ion-content>
</ion-view>

This file contains the html code for presenting the list of friends which we will fetch from friends object in your ionic applications.

Similarly create tab-account and tab-dashboard

Tab-account.html
<ion-view title="{{friend.name}}">
<ion-content has-header="true" padding="true">
</ion-content>
</ion-view>
Tab-dashboard.html
<ion-header-bar class="bar bar-stable title">
<h1 class="title">Dashboard</h1>
<div class="buttons">
<button class="button button-icon ion-android-search"
ng-click="vm.showFilterBar()"></button>
<button class="button button-icon ion-person-add"
ng-click="vm.showFilterBar()"></button>
</div>

</ion-header-bar>
Tab-discovery.html

<ion-header-bar class="bar bar-stable title">
<h1 class="title">News Feed</h1>
<div class="buttons">
<button class="button button-icon ion-android-search"
ng-click="vm.showFilterBar()"></button>
<button class="button button-icon ion-person-add"
ng-click="vm.showFilterBar()"></button>
</div>
</ion-header-bar>



Next ,create the tab-discovery.html template for facebook like feed in ionic

.The tab-discovery.html  has the function of pull-to-refresh functionality which will be used to refresh the feed list.

Steps to Attain feed view design:


1)Create the header bar with title(News Feed) which hold the search and chatlist feature






2)Create the tab view which holds the the different views of the tabs.



3) Creating the feed view with



4) Finally the bottom tab which will have three tabs to update status,Checkin etc.

<div class="tabs-striped tabs-top tabs-background-light tabs-color-positive-dark">
<div class="tabs">
<a class="tab-item active" href="#">
<i class="icon ion-card"></i>
Test
</a>
<a class="tab-item" href="#">
<i class="icon ion-person-stalker"></i>
Favorites
</a>
<a class="tab-item" href="#">
<i class="icon ion-chatbubbles"></i>
Settings
</a>
<a class="tab-item" href="#">
<i class="icon ion-earth"></i>
Settings
</a>
<a class="tab-item" href="#">
<i class="icon ion-navicon"></i>
Settings
</a>
</div>

<ion-content class="padding has-tabs-top" >
<ion-refresher
pulling-text="Pull to refresh..."
on-refresh="doRefresh()">
</ion-refresher>
<ion-list >

<ion-item class="discovery-item" ng-repeat="feed in feeds" type="item-text-wrap" >


<div class="item item-avatar">
<img class="head-img" ng-src="{{feed.profilePic}}">
<h2><b>{{feed.name}}</b></h2>
<p am-time-ago="{{feed.timeStamp}}"></p>
</div>

<div class="item item-body">
<p>
{{feed.status}}
</p>
<img class="feed-content-img" ng-src="{{feed.image}}">

<p>
<b><a href="#" class="subdued">1 likes</a>
<b><a href="#" class="subdued">5 Comments</a>
</p>
</div>

<div class="buttons-share">
<button class="button button-icon icon ion-thumbsup">Like</button>
<button class="button button-icon ion-chatbox">Comment</button>
<button class="button button-icon ion-reply-all">Share</button>
</div>

</ion-item>
</ion-list>
<ion-infinite-scroll
if="!noMoreItemsAvailable"
on-infinite="loadMore(10)"
icon="ion-loading-c"
distance="1%">
</ion-infinite-scroll>
</ion-content>
</ion-view>
Adding the templates and controller to index.html
Include the controller file and template file in the main index.hml to bind all the things at one.by creating three controller
Navigate to js folder and create three js files.controller.js -handling logic of the app
app.js-Defining the routers and controller mappingservice.js-Sending the request to API and updating with response.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>

<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">

<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->

<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ngCordova/dist/ng-cordova.min.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>

<!-- your app's js -->
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="app">

<ion-nav-view>
</ion-nav-view>
</body>
</html>



Here Comes the Controller!

Building the controller with angular.js that goes to the backend and does all the work

Navigate to js folder  and add the below code to it.
app.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])

.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})

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

// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider

// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})

// Each tab has its own nav history stack:

.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.discovery', {
url: '/discovery',
views: {
'tab-discovery': {
templateUrl: 'templates/tab-discovery.html',
controller: 'DiscoveryCtrl'
}
}
})
.state('tab.friends', {
url: '/friends',
views: {
'tab-friends': {
templateUrl: 'templates/tab-friends.html',
controller: 'FriendsCtrl'
}
}
})
.state('tab.friend-detail', {
url: '/friend/:friendId',
views: {
'tab-friends': {
templateUrl: 'templates/friend-detail.html',
controller: 'FriendDetailCtrl'
}
}
})

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

// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/discovery');

});

Creating the Controller.js which will be used which will be used to load the feed in increment whenever the feed reached to bottom a new record is viewed and generates a infinfte scroll view.
angular.module('starter.controllers', ["angularMoment"])

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

.controller('DiscoveryCtrl', function ($scope, Discovery, $http, $ionicLoading) {
$scope.feeds = [];
$scope.loadedFeeds = Discovery.all();
$scope.noMoreItemsAvailable = false;

$scope.loadMore = function (NumOfFeedToLoad) {
//NumOfFeedToLoad decide how many feed load per loadMore called
for(var i=0;i<NumOfFeedToLoad;i++){
var numOffeeds = $scope.feeds.length;
$scope.feeds.push($scope.loadedFeeds[numOffeeds]);
}

//Stop loadMore while no more data inside loadedFeeds
if ($scope.feeds.length == $scope.loadedFeeds) {
$scope.noMoreItemsAvailable = true;
}

$scope.$broadcast('scroll.infiniteScrollComplete');

}

$scope.showloading = function (durationtime) {

if (!durationtime) {

$ionicLoading.show({
template: 'Loading...',
noBackdrop: true
});
} else {

$ionicLoading.show({
template: 'Loading...',
noBackdrop: true,
duration: durationtime
});
}

};
$scope.hideloading = function () {
$ionicLoading.hide();
};
$scope.doRefresh = function () {
$scope.showloading()
$http.get('/new-items')
.success(function (newItems) {
$scope.feeds = newItems;
})
.finally(function () {
// Stop the ion-refresher from spinning
$scope.hideloading()
$scope.$broadcast('scroll.refreshComplete');
});
};
})
.controller('FriendsCtrl', function ($scope, Friends) {
$scope.friends = Friends.all();
})

.controller('FriendDetailCtrl', function ($scope, $stateParams, Friends) {
$scope.friend = Friends.get($stateParams.friendId);
})

.controller('AccountCtrl', function ($scope) {
});

Setting Up and Calling the API through services.js
angular.module('starter.services', [])

/**
* A simple example service that returns some data.
*/
.factory('Friends', function() {
// Might use a resource here that returns a JSON array


var friends = [
{ id: 0, name: 'Alexa' },
{ id: 1, name: 'Venkates Pillai' },
{ id: 2, name: 'vaibhav Kumar' },
{ id: 3, name: 'Ramesh singh' },
{ id: 4, name: 'Srinivas ' },
{ id: 4, name: 'Ramanujam' },
{ id: 4, name: 'Samavedam' }

];

return {
all: function() {
return friends;
},
get: function(friendId) {
// Simple index lookup
return friends[friendId];
}
}
})
.factory('Discovery',function(){
var feeds = [...
Run the Application:

Ionic_angular.js_facebooklike_feedview

Friends View



Implementing Android Push Notification using PHP,MYSQL and GCM-II

php_mysql_push_notification_android_gcm

In the last post we checked how to work with GCM on the client side.Now in this post we are going to post notification through PHP and MySql DB.


The Mysql DB will be used to store token ID generated from GCM..PHP will bind the Android and Mysql to send PHP notification to devices.


Part 1:Implementing push notification using GCM


lets get Started!


First we need to setup our Mysql DB to store token


Create a DB "gcmdb"


create database gcmdb;


Next we need to create table


Create table deviceinfo(tokenid varchar2(250) not null);


Next we need to create our php files, we are going to use PDOconnections


creating PDOConnections.php



<?php
$dbName = "gcmdb";
$user = "system";
$pwd = "1234";
$host = "localhost";
$cnn = new PDO('mysql:dbname='.$dbName.';host='.$host, $user, $pwd);

Fetching and Sending the request to GCM


Next we have to post request to server using gcm.php which will insert the token and retrieve it while sending notification.



prepare($query);
$stmt->bindParam(1, $token);
$stmt->execute();
echo("Insert success");
}
//Check exists token
function isExistToken($cnn, $token)
{
$query = "SELECT * FROM deviceinfo WHERE TOKENID = ?";
$stmt = $cnn->prepare($query);
$stmt->bindParam(1, $token);
$stmt->execute();
$rowcount = $stmt->rowCount();
return $rowcount;
}
?>

The Notification Page!Next creating the send notification page where we will send the notification messages to devices.


<?php
include("PDOConnection.php");
define('GOOGLE_API_KEY', 'AIzaSyCBV6kqW1sPsftrcnXeXqaJ8vZ2JbVQPyo');//Replace with your Key

$pushStatus = '0';;

if(isset($_POST['submit'])) {
$gcmRegIds = array();
$sql = "SELECT TOKENID FROM DEVICEINFO";
$result = $cnn->query($sql);
while($row = $result->fetch(PDO::FETCH_ASSOC))
{
array_push($gcmRegIds, $row["TOKENID"]);
}
$pushMessage = $_POST['message'];
if(isset($gcmRegIds) && isset($pushMessage)) {
$message = array('message' => $pushMessage);
$pushStatus = sendPushNotification($gcmRegIds, $message);
}
}

function sendPushNotification($registration_ids, $message) {
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registration_ids,
'data' => $message,
);
$headers = array(
'Authorization: key=' . GOOGLE_API_KEY,
'Content-Type: application/json'
);
// Open connection
$ch = curl_init();

// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
return $result;
}

?>
<html>
<head>
<title>GCM Server</title>
</head>
<body style="text-align:center;color:white">
<div style="background-color:#F2425A;height:100px;padding-top:15ppx;padding-bottom:15px;margin-top:-45px;width:100%">
<h1>AndroidXU</h1>
<h2 >Google Cloud Messaging (GCM) Server</h2>
</div>
<form method = 'POST' action = ''>
<div style="padding-top:10px">
<textarea rows = 6 name = "message" cols = 50 placeholder = 'Messages send to all device in database via GCM'></textarea>
</div>
<div style="margin-top:10px" >
<input type = 'submit' name="submit" value = 'Send Notification' style="background-color:#F2425A;color:#fff;padding:5px 5px 5px 5px;border:none">
</div>
<p>
<h3>
<?php
if('0' != $pushStatus)
{
$obj = json_decode($pushStatus);
if($obj != null)
{
echo("<div style='color:green'>");
echo("<p style='color:red'>Status:</p>");
echo("Success:".$obj->success);
echo("&nbsp;&nbspFailure:".$obj->failure);
echo("</div>");
}
else
{
echo("<div style='color:red'>".$pushStatus."</div>");
} }
?>
</h3>
</p>
</form>
</body>
</html>
One you hit the URL: http://localhost/gcm/gcm.php. You can see the below page.


GCM_push_notification


We need to send the request from our android code to PHP usng the token generated.

Finally Modifying the Java intent Service class

We are going to use the code which we used in previous post in part I

we are going to modify the GCMRegistrationIntentservice.java
if the token is already generated we will use shared preferances

package androidgreeve.android.com.gcmpushnotify;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.google.android.gms.iid.InstanceID;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* Created by venkatesh on 15-05-2016.
*/
public class GCMRegistrationIntentService extends IntentService {
//Assigning success and failure Messages
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
public static final String REGISTRATION_ERROR = "RegistrationError";
public static final String TAG = "GCMTOKEN";
public GCMRegistrationIntentService() {
super("");
}

@Override
protected void onHandleIntent(Intent intent) {
registerGCM();
}

private void registerGCM() {
SharedPreferences sharedPreferences = getSharedPreferences("GCM", Context.MODE_PRIVATE);//Define shared reference file name
SharedPreferences.Editor editor = sharedPreferences.edit();
Intent registrationComplete = null;
String token = null;
try {
InstanceID instanceID = InstanceID.getInstance(getApplicationContext());
token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.w("GCMRegIntentService", "token:" + token);
//notify to UI that registration complete success
registrationComplete = new Intent(REGISTRATION_SUCCESS);
registrationComplete.putExtra("token", token);

String oldToken = sharedPreferences.getString(TAG, "");//Return "" when error or key not exists
//Only request to save token when token is new
if(!"".equals(token) && !oldToken.equals(token)) {
saveTokenToServer(token);
//Save new token to shared reference

editor.putString(TAG, token);
editor.commit();
} else {
Log.w("GCMRegistrationService", "Old token");
}
} catch (Exception e) {
Log.w("GCMRegIntentService", "Registration error");
registrationComplete = new Intent(REGISTRATION_ERROR);
}
//Send broadcast
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}

private void saveTokenToServer(String token){
Map paramPost = new HashMap();
paramPost.put("action","add");
paramPost.put("tokenid", token);
try {
String msgResult = getStringResultFromService_POST("http://192.168.209.2/gcm/gcm.php", paramPost);
Log.w("ServiceResponseMsg", msgResult);
}catch (Exception e){
e.printStackTrace();
}
}
public String getStringResultFromService_POST(String serviceURL, Map<String, String> params) {
HttpURLConnection cnn = null;
String line = null;
URL url;
try{
url = new URL(serviceURL);
} catch (MalformedURLException e){
throw new IllegalArgumentException("URL invalid:"+serviceURL);
}
StringBuilder bodyBuilder = new StringBuilder();
Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
//Construct the post body using the parameter
while (iterator.hasNext()){
Map.Entry<String, String> param = iterator.next();
bodyBuilder.append(param.getKey()).append('=').append(param.getValue());
if(iterator.hasNext()){
bodyBuilder.append('&');
}
}
String body = bodyBuilder.toString(); //format same to arg1=val1&arg2=val2
Log.w("AccessService", "param:" + body);
byte[]bytes = body.getBytes();
try{
cnn = (HttpURLConnection)url.openConnection();
cnn.setDoOutput(true);
cnn.setUseCaches(false);
cnn.setFixedLengthStreamingMode(bytes.length);
cnn.setRequestMethod("POST");
cnn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
//Post the request
OutputStream outputStream = cnn.getOutputStream();
outputStream.write(bytes);
outputStream.close();

//Handle the response
int status = cnn.getResponseCode();
if(status!=200){
throw new IOException("Post fail with error code:" + status);
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(cnn.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
while ((line = bufferedReader.readLine())!=null){
stringBuilder.append(line+'\n');
}
return stringBuilder.toString();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}

check the logcat completely to identify flow,if you are facing difficulty try to uninstall app from device and run again.

If you are facing any issue feel free to comment below.

Like,Share and suggest if you want it to be covered  and happy Coding!

Mastering Hybrid apps with Ionic and Angular js






Getting Started with Ionic Framework

1)Introduction:

A)Ionic is open source framework used for developing mobile applications. It provides tools and services for building mobile UI with native look and feel. Ionic framework needs native wrapper to be able to run on mobile devices.

B)This tutorial is created for JavaScript developers that are new to mobile development. It provides simple, easy to understand explanations with useful working examples. We will go through most of the Ionic framework so you can also use this as a reference for your projects.

C)The ionic Framework provide a easy to and build Hybrid apps using  MVC model with angularjs and connect with real data super quick.


2)Prerequisites

Since Ionic is built on top of AngularJS and Apache Cordova you will need to have basic knowledge about these technologies. You also need to be familiar with HTML, CSS and JavaScript if you want to completely understand all the information provided.

Setting Up Ionic and Cordova requires Node.js


Step 1)Setting Up Node.js


Follow the link to download the Node.js for required platform from

Note:Dont Forget to include the bin package in environment variable.


Step 2)

Installing Ionic and cordova using Node package manager  (NPM)
Type the command:

npm install -g cordova ionic

Let the  dependencies download gets completed  and we are ready to begin developing our first app.


3)Developing a Basic Template

Ionic provides three type of basic template to start with


  • Tabs App:
  • Blank App:
  • Side menu App:


In your command window open the folder where you want to create your app and try one of the options mentioned below.

Tabs App:

If you want to use Ionic tabs template your app will be built with tab menu, header and couple of useful screens and functionalities. This is default Ionic template. Open your command window and choose where you want to create your app.
ionic start myApp tabs

Quick tip:
"How to configure cordova to android emulator :"
Now let's add Cordova project for android Platform and install basic cordova plugins. This step allows us to run the app on Android emulator or device.

ionic platform add android



Next let's build our first basic app. If you have building errors after running following command you probably didn't install android SDK and its dependencies.


ionic build android



The last step of the installation process is to run your app which will start the mobile device if connected or default emulator if there is no device connected. Android default emulator is slow so I suggest you to install Genymotion or some other popular Android emulator.


ionic run android



This will produce below result which is an Ionic Tabs App.


Full list of Ionic starter templates

Start with a blank Ionic template
$ ionic start appName blank

Start with an Ionic tabs template

$ ionic start appName tabs

Start with a side menu Ionic template

$ ionic start myApp sidemenu

Start with an Ionic maps template

$ ionic start myApp maps

Start with an Ionic push notification template
$ ionic start myApp push

Start with an Ionic analytics template

$ ionic start myApp analytics

Start with an Ionic salesforce template
$ ionic start myApp salesforce

Start with an app containing ionic.io services
$ ionic start myApp io

Start with an app containing Ionic deploy
$ ionic start myApp deploy

A test of different kinds of page navigation

$ ionic start myApp tests

A complex list starter template

$ ionic start myApp complex list

Note:You can view in the browser by hitting  the url http://192.168.0.119:8100/#/tab/dash
 $Ionic serve


What's Next ?

Ionic 2 is an evolutionary step from Ionic 1 that reduces the amount of code and polishes the user interface. The full catalogue of Ionic components on iOS and Android feel and look even more native than Ionic 1. Angular 2 brings huge performance increases and neat things like observables to make your app more dynamic and responsive.


Happy Coding!