Hello Friends,
Today I am going to share very Important code for GCM(Google Cloud Messaging) for Android. I worked with my php developer(Ankit Garg) for back end and it is working Okay for me.
My article have 3 category-
1)Creating a Google API Project
2)PHP Back-end
3)Android Front-end
Part-A Google API Project
1)Open Google API console from here
2)If you have not created any project create new project for your application-
8)Now from below window choose create button:
1)GCM.php
Please write your comment and feedback below:
Today I am going to share very Important code for GCM(Google Cloud Messaging) for Android. I worked with my php developer(Ankit Garg) for back end and it is working Okay for me.
My article have 3 category-
1)Creating a Google API Project
2)PHP Back-end
3)Android Front-end
Part-A Google API Project
1)Open Google API console from here
2)If you have not created any project create new project for your application-
3)See your browser URL and note your project ID from above some thing like that-1080127563513
https://code.google.com/apis/console/#project:1080127563513
4)In the main Google APIs Console page, select Services.
5)Turn the Google Cloud Messaging toggle to ON.
6)In the Terms of Service page, accept the terms.
7)get API Key from main Google APIs Console page, select API Access. You will see a screen that resembles the following and click on Create new Server Key:
8)Now from below window choose create button:
9)From below window note your project id and api key:
1)GCM.php
<?php $regID=$_GET['regID']; $registatoin_ids=array($regID); $msg=array("message"=>'HI Manish'); $url='https://android.googleapis.com/gcm/send'; $fields=array ( 'registration_ids'=>$registatoin_ids, 'data'=>$msg ); $headers=array ( 'Authorization: key=AIzaSyA46UE7bBWXCpHSD5sbNxbRwI1MAKVI-jg', '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); curl_close($ch); echo $result; ?>1)MainActivity.java
package com.manish.gcm.push; import static com.manish.gcm.push.CommonUtilities.SENDER_ID; import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpParams; import android.annotation.TargetApi; import android.app.Activity; import android.app.ProgressDialog; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import com.google.android.gcm.GCMRegistrar; @TargetApi(Build.VERSION_CODES.GINGERBREAD) public class MainActivity extends Activity { private String TAG = "** GCMPushDEMOAndroid**"; private TextView mDisplay; String regId = ""; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); checkNotNull(SENDER_ID, "SENDER_ID"); GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); mDisplay = (TextView) findViewById(R.id.textView1); regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("")) { GCMRegistrar.register(this, SENDER_ID); } else { Log.v(TAG, "Already registered"); } /** * call asYnc Task */ new sendIdOnOverServer().execute(); mDisplay.setText("RegId=" + regId); } private void checkNotNull(Object reference, String name) { if (reference == null) { throw new NullPointerException(getString(R.string.error_config, name)); } } @Override protected void onPause() { super.onPause(); GCMRegistrar.unregister(this); } public class sendIdOnOverServer extends AsyncTask2)GCMIntentService.java{ ProgressDialog pd = null; @Override protected void onPreExecute() { pd = ProgressDialog.show(MainActivity.this, "Please wait", "Loading please wait..", true); pd.setCancelable(true); } @Override protected String doInBackground(String... params) { try { HttpResponse response = null; HttpParams httpParameters = new BasicHttpParams(); HttpClient client = new DefaultHttpClient(httpParameters); String url = "http://10.0.0.30//parsing/GCM.php?" + "®ID=" + regId; Log.i("Send URL:", url); HttpGet request = new HttpGet(url); response = client.execute(request); BufferedReader rd = new BufferedReader(new InputStreamReader( response.getEntity().getContent())); String webServiceInfo = ""; while ((webServiceInfo = rd.readLine()) != null) { Log.d("****Status Log***", "Webservice: " + webServiceInfo); } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { pd.dismiss(); } } }
package com.manish.gcm.push; import static com.manish.gcm.push.CommonUtilities.SENDER_ID; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.util.Log; import com.google.android.gcm.GCMBaseIntentService; public class GCMIntentService extends GCMBaseIntentService { public GCMIntentService() { super(SENDER_ID); } private static final String TAG = "===GCMIntentService==="; @Override protected void onRegistered(Context arg0, String registrationId) { Log.i(TAG, "Device registered: regId = " + registrationId); } @Override protected void onUnregistered(Context arg0, String arg1) { Log.i(TAG, "unregistered = " + arg1); } @Override protected void onMessage(Context context, Intent intent) { Log.i(TAG, "new message= "); String message = intent.getExtras().getString("message"); generateNotification(context, message); } @Override protected void onError(Context arg0, String errorId) { Log.i(TAG, "Received error: " + errorId); } @Override protected boolean onRecoverableError(Context context, String errorId) { return super.onRecoverableError(context, errorId); } /** * Issues a notification to inform the user that server has sent a message. */ private static void generateNotification(Context context, String message) { int icon = R.drawable.ic_launcher; long when = System.currentTimeMillis(); NotificationManager notificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = new Notification(icon, message, when); String title = context.getString(R.string.app_name); Intent notificationIntent = new Intent(context, MainActivity.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent intent = PendingIntent.getActivity(context, 0, notificationIntent, 0); notification.setLatestEventInfo(context, title, message, intent); notification.flags |= Notification.FLAG_AUTO_CANCEL; notificationManager.notify(0, notification); } }3)CommonUtilities .java
package com.manish.gcm.push; public final class CommonUtilities { //put here your sender Id static final String SENDER_ID = "311451115764"; }4)activity_main.xml
5)manifest.xml
6)Download Zip Code
Thanks,Please write your comment and feedback below:
Nice tutorial can you please help me? how to use sql database to send push?
ReplyDeletePlease see demo i am using mysql. You can use any...
DeleteHi Can u upload the whole project source code ...
ReplyDeleteI thinks it's gonna be more helpful for us than some peace of code.
the project can be built .
Thanks in advance.
Sure i will upload soon..
DeleteHi, I'm new to java and android but I think there could be a problem with your example.
ReplyDeleteIf the device has not registered before, GetRegistrationId will return an empty string and so you then call register. That returns the new registrationId in the GCMIntentService as a local variable.
So when you call sendIdOnOverServer the registrationId might not have been received but even if it has been received, it will not be the registrationId that is sent to the server in MainActivity. That one will still be blank.
Or am I missing something?
Thanks.
No no this demo always send registration id before get a push..
DeleteIt should not be blank any time...
I have tested it no issue here and i am using it in my app also...
I'm sure you know your program better than I do but I'm confused as to how it is working. This is how I see it:
ReplyDeleteThe first ever time you call getRegistrationId it will return an empty string. You then call register to get a regId from GCM but that call returns immediately and the regId is returned seconds later in the intent service.
You call sendIdOnOverServer immediately after the call to register and hence regId will be empty at that time so an empty string will be sent to your server.
The next time the progam runs, it will work fine because getRegistrationId will return the last registration and so regId will not now be empty and so a valid regId will be sent to your server.
If I am wrong about this I'd appreciate to know how it works. I can understand that your app may work long term but I think first time, it will effectively fail.
No John its work all time fine because this app send registration id on server every time.. I have tested it..
Deleteupload full project source code please
ReplyDeleteSure I will Upload on GIT server, keep in touch..
DeleteThanks,
Hello Manish thanks for your tutorial. but i think there is a problem..
ReplyDeletein your manifest file you are declaring
android:minsdkversion="7"
but i think it should be
GCM requires Android SDK version 2.2 (API level 8) or above.
android:minSdkVersion="8"
Deepak
Yes may be if google not allow us we can't send push message..
DeleteThis comment has been removed by the author.
ReplyDeleteNote down the project id which will be used as SENDER ID in android project=311451115764;
Deletesender Id is project_Id? and i have copied your code in that "GCM registrar" shown error line...!pls help brothr
ReplyDeleteYes sender id= project id..
DeleteWhere you are facing trouble please let me know..
Nice tutorial,it shows error in this line...public class sendIdOnOverServer extends AsyncTask, the error is Syntax error on tokens, Dimensions expected instead. I am using ROR framework,do you know how to write server side code for that one to send push notification,if i add data in server the push notification has to come in my android apps.Help me dude
ReplyDeleteI am using eclipse, and code is working for me.I have put all code of=n Git Server please download from there. And a download link on my post also.
Deletehttps://github.com/manishsri01/GCMPushDemo
Thanks,
The code is completely mangled up, probably a fault of the syntax highlighter, but it ruins the entire tut.
ReplyDeleteFor e.g. a theres a complete loss of capitalization in the xml tags for (also in the manifest):
I have add a download link on my post please download zip code and try again...
DeleteThanks,
This comment has been removed by the author.
ReplyDeleteGreat post! Thanks Manish...
ReplyDeleteThanks and your welcome!
DeleteHi Manish, Is there anyway to contact you via chat?
ReplyDeleteCan you share your problem here? It will usefull to others visitor. Well you can email me at manishupacc@gmail.com
DeleteHi Manish,
ReplyDeleteIt is a nice tutorial but I see your GCM.php starts with some weird syntax. Can you clarify the GCM.php file. it gives error of variable registatoion_ids and msg not defined.
Thanks
Hello Pragmatute!
DeleteThanks for your suggestion, I change the code please check now...
Hi Manish,
ReplyDeleteIt is a nice tutorial but I have doubt when we get $_GET['regID'];
It is not working?
DeleteIt should work any problem in code?
No problem in code but its my doubt
DeleteHow we get registration id?
You will get reg-id from client side in this method-
Deletehttp://10.0.0.30//parsing/GCM.php?®ID=+regId
Hi
DeleteWhen i use this code i get the following error
{"error":"InvalidRegistration"}
Have you short out problem? Have you created new project on Google developer?
DeleteHi Manish
DeleteI am also same this problem
I was registry, user Project ID number to register on Device and there are below notification
Your device registred with GCM
Server successful added device
But when i user server to sent notification,
At resutl message from google.send is
{"multicast_id":6265367446240819368,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}
So, how to fix it
Please help me
Its seems any php tag like "pre" or something else missing.
DeleteThis comment has been removed by the author.
ReplyDeletein logcate it's display
ReplyDelete09-17 12:22:40.017: V/GCMRegistrar(342): Registering app com.manish.gcm.push of senders 386632392116
09-17 12:22:40.017: V/GCMRegistrar(342): Creating pending intent to get package name
09-17 12:22:40.297: V/GCMBroadcastReceiver(342): onReceive: com.google.android.c2dm.intent.REGISTRATION
09-17 12:22:40.297: V/GCMBroadcastReceiver(342): GCM IntentService class: com.manish.gcm.push.GCMIntentService
09-17 12:22:40.327: I/Send URL:(342): http://10.0.2.2//parsing/GCM.php?®ID=
09-17 12:22:40.357: V/GCMBaseIntentService(342): Intent service name: GCMIntentService-386632392116-3
09-17 12:22:40.387: D/GCMBaseIntentService(342): handleRegistration: registrationId = null, error = ACCOUNT_MISSING, unregistered = null
09-17 12:22:40.387: D/GCMBaseIntentService(342): Registration error: ACCOUNT_MISSING
09-17 12:22:40.387: I/===GCMIntentService===(342): Received error: ACCOUNT_MISSING
09-17 12:22:40.527: I/global(342): Default buffer size used in BufferedReader constructor. It would be better to be explicit if an 8k-char buffer is required.
i have few question pls help me
i had set senderid as per google account regiser
i had make GCM.php file put it into parsing/GCM.php file in wamp server
but i had not create any talbe nothing so where it store?
second thing how can i send any message on device using this?
Hi Pankaj!
ReplyDeleteLet me clear all of your doubts.
1)Its not must your device return always registration id. Please try 1-3 time if you did not got registration id in your application.
2)Here we are not storing any thing in database just we are getting registration-id from device and we hit the google server and google send push message on mobile device.
3)Please check your project on google developer console and put sender-id same as your project-id, both are same.
4)In your php code change 'Authorization: key=AIzaSyA46UE7bBWXCpHSD5sbNxbRwI1MAKVI-jg', with your project key generated by you.
Note: I think you are using same package name whats in my demo app so be sure your application package name should be same on Google console. I think you should change package name in your android code and create new project on Google console.
Here I am explaining php code line by line hope it will help you.
'HI Manish'); //here I create json array message to send to user device
$url='https://android.googleapis.com/gcm/send'; //this is url where we hit for sending push message on device from php server
$fields=array
(
'registration_ids'=>$registatoin_ids,
'data'=>$msg
);
$headers=array
(
'Authorization: key=AIzaSyA46UE7bBWXCpHSD5sbNxbRwI1MAKVI-jg', //this is your google app project key
'Content-Type: application/json'
);
$ch=curl_init(); // init method is used for start curl
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);
curl_close($ch);
echo $result; // it will return result
?>
Hi this is Maheswaran, I get only the empty Reg Id while I am running your demo app. I want to send notification to my application users when created a new Events, Can u please help me to integrate your code in my app?
ReplyDeleteHave you check all necessary thing like manifest permissions? and You are using mobile device instead of emulator ? and have you created your own project on Google Developer and change project-key with yours?
DeleteYes, I have checked everything what you are asking me, Is it possible to send notification to multiple users? I am using Emulator only not a mobile. Can you please come to chat? mmaheswaran87@gmail.com this my mail ID.
ReplyDeletePlease use mobile device instead of emulator, because we can't guaranty its give you reg-id. And yes I have messaged you check your gtalk.
DeleteHello Manish .....
ReplyDeleteI just download the whole source code to see how it works. I've use my sender ID and uploaded the GCM.php file on my server. But when i run the app it just give me a screen tell " RegId = "
Any Idea why so ?
Are you using mobile phone? And please see log cat. may be there correct reg-id. And please try 1-2 time may be in first time we did not reg-id.
DeleteCan we send notification to IPHONE from android? This is, if my application installed in IPhone means, the notification will send or not?
ReplyDeleteNo dear you can't send notification to IPHONE from android device. You should use APNS(apple push notification services) for that.
DeleteIs it any possible to send notification to IPhone device through this code? I can send notification to Android Mobiles.
ReplyDeleteSee dear both are competitor and they will not allow for messaging between each other. write web-service in php and use GCM for android and APNS for iphone and send push message from php server. I think this is the best way..
Deletewhen im trying to import this app zip its telling no projects are found to import. could you please solve this problem?
ReplyDeleteadvance thanks for solving this
Don't import, create new project from exiting code.
DeleteHii Manish,,Great thanks for this tutorial
ReplyDeleteyour welcome dear!
DeleteHii Manish,Thanks for saving My Time......Great Work
ReplyDeleteThanks & your welcome!
DeleteHello Manish the demo works fine on my device but all I see is the regID. How can i get to see the messege "Hi Minash"
ReplyDeleteHi Manish,
ReplyDeleteI am following this tutorial, I am able to get reg Id for android emulator in which I have configure google account, so my android app side is ok, but to register application server i.e tomcat to c2dm i am using java REST web service in place of your php web service calling. Here from web service i am getting 401 response code and not getting push message from c2dm.
I have changed your web service calling line i.e String url = "http://10.0.0.30//parsing/GCM.php?" + "®ID=" + regId; r with my webservice calling i.e String url = "http://my_ip_add:port_number/Operations/registertogoogle?" + "®istrationid=" + regId;
and web service is code is as follows:
@Path("/registertogoogle")
@GET
@Produces("application/json")
public String registertogoogle(@QueryParam("registrationid") String registrationid)
{
System.out.println(" register google:"+registrationid);
//GetAuthenticationToken.setAuthentication();
String auth_token="key=AIzaSyB6w2Acf4C3DN2IPefgXd-etU9SQqpzuAo";
//"key=AIzaSyB6w2Acf4C3DN2IPefgXdetU9SQqpzuAo";//ServerConfiguration.getAUTHENTICATION_TOKEN();
System.out.println("authtocken:"+auth_token);
JSONObject jsonObject = new JSONObject();
try {
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder.append(PARAM_REGISTRATION_ID).append("=")
.append(registrationid);
postDataBuilder.append("&").append(PARAM_COLLAPSE_KEY).append("=")
.append("0");
postDataBuilder.append("&").append("data.payload").append("=")
.append(URLEncoder.encode("This works fine", UTF8));
byte[] postData = postDataBuilder.toString().getBytes(UTF8);
// Hit the dm URL.
URL url = new URL("https://android.apis.google.com/c2dm/send");//https://android.clients.google.com/c2dm/send");
HttpsURLConnection
.setDefaultHostnameVerifier(new CustomizedHostnameVerifier());
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8");
conn.setRequestProperty("Content-Length",
Integer.toString(postData.length));
conn.setRequestProperty("Authorization", auth_token);//"GoogleLogin auth=" +
System.out.println("Connectopn:"+conn.toString());
OutputStream out = conn.getOutputStream();
out.write(postData);
out.close();
int responseCode = conn.getResponseCode();
System.out.println("responsecode:"+responseCode);
jsonObject.put("responsecode",responseCode);
} catch (JSONException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return jsonObject.toString();
}
private static class CustomizedHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
I have searched for 401 error code it's about authentication but not able to get exact solution to fix this issue, could please give your suggestion!!!!!
Sorry Dear i have no more idea about web-services so I can't say anything. well error 401 means "Authorization Required error" That mean your server or Google server some where authentication is required.
DeleteI have download this code from this link https://github.com/manishsri01/GCMPushDemo . But when I import this project in eclipse . It will not import and error is that "No projects are found to import". give me solution ?
ReplyDeletePlease go through file menu and and create new project using exciting code.
DeleteHi Marnish,
ReplyDeleteNice tutorial and I have copied your source code in my apps and it works. However, i have little problem.
It seems I have got the registration ID but I in the app, it always shows "RegId=", however, i can see i have got the id in the cat log:03-29 19:06:41.241: I/===GCMIntentService===(7156): Device registered: regId = APA91bFFkVQMPl5SAQtofT-KXu5OwsU7sY2dFfRs5P0PyGFrjMxkwjr3k38M5C_k7as71bqEkYzP6sHSDVo0R9qqZ4Qsj0z2vIO7kPsbX77ta20nYa2HH3aBy-gnb4WChJKaNrC1R2hF0M3fwF_kMkMcsR2vqJFfKA
But in the status log, it create error:
03-29 19:06:42.151: D/****Status Log***(7156): Webservice: {"multicast_id":6265367446240819368,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MissingRegistration"}]}
03-29 19:06:42.191: E/ViewRootImpl(7156): sendUserActionEvent() mView == null\
could you please help me? thanks!!
Please add this line inside onPostExcute() method -
DeletemDisplay.setText("RegId=" + regId);
Part - A
ReplyDeleteNumber : 8
what i add in Accept requests from these server IP addresses:???
i can not get RegId now .
i change SenderID in Java class and API key in PHP
In my case, 9 out of 10 times sendIdOnOverServer has been executed before GCMRegistrar returns an ID. Logcat shows one second difference between sending ID and GCMBaseIntent.handleregistration. How to avoid empty RegId strings?
ReplyDeletePeet
can u please give the gcm server code using java
ReplyDeleteHi , I am new to android and require some urgent help. Is there any way to subtract two dates from picker. Ex: I will select a date from picker1 and date from picker2. Now, I what I am trying to do is picker2 - picker1 to get the number of days between these two dates.
ReplyDeletelike
06/10/2014
20/10/2014
14
Please help.
You need to use-
Deletelong diff=date2.getTime()-date1.getTime();
Now you can change this long to minute hour according to your need.
import com.google.android.gcm.GCMBaseIntentService;
ReplyDeletei am getting error on this import saying import cannot be resolved ,please help manish sir.
I need a simple application android, a user registers on my rest server and see the rest server response if the record was made by a push notification, have some sample code as well? thank you
ReplyDeletei have an error that" import com.google.android.gcm.GCMBaseIntentService;" or GCMBaseIntentService, and
ReplyDeleteimport com.google.android.gcm.GCMRegistrar; GCMRegister class file not found..please you have any solutions..
"Android Cloud to Device Messaging (C2DM) is deprecated. The C2DM service will be shut down completely on 10/20/2015. Currently, C2DM accepts no new users, and grants no new quotas. C2DM developers are strongly encouraged to move to Google Cloud Messaging (GCM). GCM is the next generation of C2DM."
ReplyDeletehave you any update for it?
Now Android is using "Google play services" for push messaging and they have full demo on android official website. please download from there.
DeleteThank you!
please can you post that url @manish
Deletehttps://developers.google.com/cloud-messaging/
DeleteCan you Please send the Code for Sending Notifications using Google Play Services @Manish
ReplyDeleteHow can I send Notifications from Server Machine to Multiple Devices(Mobiles) for Single Click can you Please Explain I new to Android
ReplyDeletehow to send push notification everyday at particular time...?
ReplyDeletein android using php..
DeleteAre you able to send a message on send button? If yes then just set a crone job. Search it on google -"How to create cron job using PHP?"
Deletewe are using button right now .. but i want to send automatically every 24hrs..
DeleteThank you
i want to send automatically without using any button ...
ReplyDeleteThank you
we are using button right now .. but i want to send automatically every 24hrs...
ReplyDeleteUsing cron job you don't need button, it is same like Alarm Manager.
DeleteThis comment has been removed by the author.
Deletehow can i create cron job ...?
Deletehow to send message to one device to anther device using GCM , if you have any code related to this please share with me
ReplyDeleteemail id vijayk3151@gmail.com
I don't think GCM support device to device messaging. You can use Bluetooth or WiFi for communication between 2 phone. Or you can use some logic like send message to server than server again redirect to 2nd device, it is same like how chat application does work.
Delete