Posted on

Android Push Notification using GCM

GCM Server

Welcome to the Android Push Notification using GCM tutorial.

Introduction: Many app developers still struggle to implement Android Push Notification in their apps/games.So what is actually a push notification.Push Notification are used by developers to inform user about new messages,events or any other thing which they can see without opening their app.

In this tutorial i am going to tell you how to use GCM (Google Cloud Messaging) to send push notification on Android device.You can use this code in your android app,games made with LibGDX,Cocos2d-x with little modification.This tutorial contains PHP,MySQL & JAVA code.

Step by Step sheet

  • Getting project id & project number from Google developers site.
  • Application Code
  • Server side code (PHP,MySQL)
  • Sending push notifications

Let’s get started!

Getting project id & project number from Google developers site.

Go to this site https://developers.google.com/mobile/add?platform=android (Make sure you are logged in your google account)

  • Fill app name – Push Testing
  • Fill package name – com.developerhouse.push
  • Click on “continue to” button
Google Project Console
Google Project Console

 

wait for few seconds it will take some time.
click on enable Google cloud messaging

Enable Cloud Messaging
Enable Cloud Messaging

Now the project has been created we have to go on this link https://console.developers.google.com/ to edit IP address from which we can make request to send push messages & to get the API Key & Project ID

Select project from drop down on top ,note down the Project ID & Project Number

Select Project From Console
Select Project From Console

Now Click on Credentials sub menu button under API & auth

you will see something like this, note down the API Key and click on it

Select Credentials in Project Console
Select Credentials in Project Console

 

This is a optional step to make your push notification secure by adding the ip address of your server

Add IP Address
Add IP Address

add ip address & click on save button

Application Code

We have to write the code for android application which will send the device id first time so that it can be save on our server
Create a application with the same package name which we have used while setting up GCM. Add google play services library in your project

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.developerhouse.push"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="21" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.google.android.gms.gcm.GcmReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.developerhouse.push"/>
</intent-filter>
</receiver>
<service
android:name="com.developerhouse.push.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="com.developerhouse.push.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<service
android:name="com.developerhouse.push.RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>

This class is used for registering the Token in our web server .First it will get the token then it will save on our web server.

RegistrationIntentService.java

 

package com.developerhouse.push;
import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegServicePush";
public RegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(Constants.GCM_SENDER_ID,
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
}
private void sendRegistrationToServer(String token) {MainActivity.newRegID=token;
WebServerRegistrationTask webServer=new WebServerRegistrationTask();
webServer.execute();
}
public class WebServerRegistrationTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(RegistrationIntentService.this);
URL url = null;
try {
url = new URL(Constants.WEB_SERVER_URL);
} catch (MalformedURLException e) {
e.printStackTrace();
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, "").apply();
}
Map<String, String> dataMap = new HashMap<String, String>();
dataMap.put("regID", MainActivity.newRegID);
StringBuilder postBody = new StringBuilder();
Iterator<Map.Entry<String, String>> iterator = dataMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String,String> param = (Entry<String,String>) iterator.next();
postBody.append(param.getKey()).append('=')
.append(param.getValue());
if (iterator.hasNext()) {
postBody.append('&');
}
}
String body = postBody.toString();
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
String response="";
InputStream is = null;
try {
is = conn.getInputStream();
int ch;
StringBuffer sb = new StringBuffer();
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
response=sb.toString();
} catch (IOException e) {
throw e;
} finally {
if (is != null) {
is.close();
}
}
int status = conn.getResponseCode();
if (status == 200) {
if(response.equals("1")){
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, MainActivity.newRegID).apply();
Intent registrationComplete = new Intent(Constants.SERVER_SUCCESS);
LocalBroadcastManager.getInstance(RegistrationIntentService.this).sendBroadcast(registrationComplete);
}
} else {
throw new IOException("Request failed with error code "
+ status);
}
} catch (ProtocolException pe) {
pe.printStackTrace();
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, "").apply();
} catch (IOException io) {
io.printStackTrace();
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, "").apply();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return null;
}
}
}

MyInstanceIDListenerService.java

package com.developerhouse.push;
import android.content.Intent;
import com.google.android.gms.iid.InstanceIDListenerService;
public class MyInstanceIDListenerService extends InstanceIDListenerService {
@Override
public void onTokenRefresh() {
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}

MyGcmListenerService.java

package com.developerhouse.push;
import com.google.android.gms.gcm.GcmListenerService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
public class MyGcmListenerService extends GcmListenerService {
public static final int MESSAGE_NOTIFICATION_ID = 435345;
private NotificationManager mNotificationManager;
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
createNotification( message);
}
// Creates notification based on title and body received
private void createNotification( String body) {
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
long[] pattern = {500};
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Push Notification Test").setVibrate(pattern)
.setStyle(new NotificationCompat.BigTextStyle().bigText(body))
.setContentText(body)
.setAutoCancel(true).setSound(sound);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(MESSAGE_NOTIFICATION_ID, mBuilder.build());
}
}

Line 20 : MESSAGE_NOTIFICATION_ID is used to make notification same for example if you send another notification and user have not read the old one it will replace the old one
Line 24 : Method which will receive the content from GCM
Line 34 : Sound for notification
Line 35 : Vibration Pattern
Line 37 : Intent which will run on click of notification you can open link to browser or you can open the activity

Constants.java

package com.developerhouse.push;
public class Constants {
public static String PREF_GCM_REG_ID = "PREF_GCM_REG_ID";
public static String GCM_SENDER_ID = "339415449819";
public static String WEB_SERVER_URL = "http://192.168.1.103/push/reg.php";
public static final String SERVER_SUCCESS="server_success";
}

GCM_SENDER_ID = Project ID
WEB_SERVER_URL = URL to register user unique id

MainActivity.java

package com.developerhouse.push;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
public static String newRegID="";
private BroadcastReceiver mRegistrationBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
String sentToken = sharedPreferences
.getString(Constants.PREF_GCM_REG_ID, "");
System.out.println("SERVER_SUCCESS")
; if (sentToken.equals("")) {
Toast.makeText(MainActivity.this, "Failed to save on server", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Succesfully saved on server", Toast.LENGTH_SHORT).show();
}
}
};
if (checkPlayServices()) {
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(Constants.SERVER_SUCCESS));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
9000).show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
}</pre>
<pre>

Server side code (PHP,MySQL)
In Server side we have to create a 4 PHP scripts for inserting the registration id & sending push notification.I am not going to explain basic steps to create PHP Script and MySQL DB for that you can check this link

http://developerhouse.com/blog/2015/08/tutorial-1-connect-android-with-php-mysql/
I am not focusing on design of the admin panel or anything related to it because our main focus will be on coding and getting your work done by adding Login Page(some of readers will be using it in their apps so it can be misuse)
Also i am not saving the username and pass in MySQL DB there is no need for it at this moment it’s just for learning purpose so that android developer can easily get push notification implemented without needing any PHP developer for php code.

Create Database named push
Table named registration

PHPMyAdmin Registration Table
PHPMyAdmin Registration Table

These are the structure of these tables

Name Type Length/Values A I (Auto Increment)
id INT Yes
gcm_regid VARCHAR 300 No (By Default)
created_at timestamp No (By Default)

 

PHP Files
connect.php // Change this for settings of MySQL DB
login.php // To login into admin panel
reg.php // For saving registration ID’s
send.php // For sending the push notification

connect.php
It’s used for changing login page username,password & also for changing mysql details.

<?php
define("apiKey","AIzaXXXXXXXXXXXXXXXXXXXXXXXX");//Fill the key which we got from Developer Console
$user="admin";
$pass="password";
$host="localhost";
$db_user_name="root";
$db_password="";
$db_name="push";
$con = new PDO('mysql:host='.$host.';dbname='.$db_name.';charset=utf8', $db_user_name, $db_password);
$con->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
?>

login.php

It’s used for login into Android Push Notification panel so that no one can access it without username and password .You can change the username & password in connect.php file

<?php
session_start();
if (isset($_POST['submit'])) {
if (empty($_POST['username']) || empty($_POST['password'])) {
echo "Login is invalid";
}
else
{
$username=$_POST['username'];
$password=$_POST['password'];
include_once "connect.php";
if ($username==$user & $password==$pass) {
$_SESSION['login_user']=$user;
header("location: send.php");
exit();
} else {
echo "Login is invalid";
}
}
}
if(isset($_SESSION['login_user'])){
header("location: send.php");
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Admin Panel Login: Developer House</title>
</head>
<body>
<div id="main">
<h1>Admin Panel Login Push Notification</h1>
<div id="login">
<h2>Login Form</h2>
<form action="" method="post">
<label>Username :</label>
<input id="name" name="username" placeholder="username" type="text">
<label>Password :</label>
<input id="password" name="password" placeholder="**********" type="password">
<input name="submit" type="submit" value=" Login ">
</form>
</div>
</div>
</body>
</html>

reg.php
This is the file which will be requested through Android platform via HTTP Request.

<?php
include_once "connect.php";
function storeUser($con,$gcm_regid) {
$stmt = $con->prepare("INSERT INTO registration(gcm_regid, created_at) VALUES(:field, NOW())");
$stmt->execute(array(':field' => $gcm_regid));
$id = $con->lastInsertId();
$result = $con->query("SELECT * FROM registration WHERE id = $id");
if ($result->rowCount() > 0) {
return true;
} else {
return false;
}
}
function getSame($con,$gcm_regid) {
$result =$con->query("SELECT * FROM registration WHERE gcm_regid=\"".$gcm_regid."\"");
if ($result->rowCount()>0) {
return true;
} else {
return false;
}
}
if (isset($_POST["regID"])) { 
$gcm_regid = $_POST["regID"];
if(!getSame($con,$gcm_regid)){
storeUser($con,$gcm_regid);
echo "1";
}else{echo "0";}
} else {
echo "0";
}?>

send.php
This file is used for sending the push notification of our choice to the all users in group.

<?php
session_start();
include_once 'connect.php';
function send_notification($con,$registatoin_ids, $message) {
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'data' =>array("message" => $message),
'registration_ids' => $registatoin_ids
);
$headers = array(
'Authorization: key=' . apiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
echo $result;
}
if(isset($_SESSION['login_user'])){
if(isset($_POST["submit"]) && isset($_POST["message"])) {
$num=$con->query("SELECT gcm_regid from registration")->rowCount();
$current_num=0;
$message=$_POST["message"];
for($i=0;$i<$num/1000;$i++){
$query=$con->query("SELECT gcm_regid from registration LIMIT $current_num,1000");
foreach($query as $data) {
$row[]=$data["gcm_regid"];
}
$pushStatus = send_notification($con,$row, $message);
$current_num+=1000;
}
}else if(isset($_POST["logout"])){
if(session_destroy()) // Destroying All Sessions
{
header("Location: login.php"); // Redirecting To Home Page
}
}
?>
<?php
?><!DOCTYPE html>
<html>
<head>
<title>Send Push Notification : Developer House</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<?php
$result = $con->query("SELECT * FROM registration");
if ($result != false)
$no_of_users =$result->rowCount();
else
$no_of_users = 0;
?>
<div >
<h1>No of Devices Registered: <?php echo $no_of_users; ?></h1>
<hr/>
<?php
if ($no_of_users > 0) {
?>
<form method="POST" action="">
<textarea rows="3" name="message" cols="25" placeholder="Type message here"></textarea>
<button type="submit" name="submit" value="Submit">Submit</button>
<button type="submit" name="logout" value="Submit">Logout</button>
</div>
</form>
<?php
} else { ?>
<li>
No Users Registered!
</li>
<?php }
}?>
</div>
</body>
</html>

 

Sending push notifications

Now if you have followed the tutorial this step will work for you.

So steps are

  1. Open Android Costants.java file & replace GCM_SENDER_ID variable value to the project number from project console ,WEB_SERVER_URL value to the one with your server url and file path for example if you have uploaded in wamp www then check IP of your computer it should be like this http://192.168.1.103/reg.php or if you have used a Linux Hosting and uploaded in public_html your main domain is developerhouse.com then it will be http://developerhouse.com/reg.php
  2. Open connect.php change apiKey value to the one we got from project console Api & auth -> Credentials
  3. Compile & Run the android application . Don’t worry if it does not show anything because we have not made it for this purpose .
  4. It will show Toast Registered with web server if everything works well
  5. Now check PHPMyAdmin it will have a new value in registration table
  6. Now to send the Push Notification go to this url http://192.168.1.103/login.php .Fill username & password.You will be redirected to the http://192.168.1.103/send.php file it will show no. of registered user & a textarea with two buttons
  7. Press submit & check notification.
  8. Finish

Code Download Click here (Dropbox)

Few Notes

  • In send.php i have used 1000 limit code because i had read this on few sites that in 1 request you cannot send push notification to more then 1000 device id so i have created a loop for this (Of-course you can try other approach)
  • I have not gave my focus to the design of Login page or Send page because you are admin you don’t have to show this page to the world But a nice design is always best so feel free to change it .
  • I have edited the code from first version because it was not using MyInstanceIDListenerService class it’s useful if the token got expired or compromised it will refresh the token in onTokenRefresh which will call RegistrationIntentService .Another reason to edit the post was using PDO in PHP Files which can helps us to prevent SQL Injection.
Posted on

Tutorial 2 : Connect Android with PHP,MySQL (JAVA Code)

Fetched Data by Tutorial Connect

Welcome to Connect Android with PHP & MySQL Series Part 2

Summary

In this tutorial i will show you how to access the fetched data from PHP Script using Volley Library,Parse the fetched JSON and show it in ListView

0.) Requirement

To test the communication between WAMP and your android app you must be on same network.For eg. you are connected to same Wireless router on your device and with your computer on which WAMP is running.

1.) Setting up Required Libraries (Volley Library)

Download volley library from here

Add the downloaded jar file to project
Create a new Project in Eclipse File -> New -> Android Application Project -> Fill the required fields.
once the project is succesfully created paste the volley.jar in libs folder (if there is no libs folder then you can make one)

2.) Starting Project

Creating Volley Applicatio class this class will maintain volley objects & request queue.
In your project create a new class named VolleyController.java & extend the class from Application & add following code
VolleyController.java

package com.developerhouse.android.connect;
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
public class VolleyController extends Application {
public static final String TAG_APP = VolleyController.class
.getSimpleName();
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private static VolleyController instance;
@Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static synchronized VolleyController getInstance() {
return instance;
}
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
requestQueue = Volley.newRequestQueue(getApplicationContext());
}
return requestQueue;
}
public ImageLoader getImageLoader() {
getRequestQueue();
if (imageLoader == null) {
imageLoader = new ImageLoader(this.requestQueue,
new LruBitmapCache());
}
return this.imageLoader;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG_APP : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG_APP);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (requestQueue != null) {
requestQueue.cancelAll(tag);
}
}
}

LruBitmapCache.java

package com.developerhouse.android.connect;
import com.android.volley.toolbox.ImageLoader.ImageCache;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public class LruBitmapCache extends LruCache<String, Bitmap> implements
ImageCache {
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
public LruBitmapCache() {
this(getDefaultLruCacheSize());
}
public LruBitmapCache(int sizeInKiloBytes) {
super(sizeInKiloBytes);
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight() / 1024;
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
&nbsp;

Edit AndroidManifest.xml file and add the VolleyController class in <application> tag using android:name
this will execute the class automatically when the app launch & add INTERNET permission because we need to call web services.
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.developerhouse.android.connect"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name="com.developerhouse.android.connect.VolleyController"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

We are outputting JSON array from php Script in JSON if the starting tag is [ then it’s a Array else if it is { then it’s a Object

Json Array (Current output)

[{"id":"1","title":"Rickshaw Racer","description":"Get Rickshaw Racer on Google Play","img_url":"http:\/\/s22.postimg.org\/kg4dj2usx\/Icon_Rickshaw_512.png"}]

Json Object

{"id":"1","title":"Rickshaw Racer","description":"Get Rickshaw Racer on Google Play","img_url":"http:\/\/s22.postimg.org\/kg4dj2usx\/Icon_Rickshaw_512.png"}

MainActivity.java

package com.developerhouse.android.connect;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
public class MainActivity extends Activity { 
private ProgressDialog dialog=null ;
private String TAG="Tutorial Connect";
private String tag_json_arry = "json_array_req";
private String url = "http://192.168.1.5";
private String url_file="/fetch.php";
private CustomAdapter adapter;
private ListView list;ArrayList<RowData> rowdata;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list=(ListView) findViewById(R.id.listView1);
rowdata=new ArrayList<RowData>();
dialog= new ProgressDialog(this);
dialog.setMessage("Loading...");
dialog.show();
JsonArrayRequest request = new JsonArrayRequest(url+url_file,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString()); try {
for(int i=0;i<response.length();i++){
String title=response.getJSONObject(i).getString("title");
String description=response.getJSONObject(i).getString("description");
String img_url;
img_url = response.getJSONObject(i).getString("img_url");
rowdata.add(new RowData(title, description, img_url));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
adapter=new CustomAdapter(MainActivity.this, rowdata);
list.setAdapter(adapter);
dialog.dismiss();
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error: " + error.getMessage());
dialog.dismiss();
}
});
// Adding request to request queue
VolleyController.getInstance().addToRequestQueue(request, tag_json_arry);
}
}

Line 22

private String url = "http://192.168.1.5";

Change this to the IP of your computer

How to get IP of the computer ?

Open CMD type ipconfig you will see something like this

How to use IPConfig
How to use IPConfig

check your default Network Adapter IP

the above code will Log the response & show fetched data in ListView so fire up WAMP ,check PHP Script it’s fetching result or not & run your android app if it output something in LogCat then you are good to continue else post the Error in Comment section or search it on Google

 

CustomAdapter.java

this class is Custom Adapter which will fill be filled by listview

package com.developerhouse.android.connect;
import java.util.ArrayList;
import com.android.volley.toolbox.NetworkImageView;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class CustomAdapter extends BaseAdapter{
private ArrayList<RowData> result;
private Context context;
private static LayoutInflater inflater=null;
public CustomAdapter(MainActivity mainActivity, ArrayList<RowData> data) {
// TODO Auto-generated constructor stub
result=data;
context=mainActivity;
inflater = ( LayoutInflater )context.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return result.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public class Holder
{
TextView title;
TextView description;
NetworkImageView img;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.list_item, null);
holder.title=(TextView) rowView.findViewById(R.id.textView1);
holder.description=(TextView) rowView.findViewById(R.id.textView2);
holder.img=(NetworkImageView) rowView.findViewById(R.id.networkImageView);
holder.title.setText(result.get(position).getTitle());
holder.description.setText(result.get(position).getDescription());
// If you are using NetworkImageView
holder.img.setImageUrl(result.get(position).getImageURL(), VolleyController.getInstance().getImageLoader()); 
return rowView;
}
}

RowData.java

this class contains variable to hold list item data which is Title,Description,Image Url

package com.developerhouse.android.connect;
public class RowData {
private String title;
private String description;
private String img_url;
public RowData(String title,String description,String img_url){
this.title=title;
this.description=description;
this.img_url=img_url;
}
public String getTitle(){
return title;
}
public String getDescription(){
return description;
}
public String getImageURL(){
return img_url;
}
}

 

XML Layout

activity_main.xml

<LinearLayout 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"
tools:context="com.developerhouse.android.connect.MainActivity"
android:orientation="vertical">
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/networkImageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerHorizontal="false" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/networkImageView"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/networkImageView"
android:layout_below="@+id/textView1"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>

Fetched data will show like this

Fetched Data by Tutorial Connect
Fetched Data by Tutorial Connect
Posted on

Tutorial 1 : Connect Android with PHP,MySQL (PHP Code)

Welcome to Connect Android with PHP & Mysql Series Part 1

Summary

In this tutorial i will show you how to create database, get data from PHP scripts & show it in json form which you access by a URL.

1.) Installing Wamp Server on Windows.

Go to http://www.wampserver.com/en/ download the Wamp as per your software architecture 64 bit or 32 bit

Wamp Folder
Wamp Folder

Then go to install location mine is C:\wamp (by default this is the install location for are users) open wampmanager.exe

Now you can test your wamp server by going to this address in browser http://localhost/ or http://127.0.0.1. If it’s opening default page of wamp then you’re good to proceed further.

Check the phpmyadmin also with the url : http://localhost/phpmyadmin (PHPMyAdmin helps us to create,manage,insert into the database,tables with Graphical User interface instead of MySQL Console window)

2.) Creating our first PHP Script to test

Open notepad or notepad++ (i am using Notepad++)

write this code

<?php
echo "Hello,World";
?>

<?php means opening tag for any PHP Script it’s like public class name { in java

and ?> means closing tag like closing bracket in JAVA

what ever you code write in these tag will be handle as PHP code

echo means System.out.println

Save it as test.php in c:\wamp\www (all files in this folder will be accessible from localhost)

now when you access it with this URL http://localhost/test.php it will print this Hello,World

Hello-World
Hello-World

3. )Let’s move to create database through PHPMYADMIN

open this http://localhost/phpmyadmin

Click on Database button on top header now it will take you to create database page

Localhost PHPMyAdmin
Localhost PHPMyAdmin

Enter DB (Database) name in first text box and create on create.

Create Database in PHPMyAdmin
Create Database

Now on left sidebar you will see list of database.Click on your newly created database then click on Create Table.

Create Table in PHPMyAdmin
Create Table

Fill fields

  1. Table Name : products
  2. No. of columns : 4

Columns

Products Table
Products Table
Name Type Length/Values A I (Auto Increment)
id INT Empty (By Default) Yes
title VARCHAR 40 No (By Default)
description VARCHAR 250 No (By Default)
img_url VARCHAR 100 No (By Default)

Now we will add a entry in MySQL Table named products

Select products from side panel.Click on Insert on Header

Now fill it like this

Column Type Function Value
id INT(11)
title VARCHAR(40) Rickshaw Racer
description VARCHAR(250) Get Rickshaw Racer on Google Play
img_url VARCHAR(100) http://s22.postimg.org/kg4dj2usx/Icon_Rickshaw_512.png

Now you have filled it with details click on Go Button.

Insert 1 or  more rows with the details you want to be shown in Android App.

4.) Move to PHP again to show our data by echo command

Let’s make a config.php file in the www folder in wamp directory.

Detail about config.php : It’s usefull to save all the MySQL database info in one file so you don’t have to fill it again & again.

  • Host = localhost (by default if you’re using it on wamp and MySQL Server is also installed on same machine)
  • Username = root (by default)
  • Password =  (by default Empty 0 length)
  • Database name = android_db (same)
  • Table name = products (same)
<?php
$host="localhost";
$user_name="root";
$password="";
$db_name="android_db";
$table_name="products";
//Let's make a mysql connection to connect the server.
$con=mysqli_connect($host,$user_name,$password);
mysqli_select_db($con,$db_name);
?>

Explanation by lines

1.) Opening Tag.

2.) Host name or Ip Address where our MySQL Server is installed.

3.) Username to access the database.

4.) Password for the username to get pass authentication.

5.) Database name in our case android_db which we made in earlier steps.

6.) Table name in our case products

8.) Comment just like we do in JAVA

9.) It’s connecting to MySQL Database to make communication

10.) Select database to communicate

5.) Create fetch.php to get results from table

Code

<?php
include_once("config.php");
$query=mysqli_query($con,"SELECT * FROM ".$table_name);
$array;
while($result=mysqli_fetch_assoc($query)){
$array[]=$result;
}
echo json_encode($array);
?>

Explanation by lines

2.) Include config.php just like Import in Java.

4.) Here we query the MySQL Database to give us all rows from table name

5.) Declaring array as a variable

6.) While Loop to fetch all results

8.)The $result fill all results in $array

11.) Print encoded JSON

try to access the file via Browser from this url http://localhost/fetch.php it will print something like this

[{"id":"1","title":"Rickshaw Racer","description":"Get Rickshaw Racer on Google Play","img_url":"http:\/\/s22.postimg.org\/kg4dj2usx\/Icon_Rickshaw_512.png"}]

So the PHP Part is completed in next Tutorial we will work on Android Code

Posted on

Android App Tutorial Series Connect with PHP,MySQL

Web Services Diagram

Android App Tutorial Series

In this Series of android app tutorial we will focus on how to connect with PHP Scripts with MySQL as database and communicating with android.

Basically it is used as Web Services for fetching,inserting,managing data through android app with the help of PHP Scripts.

We will call the PHP Script with Volley Library (Saves time,Easy to use)

So the operation will be simple as defined in below image

Web Services Diagram
Web Services Diagram

your code calls PHP script

 

What is PHP ?

PHP is a server-side scripting language designed for web development but also used as a general-purpose programming language

What is MySQL ?

With PHP, you can connect to and manipulate databases.

MySQL is the most popular database system used with PHP

How to host files of PHP & MySQL (It’s not same as putting *.java files in your Project) ?

You need a hosting if  you want to access it over Internet

OR

You can use WAMP,XAMPP or any other server on your computer install one of them by this you can host your PHP files locally and access it via 127.0.0.1 or localhost (these are the address to access your files just like domain name developerhouse.com)

PHP script will work on Server Side for inserting, Editing, Deleting ,Showing Records with MySQL Database.

I’ll be using Hostgator shared hosting to host PHP Scripts.if you want to use any other hosting the process will be same if the hosting provides CPanel.

OR

I will also post Screenshot to get you started with WAMP so that you ca use localhost instead of Linux Hosting (WAMP,XAMPP)

Tutorial List:

Part 1- Tutorial 1 : Connect Android with PHP,MySQL (PHP Code)

Part 2- Tutorial 2 : Connect Android with PHP,MySQL (JAVA Code)

Posted on

Android : Too many pattern attempts Solution

Android the most popular Operating System fro smartphones now a days.The OS is Linux based designed mainly for Touchscreen & tablet devices.
I am not here to talk about android History if you want to read more about android then visit this Link

Android

A Common prob. in android Smartphones users are facing is their smartphones is locked after too many wrong pattern attempts

Most of Android smartphones users lock their smartphone using pattern lock for better privacy. (Reason can be they have some 18+ Pics which they don’t want to show to their friends :P)

What is pattern Lock ??
The Pattern lock is type of lock which let you draw image by connecting circles which make a pattern. You can only open your mobile if your draw right pattern. In case you draw wrong pattern, you are aksed to redraw the right Pattern

If you are a android user and draw more then 20 times wrong pattern then your smartphone get locked.
Now you can’t try new pattern or use any other feature of smartphone.Even you can’t make any Phone call.
If this is your case then you are in right place.

Solution to the Prob.

If your smartphone is locked with too many wrong attempts then here we go with our First solution.

Use Google account associated with smartphone. You need to login with your google account & then you can easily disable or change the pattern of your lock but for this
you your WiFi has to be turned on already because you can’t turn on the WiFi if your smartphone is locked.
Another solution is in some smartphones when you press Lock key more then 4-5 seconds you will get a Alert dialog
to turn on your Mobile Data pack (Only useful if you have set the APN already)

If WiFi is turned off on your smartphone then you can’t login into your account. You can also enable the WiFi or Mobile data through Android Debug Bridge 
This method requirement is that you must enabled USB Debugging feature under ‘Developer Options’ on your device

Steps to bypass Lock screen through ADB (Not by turning on the Wifi)
1. Download ADB thorugh Google site
2. Connect your Device through USB
3. Open CMD in windows
4. Issue the following Command

adb shell
rm /data/system/gesture.key

5. Now reboot your android device & supply the following Commands
6.

adb shell
cd /data/data/com.android.providers.setting­s/databases
sqlite3 settings.db
update system set value=0 where name=’lock_pattern_autolock’;
update system set value=0 where name=’lockscreen.lockedoutpermanently’;
.quit

7. Restart it
8. You’re done now it will accept any new pattern

If you are facing any error then please let me know in Comments