-
In my previous article Android Login and Registration Screen Design i explained designing the login and registration interfaces, but it has no functionality. In this tutorial i am explaining how to build complete login and registration system in android using PHP, MySQL and SQLite. Also this tutorial covers how to build simple API using PHP and MySQL.
Prerequisites
This tutorial is combination of some of my previous tutorials. I hope you covered these tutorials before.
Android making HTTP Requests
Android JSON Parsing Tutorial
Android SQLite Database Tutorial
Android Login and Registration Screen DesignAPI (Application Programming Interface)
⇒ Accepting requests by GET/POST methods
⇒ Interact with PHP classes to get data from database or store in database
⇒ Finally will give output in JSON format1. Creating MySQL Database and Tables
As I am writing API in PHP I selected MySql database to maintain users and other related information. Open your mysql console or phpmyadmin and run following query to create database and users table.create database android_api /** Creating Database **/
use android_api /** Selecting Database **/
create table users(
uid int(11) primary key auto_increment,
unique_id varchar(23) not null unique,
name varchar(50) not null,
email varchar(100) not null unique,
encrypted_password varchar(80) not null,
salt varchar(10) not null,
created_at datetime,
updated_at datetime null
); /** Creating Users Table **/2. Building PHP API Classes
To make it minimum i tried to use less number of php files. Following are the files are required to build API in php. You can find description of each file in the below image.config.php – This file contains constant variables to connect to database.
<?php
/**
* Database config variables
*/
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "");
define("DB_DATABASE", "android_api");
?>
DB_Connect.php – This file is used to connect or disconnect to database.<?php
class DB_Connect {
// constructor
function __construct() {
}// destructor
function __destruct() {
// $this->close();
}// Connecting to database
public function connect() {
require_once 'config.php';
// connecting to mysql
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
// selecting database
mysql_select_db(DB_DATABASE);// return database handler
return $con;
}// Closing database connection
public function close() {
mysql_close();
}}
?>
DB_Functions.php – This file contains functions to store user in database, get user from database. You can also add methods like update user, delete user.
user unique id – I am generating unique user id in php using uniqid(”, true) function. Sample user id will be like 4f074eca601fb8.88015924
Encrypted Password – This password is stored using base64_encode method. Each password will need two columns to store in database. One is to store encrypted password and second column is to store salt used to encrypt the password.
<?php
class DB_Functions {
private $db;
//put your code here
// constructor
function __construct() {
require_once 'DB_Connect.php';
// connecting to database
$this->db = new DB_Connect();
$this->db->connect();
}// destructor
function __destruct() {
}/**
* Storing new user
* returns user details
*/
public function storeUser($name, $email, $password) {
$uuid = uniqid('', true);
$hash = $this->hashSSHA($password);
$encrypted_password = $hash["encrypted"]; // encrypted password
$salt = $hash["salt"]; // salt
$result = mysql_query("INSERT INTO users(unique_id, name, email, encrypted_password, salt, created_at) VALUES('$uuid', '$name', '$email', '$encrypted_password', '$salt', NOW())");
// check for successful store
if ($result) {
// get user details
$uid = mysql_insert_id(); // last inserted id
$result = mysql_query("SELECT * FROM users WHERE uid = $uid");
// return user details
return mysql_fetch_array($result);
} else {
return false;
}
}/**
* Get user by email and password
*/
public function getUserByEmailAndPassword($email, $password) {
$result = mysql_query("SELECT * FROM users WHERE email = '$email'") or die(mysql_error());
// check for result
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
$result = mysql_fetch_array($result);
$salt = $result['salt'];
$encrypted_password = $result['encrypted_password'];
$hash = $this->checkhashSSHA($salt, $password);
// check for password equality
if ($encrypted_password == $hash) {
// user authentication details are correct
return $result;
}
} else {
// user not found
return false;
}
}/**
* Check user is existed or not
*/
public function isUserExisted($email) {
$result = mysql_query("SELECT email from users WHERE email = '$email'");
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
// user existed
return true;
} else {
// user not existed
return false;
}
}/**
* Encrypting password
* @param password
* returns salt and encrypted password
*/
public function hashSSHA($password) {$salt = sha1(rand());
$salt = substr($salt, 0, 10);
$encrypted = base64_encode(sha1($password . $salt, true) . $salt);
$hash = array("salt" => $salt, "encrypted" => $encrypted);
return $hash;
}/**
* Decrypting password
* @param salt, password
* returns hash string
*/
public function checkhashSSHA($salt, $password) {$hash = base64_encode(sha1($password . $salt, true) . $salt);
return $hash;
}}
?>
index.php – This file plays role of accepting requests and giving response. This file accepts all GET and POST requests. On each request it will talk to database and will give appropriate response in JSON format.<?php
/**
* File to handle all API requests
* Accepts GET and POST
*
* Each request will be identified by TAG
* Response will be JSON data/**
* check for POST request
*/
if (isset($_POST['tag']) && $_POST['tag'] != '') {
// get tag
$tag = $_POST['tag'];// include db handler
require_once 'include/DB_Functions.php';
$db = new DB_Functions();// response Array
$response = array("tag" => $tag, "success" => 0, "error" => 0);// check for tag type
if ($tag == 'login') {
// Request type is check Login
$email = $_POST['email'];
$password = $_POST['password'];// check for user
$user = $db->getUserByEmailAndPassword($email, $password);
if ($user != false) {
// user found
// echo json with success = 1
$response["success"] = 1;
$response["uid"] = $user["unique_id"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["created_at"] = $user["created_at"];
$response["user"]["updated_at"] = $user["updated_at"];
echo json_encode($response);
} else {
// user not found
// echo json with error = 1
$response["error"] = 1;
$response["error_msg"] = "Incorrect email or password!";
echo json_encode($response);
}
} else if ($tag == 'register') {
// Request type is Register new user
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];// check if user is already existed
if ($db->isUserExisted($email)) {
// user is already existed - error response
$response["error"] = 2;
$response["error_msg"] = "User already existed";
echo json_encode($response);
} else {
// store user
$user = $db->storeUser($name, $email, $password);
if ($user) {
// user stored successfully
$response["success"] = 1;
$response["uid"] = $user["unique_id"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["created_at"] = $user["created_at"];
$response["user"]["updated_at"] = $user["updated_at"];
echo json_encode($response);
} else {
// user failed to store
$response["error"] = 1;
$response["error_msg"] = "Error occured in Registartion";
echo json_encode($response);
}
}
} else {
echo "Invalid Request";
}
} else {
echo "Access Denied";
}
?>
Types of API JSON Responses
The following are the different types of JSON responses generated by API.
Registration Success Response – Success Code = 1 (User Successfully Stored){
"tag": "register",
"success": 1,
"error": 0,
"uid": "4f074ca1e3df49.06340261",
"user": {
"name": "Ravi Tamada",
"email": "ravi8x@gmail.com",
"created_at": "2012-01-07 01:03:53",
"updated_at": null
}
}
Registration Error Response – Error Code = 1 (Error in storing){
"tag": "register",
"success": 0,
"error": 1,
"error_msg": "Error occured in Registartion"
}
Registration Error Response – Error Code = 2 (User Already Existed){
"tag": "register",
"success": 0,
"error": 2,
"error_msg": "User already existed"
}
Login Success Response – Success Code = 1 (User Logged in){
"tag": "login",
"success": 1,
"error": 0,
"uid": "4f074eca601fb8.88015924",
"user": {
"name": "Ravi Tamada",
"email": "ravi8x@gmail.com",
"created_at": "2012-01-07 01:03:53",
"updated_at": null
}
}
Login Error Response – Error Code = 1 (Login Error – Incorrect username/password){
"tag": "login",
"success": 0,
"error": 1,
"error_msg": "Incorrect email or password!"
}
Here it completes the API part and start the Android Project.3. Starting Android Project
Until now we wrote server side programming to build simple api. Next thing is build android app to interact with the API. In this project i am coding simple app which will have three screens Login Screen, Registration Screen and a welcome Dashboard Screen. So let’s get started by creating new project in you Eclipse IDE.1. Create a new project by going to File ⇒ New Android Project. Fill all the details and name your activity as DashboardActivity.
2. Next step is to create a new package to store all our library files. Right Click on ⇒ src ⇒ New ⇒ Package and name it as library.JSON Parser Class
3. Next we need parser class to parse api response JSON. So create a new class in your library package name it as JSONParser.java and fill it with following code.JSONParser.java
package com.example.androidhive.library;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;import android.util.Log;
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";// constructor
public JSONParser() {}
public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}// return JSON String
return jObj;}
}
SQLite Database Handler Class
4. In the application to store user information i am using SQLite Database. So create new class in you library package folder and name it as DatabaseHandler.java and fill the class with following code. This class file has functions to handle database operations like storing user and getting user.DatabaseHandler.java
package com.example.androidhive.library;import java.util.HashMap;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;// Database Name
private static final String DATABASE_NAME = "android_api";// Login table name
private static final String TABLE_LOGIN = "login";// Login Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_EMAIL = "email";
private static final String KEY_UID = "uid";
private static final String KEY_CREATED_AT = "created_at";public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_LOGIN + "("
+ KEY_ID + " INTEGER PRIMARY KEY,"
+ KEY_NAME + " TEXT,"
+ KEY_EMAIL + " TEXT UNIQUE,"
+ KEY_UID + " TEXT,"
+ KEY_CREATED_AT + " TEXT" + ")";
db.execSQL(CREATE_LOGIN_TABLE);
}// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOGIN);// Create tables again
onCreate(db);
}/**
* Storing user details in database
* */
public void addUser(String name, String email, String uid, String created_at) {
SQLiteDatabase db = this.getWritableDatabase();ContentValues values = new ContentValues();
values.put(KEY_NAME, name); // Name
values.put(KEY_EMAIL, email); // Email
values.put(KEY_UID, uid); // Email
values.put(KEY_CREATED_AT, created_at); // Created At// Inserting Row
db.insert(TABLE_LOGIN, null, values);
db.close(); // Closing database connection
}
/**
* Getting user data from database
* */
public HashMap<String, String> getUserDetails(){
HashMap<String,String> user = new HashMap<String,String>();
String selectQuery = "SELECT * FROM " + TABLE_LOGIN;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// Move to first row
cursor.moveToFirst();
if(cursor.getCount() > 0){
user.put("name", cursor.getString(1));
user.put("email", cursor.getString(2));
user.put("uid", cursor.getString(3));
user.put("created_at", cursor.getString(4));
}
cursor.close();
db.close();
// return user
return user;
}/**
* Getting user login status
* return true if rows are there in table
* */
public int getRowCount() {
String countQuery = "SELECT * FROM " + TABLE_LOGIN;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int rowCount = cursor.getCount();
db.close();
cursor.close();
// return row count
return rowCount;
}
/**
* Re crate database
* Delete all tables and create them again
* */
public void resetTables(){
SQLiteDatabase db = this.getWritableDatabase();
// Delete All Rows
db.delete(TABLE_LOGIN, null, null);
db.close();
}}
User Functions Class
5. Create a new class file under library package and name it as UserFunctions.java. This class will have functions to handle all user events like
loginUser()
registerUser()
getLoginStatus()
logoutUser().In this class all the functions will interact with JSONParser, DatabaseHandler classes. I am testing API in localhost using xampp software. Normally localhost will run on port http://127.0.0.1 or http://localhost/. In AVD to connect to localhost you need to use url http://10.0.2.2/ instead of http://localhost/. If you want deploy your api on website the use the url http://yoursite.com/api/
UserFunctions.java
package com.example.androidhive.library;import java.util.ArrayList;
import java.util.List;import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONObject;import android.content.Context;
public class UserFunctions {
private JSONParser jsonParser;
// Testing in localhost using wamp or xampp
// use http://10.0.2.2/ to connect to your localhost ie http://localhost/
private static String loginURL = "http://10.0.2.2/ah_login_api/";
private static String registerURL = "http://10.0.2.2/ah_login_api/";
private static String login_tag = "login";
private static String register_tag = "register";
// constructor
public UserFunctions(){
jsonParser = new JSONParser();
}
/**
* function make Login Request
* @param email
* @param password
* */
public JSONObject loginUser(String email, String password){
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", login_tag));
params.add(new BasicNameValuePair("email", email));
params.add(new BasicNameValuePair("password", password));
JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);
// return json
// Log.e("JSON", json.toString());
return json;
}/**
* function make Login Request
* @param name
* @param email
* @param password
* */
public JSONObject registerUser(String name, String email, String password){
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", register_tag));
params.add(new BasicNameValuePair("name", name));
params.add(new BasicNameValuePair("email", email));
params.add(new BasicNameValuePair("password", password));
// getting JSON Object
JSONObject json = jsonParser.getJSONFromUrl(registerURL, params);
// return json
return json;
}
/**
* Function get Login status
* */
public boolean isUserLoggedIn(Context context){
DatabaseHandler db = new DatabaseHandler(context);
int count = db.getRowCount();
if(count > 0){
// user logged in
return true;
}
return false;
}
/**
* Function to logout user
* Reset Database
* */
public boolean logoutUser(Context context){
DatabaseHandler db = new DatabaseHandler(context);
db.resetTables();
return true;
}
}
Designing the Screens
6. Until now we have developed the library classes needed in this application. Next thing is build screens. We need three screens Login Screen, Registration Screen and Dashboard Screen.
Create 3 xml files under res ⇒ layout folder and name them as login.xml, register.xml and dashboard.xmllogin.xml – login screen design layout
login.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#3b3b3b" ><LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dip" >
<!-- View Title Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:text="LOGIN"
android:textSize="25dip"
android:textStyle="bold" />
<!-- Email Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Email" />
<!-- Email TextField -->
<EditText
android:id="@+id/loginEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- Password Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:text="Password" />
<!-- Password TextField -->
<EditText
android:id="@+id/loginPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="true" />
<!-- Error message -->
<TextView android:id="@+id/login_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#e30000"
android:padding="10dip"
android:textStyle="bold"/><!-- Login Button -->
<Button
android:id="@+id/btnLogin"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:text="Login" /><!-- Link to Registration Screen -->
<Button
android:id="@+id/btnLinkToRegisterScreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dip"
android:background="@null"
android:text="I don't have account. Register Me!"
android:textColor="#21dbd4"
android:textStyle="bold" />
</LinearLayout></ScrollView>
register.xml – registration screen design layout
register.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#3b3b3b" ><LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="10dip" >
<!-- View Title Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:text="REGISTER"
android:textSize="25dip"
android:textStyle="bold" />
<!-- Name Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Full Name" />
<!-- Name TextField -->
<EditText
android:id="@+id/registerName"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- Email Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Email" />
<!-- Email TextField -->
<EditText
android:id="@+id/registerEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<!-- Password Label -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:text="Password" />
<!-- Password TextField -->
<EditText
android:id="@+id/registerPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:password="true" />
<!-- Error message -->
<TextView android:id="@+id/register_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#e30000"
android:padding="10dip"
android:textStyle="bold"/><!-- Login Button -->
<Button
android:id="@+id/btnRegister"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:text="Register" /><!-- Link to Login Screen -->
<Button
android:id="@+id/btnLinkToLoginScreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dip"
android:background="@null"
android:text="Already registred. Login Me!"
android:textColor="#21dbd4"
android:textStyle="bold" />
</LinearLayout></ScrollView>
dashboard.xml – dashboard screen design layout
dashboard.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#3b3b3b">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="WELCOME"
android:textSize="40dip"
android:gravity="center"
android:layout_marginTop="20dip"/>
<Button android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Logout Me"
android:textSize="20dip"
android:textColor="#21dbd4"
android:textStyle="bold"
android:id="@+id/btnLogout"
android:layout_marginTop="80dip"
android:background="@null"/></LinearLayout>
Switching between Activites
7. Now the designing part of the app is done next thing is to create activities for each layout and write functionality to achieve login and registration process.
Create new activities LoginActivity.java and RegisterActivity.java and fill them with respective code below.LoginActivity.java – Activity to handle login event
LoginActivity.java
package com.example.androidhive;import java.util.HashMap;
import org.json.JSONException;
import org.json.JSONObject;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;import com.example.androidhive.library.DatabaseHandler;
import com.example.androidhive.library.UserFunctions;public class LoginActivity extends Activity {
Button btnLogin;
Button btnLinkToRegister;
EditText inputEmail;
EditText inputPassword;
TextView loginErrorMsg;// JSON Response node names
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);// Importing all assets like buttons, text fields
inputEmail = (EditText) findViewById(R.id.loginEmail);
inputPassword = (EditText) findViewById(R.id.loginPassword);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLinkToRegister = (Button) findViewById(R.id.btnLinkToRegisterScreen);
loginErrorMsg = (TextView) findViewById(R.id.login_error);// Login button Click Event
btnLogin.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.loginUser(email, password);// check for login response
try {
if (json.getString(KEY_SUCCESS) != null) {
loginErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully logged in
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Login Screen
finish();
}else{
// Error in login
loginErrorMsg.setText("Incorrect username/password");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});// Link to Register Screen
btnLinkToRegister.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
RegisterActivity.class);
startActivity(i);
finish();
}
});
}
}
RegisterActivity.java – Activity to handle registration eventLoginActivity.java
package com.example.androidhive;import org.json.JSONException;
import org.json.JSONObject;import com.example.androidhive.library.DatabaseHandler;
import com.example.androidhive.library.UserFunctions;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;public class RegisterActivity extends Activity {
Button btnRegister;
Button btnLinkToLogin;
EditText inputFullName;
EditText inputEmail;
EditText inputPassword;
TextView registerErrorMsg;
// JSON Response node names
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);// Importing all assets like buttons, text fields
inputFullName = (EditText) findViewById(R.id.registerName);
inputEmail = (EditText) findViewById(R.id.registerEmail);
inputPassword = (EditText) findViewById(R.id.registerPassword);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
registerErrorMsg = (TextView) findViewById(R.id.register_error);
// Register Button Click eventbtnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.registerUser(name, email, password);
// check for login response
try {
if (json.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully registred
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Registration Screen
finish();
}else{
// Error in registration
registerErrorMsg.setText("Error occured in registration");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});// Link to Login Screen
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
// Close Registration View
finish();
}
});
}
}
DashboardActivity.java – Activity to handle dashboard eventLoginActivity.java
package com.example.androidhive;import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;import com.example.androidhive.library.UserFunctions;
public class DashboardActivity extends Activity {
UserFunctions userFunctions;
Button btnLogout;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* Dashboard Screen for the application
* */
// Check login status in database
userFunctions = new UserFunctions();
if(userFunctions.isUserLoggedIn(getApplicationContext())){
// user already logged in show databoard
setContentView(R.layout.dashboard);
btnLogout = (Button) findViewById(R.id.btnLogout);
btnLogout.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
userFunctions.logoutUser(getApplicationContext());
Intent login = new Intent(getApplicationContext(), LoginActivity.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
// Closing dashboard screen
finish();
}
});
}else{
// user is not logged in show login screen
Intent login = new Intent(getApplicationContext(), LoginActivity.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
// Closing dashboard screen
finish();
}
}
}
Finally Updating AndroidManifest.xml
Don’t forget to update you AndroidManifest.xml file. Change following modifications
⇒ Add Internet Persmissions
⇒ Add Entries of each ActivityAndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidhive"
android:versionCode="1"
android:versionName="1.0" ><uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".DashboardActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Login Activity -->
<activity
android:label="Login Account"
android:name=".LoginActivity"></activity><!-- Register Activity -->
<activity
android:label="Register New Account"
android:name=".RegisterActivity"></activity>
</application>
<!-- Allow to connect with internet -->
<uses-permission android:name="android.permission.INTERNET" /></manifest>
8. Make sure that you have the files placed as in the following imageRun your project by right clicking on your project folder ⇒ Run As ⇒ 1 Android Application.
-
The Android platform provides libraries you can use to stream media files, such as remote videos, presenting them for playback in your apps. In this tutorial, we will stream a video file, displaying it using the VideoView component together with a MediaController object to let the user control playback.
We will also briefly run through the process of presenting the video using the MediaPlayer class. If you've completed the series on creating a music player for Android, you could use what you learn in this tutorial to further enhance it. You should be able to complete this tutorial if you have developed at least a few Android apps already.
1. Create a New App
Step 1
You can use the code in this tutorial to enhance an existing app you are working on or you can create a new app now in Eclipse or Android Studio. Create a new Android project, give it a name of your choice, configure the details, and give it an initial main Activity class and layout.Step 2
Let's first configure the project's manifest for streaming media. Open the manifest file of your project and switch to XML editing in your IDE. For streaming media, you need internet access, so add the following permission inside the manifest element:1
<uses-permission android:name="android.permission.INTERNET" />
2. Add VideoViewStep 1
The Android platform provides the VideoView class in which you can play video files. Let's add one to the main layout file:<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="#000000"
tools:context=".MainActivity" ><VideoView
android:id="@+id/myVideo"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true" />
</RelativeLayout>
Alter the parent layout to suit your own app if necessary. We give the VideoView instance an id attribute so that we can refer to it later. You may need to adjust the other layout properties for your own design.Step 2
Now let's retrieve a reference to the VideoView instance in code. Open your app's main Activity class and add the following additional imports:import <span class="skimlinks-unlinked">android.net.Uri</span>;
import android.widget.MediaController;
import android.widget.VideoView;
Your Activity class should already contain the onCreate method in which the content view is set:@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
After the setContentView line, let's get a reference to the VideoView instance as follows, using the id we set in the XML layout:1
VideoView vidView = (VideoView)findViewById(R.id.myVideo);
3. Stream a Video FileStep 1
Now we can stream a video file to the app. Prepare the URI for the endpoint as follows:1
2
String vidAddress = "<span class="skimlinks-unlinked">https://archive.org/download/ksnn_compilation_master_the_internet/ksnn_compilation_master_the_internet_512kb.mp4</span>";
Uri vidUri = <span class="skimlinks-unlinked">Uri.parse(vidAddress</span>);
You will of course need to use the remote address for the video file you want to stream. The example here is a public domain video file hosted on the Internet Archive. We parse the address string as a URI so that we can pass it to the VideoView object:1
vidView.setVideoURI(vidUri);
Now you can simply start playback:1
<span class="skimlinks-unlinked">vidView.start</span>();
The Android operating system supports a range of video and media formats, with each device often supporting additional formats on top of this.As you can see in the Developer Guide, video file formats supported include 3GP, MP4, WEBM, and MKV, depending on the format used and on which platform level the user has installed.
Audio file formats you can expect built-in support for include MP3, MID, OGG, and WAV. You can stream media on Android over RTSP, HTTP, and HTTPS (from Android 3.1).
4. Add Playback Controls
Step 1
We've implemented video playback, but the user will expect and be accustomed to having control over it. Again, the Android platform provides resources for handling this using familiar interaction via the MediaController class.In your Activity class's onCreate method, before the line in which you call start on the VideoView, create an instance of the class:
1
MediaController vidControl = new MediaController(this);
Next, set it to use the VideoView instance as its anchor:1
vidControl.setAnchorView(vidView);
And finally, set it as the media controller for the VideoView object:1
vidView.setMediaController(vidControl);
When you run the app now, the user should be able to control playback of the streaming video, including fast forward and rewind buttons, a play/pause button, and a seek bar control.The seek bar control is accompanied by the length of the media file on the right and the current playback position on the left. As well as being able to tap along the seek bar to jump to a position in the file, the streaming status is indicated using the same type of display the user will be accustomed to from sites and apps like YouTube.
As you will see when you run the app, the default behavior is for the controls to disappear after a few moments, reappearing when the user touches the screen. You can configure the behavior of the MediaController object in various ways. See the series on creating a music player app for Android for an example of how to do this. You can also enhance media playback by implementing various listeners to configure your app's behavior.
5. Using MediaPlayer
Step 1
Before we finish, let's run through an alternative approach for streaming video using the MediaPlayer class, since we used it in the series on creating a music player. You can stream media, including video, to a MediaPlayer object using a surface view. For example, you could use the following layout:<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:background="#000000"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" ><SurfaceView
android:id="@+id/surfView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" /></RelativeLayout>
We will refer to the SurfaceView in the implementation of the Activity class.Step 2
In your Activity class, add the following interfaces:1
public class MainActivity extends Activity implements SurfaceHolder.Callback, OnPreparedListener
Your IDE should prompt you to add these unimplemented methods:@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}@Override
public void surfaceCreated(SurfaceHolder arg0) {
//setup
}@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}@Override
public void onPrepared(MediaPlayer mp) {
//start playback
}
We will add to the surfaceCreated and onPrepared methods.Step 3
To implement playback, add the following instance variables to the class:private MediaPlayer mediaPlayer;
private SurfaceHolder vidHolder;
private SurfaceView vidSurface;
String vidAddress = "<span class="skimlinks-unlinked">https://archive.org/download/ksnn_compilation_master_the_internet/ksnn_compilation_master_the_internet_512kb.mp4</span>";
In the Activity's onCreate method, you can then start to instantiate these variables using the SurfaceView object you added to the layout:vidSurface = (SurfaceView) findViewById(R.id.surfView);
vidHolder = vidSurface.getHolder();
vidHolder.addCallback(this);Advertisement
Step 4
In the surfaceCreated method, set up your media playback resources:try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(vidHolder);
mediaPlayer.setDataSource(vidAddress);
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch(Exception e){
e.printStackTrace();
}
Finally, in the onPrepared method, start playback:1
<span class="skimlinks-unlinked">mediaPlayer.start</span>();
Your video should now play in the MediaPlayer instance when you run the app.Conclusion
In this tutorial, we have outlined the basics of streaming video on Android using the VideoView and MediaPlayer classes. You could add lots of enhancements to the code we implemented here, for example, by building video or streaming media support into the music player app we created. You may also wish to check out associated resources for Android such as the YouTube Android Player API.
-
By integrating your Android apps with the Google Play Services, you can access Google services, such as Maps, Drive, and Google+. Once you have your apps set up to use these services, accessing them is typically straightforward. The setup process does require a few steps, but you only need to carry them out once. In this tutorial we will go through the process of integrating Google Play Services with Android apps.
Introduction
Throughout the tutorial, we will outline what you need to do to integrate apps with Play Services in both Eclipse and Android Studio. You will need access to the Google Developer Console and to the Keytool utility.
Once you are set up with Play Services, the development process itself will be determined by what you want your apps to do. The the setup procedure, however, remains the same. By using the client library to access platform services, your apps will benefit from automatic updates through the Play Store.
1. Install Play Services in your IDE
Step 1
Open your IDE and start the Android SDK Manager. In Eclipse, choose Window > Android > SDK Manager. In Android Studio, click the SDK Manager toolbar button. Scroll through the list, expand the Extras folder and select Google Play Services.Click to install the package and accept the license when you are prompted. If you are developing in Android Studio, you will also need to install the Google Repository.
Step 2
When you test apps in which you use the Google Play Services APIs, ideally, you should run them on physical devices. However, it is possible to test in the emulator. To do this, you will need to install the Google APIs Platform. You will find this inside the directory for any of the API levels 17 and up.Find the platform in your SDK Manager, install it, and accept the license. When you create an AVD (Android Virtual Device) to test an app using Google Play Services, choose Google APIs as the target.
Step 3
If you are developing in Eclipse, you will also need to copy the Play Services library into your workspace. First, browse to it on your computer using a file explorer. You will find it in the folder you downloaded your Android SDK into, at /extras/google/google_play_services/libproject/google-play-services_lib/.Copy it to a location on your computer that you use for Android development files. Once you have copied the library (you must copy it rather than using the version in the SDK directory), go back to Eclipse. Choose Import from the File menu. Expand the Android folder, select Existing Android Code Into Workspace, and click Next.
Click the Browse button and navigate to the location you copied the Play Services library into. Select the folder you copied and click Finish to import it. The package will appear in your Package Explorer.
2. Create an Android Project
Step 1
You can now start developing with the Play Services resources. Create a new Android project in your IDE. Once you have a project in your workspace, you need to reference the Play Services resources within it.In Android Studio, you will need to add a build rule to the build.gradle file in the module for your application project. In the dependencies section, use the following syntax:
compile '<span class="skimlinks-unlinked">com.google.android.gms:play-services:4.1.32</span>'
Make sure you use the number for the most recent version of Play Services. You will need to update this as the library is updated. Save the file and click the Sync Project with Gradle Files button.In Eclipse, select the project in your Package Explorer, right-click or select the Project menu, and choose Properties. Select the Android option on the left and click Add in the Library section.
Select the Google Play Services library from the pop-up window and click OK to add it. Click Apply and the OK.
Step 2
Whichever IDE you are using, you will need to add Play Services meta-data to your manifest file. Open the project's manifest file and add the meta-data element inside the application element:1
2
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
If you are using Proguard, you will need to create an exception. See the Developer Guide for more details. For an overview of the Google Play Services APIs, check out the Package Index.3. Connecting with Play Services in your Apps
Step 1
The processing steps you need to take within your application code will depend on what functionality you want to implement with Play Services. The following sections outline some general considerations and steps.Although updates are pushed through the Google Play Store, it is still advisable to check what version the user device has installed before you attempt to carry out any processing with Google Play Services.
See the Implementing GCM Client example code in the Developer Guide for an overview of how to implement these checks within an Activity class. The method call to look for is isGooglePlayServicesAvailable, which you can add to a helper method as in the following excerpt:
1
2
3
4
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
//...
}
You could call the method in onCreate, before attempting to create the GoogleAPIClient instance through which you access the Play Services resources, and within onResume. If the user device does not have the required resources installed, they will be prompted to do so through the Google Play Store.Step 2
After checking the level of support on the user device, you can create an instance of the GoogleAPIClient class to call on the Google Play resources. The following example code demonstrates this and could be included in onCreate:1
2
3
4
5
6
GoogleApiClient myClient = new GoogleApiClient.Builder(this)
.addApi(<span class="skimlinks-unlinked">Plus.API</span>)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
This would prepare your application for accessing Google+ services, as you can see from the Plus.API excerpt. The addScope line will vary depending on what your app does. This code also sets up callbacks for the connection process. Your class can implement the following interfaces:public class MainActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener
The class can then implement the onConnected and onConnectionSuspended callbacks for handling changes in connection to Play Services.To handle failures in connecting to Play Services, such as in cases where user sign-in is required, your class can also implement onConnectionFailed , for accessing various standard methods for resolving typical errors. Some of these methods will cause the onActivityResult method to execute when the user returns to the app, so you can reattempt to connect there.
In general, your Activity class should connect to Play Services in onStart and disconnect in onStop via the GoogleAPIClient class as in the following excerpt:
1
myClient.connect();
4. Using Play Services ResourcesStep 1
For certain Play Services, including Google+, you need to register for access. To do so, log into the Google APIs Console, click Create Project, and enter a name. After creating the project, you should be redirected to the project in the console.Select the APIs menu item, find Google+ API in the list, and click the button to enable it. The status should change to ON after accepting the license. Clicking the API listing will give you an overview of what you can do with it.
Step 2
Next, select Credentials and click Create New Client ID. Select the Installed application radio button, select Android as the type, and enter your app details. Now you need to use the Keytool resource to generate a SHA1 certificate.During development, you can use the debug keystore, entering the following code in a terminal:
1
keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v
You'll need to make sure this is the correct location for your debug keystore, alter the path if it isn't. When you execute this command, you'll be prompted for the password. Enter android for the debug keystore and the fingerprint should be output to the terminal.Copy the SHA1 line and paste it into the Signing certificate fingerprint box in the APIs Console. Enable deep linking if necessary and then click the button to create the ID. A section will appear entitled Client ID for Android Application. You do not actually need to use the ID in your app code, but you may wish to keep a copy of it for your own records.
Advertisement
Step 3
Before you can call on the Play Services APIs in your application code, you will need to add the appropriate permissions to your project's manifest file. The following examples demonstrate a few typical use cases, but you will need to choose the appropriate permissions for your own project:1
2
3
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
Your project should now be configured to call the Play Services APIs that you need. You will need to structure your Activity classes differently depending on what your apps do. Take a look at the Developer Guide for more information about this.Don't forget to check out the following guides to get started with some of the available Play Services:
Google+
Google Drive
Maps
Location
Games
WalletIf the Google services you wish to access are not part of the Play Services library, you can access them using Google's REST API.
Conclusion
There are a lot of possibilities with Google Play Services in Android apps. From gaming to location and mapping services, your apps can take advantage of the existing platform features within the context of your own user interfaces and functionality.
The setup process may seem a little laborious, but once you're set up, you can focus on bringing these services to your users.
We are Learncodz.
Posts
Comments
The Team
Blog Codz Author
Popular Codz Article
-
I rewrite this tutorial from forum.xda-developers.com : The users of Micromax A116 Canvas Hd can now update their handsets to Android 5.0 Lo...
-
Build Your Own URL Shortener With YOURLS
What You'll Be Creating In this tutorial, I'll show you how to install your own open source, PHP-based URL shortener, called YOU... -
Wifi Hacking – WEP – Kali Linux Aircrack-ng suite
Alright, this post is written assuming you have Kali Linux up and running on your computer. If not, here is a post on hacking with kali linu... -
Top 4 Affordable Android One Smartphones from Rs. 6000
If you’re looking for an affordable smartphone to buy this holiday season and aren’t too keen on a Windows Phone, look no further than the A... -
[MOD][4.1 4.2] Extend Phone Storage 1.5, 2.5GB A116 (Other MT6589 Devices on request)
READ EVERYTHING CAREFULLY I Will Not Responsible For Any Brick or Any Problem So Do It At Your Own Risk. This Will Extend your Device's ... -
want to build an chat application..(parse)
Introduction The Parse platform provides a complete backend solution for your mobile application. Our goal is to totally eliminate the nee... -
Distributing iOS Apps With iTunes Connect
Once you've developed your iOS or OS X app, it's time to submit it to Apple for release in the App Store. This process is done throu...
Portfolio
- 2015 at 02:00AM
- 2015 at 02:03AM
- 2015 at 02:07AM
- 2015 at 02:09AM
- 2015 at 03:51AM
- 2015 at 03:57AM
- 2015 at 04:03AM
- 2015 at 04:08AM
- 2015 at 06:38AM
- 2015 at 08:03PM
- 2015 at 08:09PM
- 2015 at 08:13PM
- 2015 at 08:18PM
- 2015 at 08:23PM
- 2015 at 08:32PM
- 2015 at 08:33PM
- 2015 at 08:42PM
- 2015 at 08:50PM
- 2015 at 09:08AM
- 2015 at 09:12AM
- 2015 at 09:20AM
- 2015 at 09:22AM
- 2015 at 09:25AM
- 2015 at 09:27PM
- 2015 at 09:28AM
- 2015 at 09:31PM
- 2015 at 09:34AM
- 2015 at 09:58AM
- 2015 at 10:31AM
- 2015 at 10:45AM
- 2015 at 10:46PM
- 2015 at 10:50AM
- 2015 at 10:57AM
- 2015 at 10:57PM
- 2015 at 10:58AM
- 2015 at 11:04PM
- 2015 at 11:07AM
- 2015 at 11:17AM
- 2015 at 11:20AM
- 2015 at 11:31AM
- 2015 at 11:32AM
- 2015 at 11:33AM
- 2015 at 11:39AM
- 2015 at 11:44AM
- 2015 at 11:45AM
- 2015 at 11:45PM
- 2015 at 11:46PM
- 2015 at 11:50PM
- 2015 at 11:51PM
- 2015 at 11:52AM
- 2015 at 11:57AM
- 2015 at 11:58PM
- 2015 at 12:02PM
- 2015 at 12:04AM
- 2015 at 12:08PM
- 3d maxx
- and
- Android
- android developer
- android developr
- android labels
- android sdk
- android studio
- android tutorial
- android tutorials
- apk
- apple
- application
- apps
- April 19
- April 20
- April 21
- April 22
- April 23
- April 24
- April 25
- At its simplest
- bac
- backtrack
- battery
- biotechnology is technology based on biology - biotechnology harnesses cellular and biomolecular processes to develop technologies and products that help improve our lives and the hea
- Blog
- blogger
- browser
- build an chat application
- C
- chrome app
- command prompt
- designing
- Developing App
- earn money
- games
- hack
- hack Facebook
- Hacking
- help
- How To
- htc
- IFTTT
- intel xdk
- Ios
- ios 8
- ios8
- ips 8
- Java
- Javascript
- lenovo
- mac
- Magento
- Mysql
- new launch
- nexus
- operating system
- OS
- phone
- Photoshop
- Php
- pivotal tracker
- Review
- Reviews
- roms
- root
- Ruby On Rails
- samsung
- sdk
- security
- swift
- Tech. News
- Tools:Tips
- tutorial
- Uncategorized
- unity
- update
- Visual Studio
- windows phone
- Wordpress
- wordpress tutorial