\n\u003Cuses-permission android:name=\"com.synyx.cloudmessagetest.permission.C2D_MESSAGE\"/>\n \u003C!-- App receives GCM messages. -->\n\u003Cuses-permission android:name=\"com.google.android.c2dm.permission.RECEIVE\"/>\n \u003C!-- GCM connects to Google Services. -->\n\u003Cuses-permission android:name=\"android.permission.INTERNET\"/>\n \u003C!-- GCM requires a Google account. -->\n\u003Cuses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>\n \u003C!-- Keeps the processor from sleeping when a message is received. -->\n\u003Cuses-permission android:name=\"android.permission.WAKE_LOCK\"/>\n","xml",[79,480,481,485,490,495,500,505,510,515,520,525,530,535,540],{"__ignoreMap":77},[82,482,483],{"class":84,"line":85},[82,484,204],{"emptyLinePlaceholder":203},[82,486,487],{"class":84,"line":200},[82,488,489],{},"\u003Cpermission\n",[82,491,492],{"class":84,"line":207},[82,493,494],{}," android:name=\"com.synyx.cloudmessagetest.permission.C2D_MESSAGE\"\n",[82,496,497],{"class":84,"line":213},[82,498,499],{}," android:protectionLevel=\"signature\"/>\n",[82,501,502],{"class":84,"line":219},[82,503,504],{},"\u003Cuses-permission android:name=\"com.synyx.cloudmessagetest.permission.C2D_MESSAGE\"/>\n",[82,506,507],{"class":84,"line":225},[82,508,509],{}," \u003C!-- App receives GCM messages. -->\n",[82,511,512],{"class":84,"line":231},[82,513,514],{},"\u003Cuses-permission android:name=\"com.google.android.c2dm.permission.RECEIVE\"/>\n",[82,516,517],{"class":84,"line":237},[82,518,519],{}," \u003C!-- GCM connects to Google Services. -->\n",[82,521,522],{"class":84,"line":243},[82,523,524],{},"\u003Cuses-permission android:name=\"android.permission.INTERNET\"/>\n",[82,526,527],{"class":84,"line":249},[82,528,529],{}," \u003C!-- GCM requires a Google account. -->\n",[82,531,532],{"class":84,"line":255},[82,533,534],{},"\u003Cuses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>\n",[82,536,537],{"class":84,"line":328},[82,538,539],{}," \u003C!-- Keeps the processor from sleeping when a message is received. -->\n",[82,541,542],{"class":84,"line":334},[82,543,544],{},"\u003Cuses-permission android:name=\"android.permission.WAKE_LOCK\"/>\n",[23,546,547],{},"And declare a GCM broadcast receiver within the application tag:",[72,549,551],{"className":476,"code":550,"language":478,"meta":77,"style":77},"\n\u003Creceiver\n android:name=\"com.google.android.gcm.GCMBroadcastReceiver\"\n android:permission=\"com.google.android.c2dm.permission.SEND\">\n \u003Cintent-filter>\n \u003Caction android:name=\"com.google.android.c2dm.intent.RECEIVE\"/>\n \u003Caction android:name=\"com.google.android.c2dm.intent.REGISTRATION\"/>\n \u003Ccategory android:name=\"com.synyx.cloudmessagetest\"/>\n \u003C/intent-filter>\n\u003C/receiver>\n\u003Cservice android:name=\".GCMIntentService\"/>\n",[79,552,553,557,562,567,572,577,582,587,592,597,602],{"__ignoreMap":77},[82,554,555],{"class":84,"line":85},[82,556,204],{"emptyLinePlaceholder":203},[82,558,559],{"class":84,"line":200},[82,560,561],{},"\u003Creceiver\n",[82,563,564],{"class":84,"line":207},[82,565,566],{}," android:name=\"com.google.android.gcm.GCMBroadcastReceiver\"\n",[82,568,569],{"class":84,"line":213},[82,570,571],{}," android:permission=\"com.google.android.c2dm.permission.SEND\">\n",[82,573,574],{"class":84,"line":219},[82,575,576],{}," \u003Cintent-filter>\n",[82,578,579],{"class":84,"line":225},[82,580,581],{}," \u003Caction android:name=\"com.google.android.c2dm.intent.RECEIVE\"/>\n",[82,583,584],{"class":84,"line":231},[82,585,586],{}," \u003Caction android:name=\"com.google.android.c2dm.intent.REGISTRATION\"/>\n",[82,588,589],{"class":84,"line":237},[82,590,591],{}," \u003Ccategory android:name=\"com.synyx.cloudmessagetest\"/>\n",[82,593,594],{"class":84,"line":243},[82,595,596],{}," \u003C/intent-filter>\n",[82,598,599],{"class":84,"line":249},[82,600,601],{},"\u003C/receiver>\n",[82,603,604],{"class":84,"line":255},[82,605,606],{},"\u003Cservice android:name=\".GCMIntentService\"/>\n",[23,608,609],{},"The GCMIntentService has to be created by us. And that is what we’ll do now. First off, the GCMIntentService has to\nextend the class GCMBaseIntentService:",[72,611,613],{"className":188,"code":612,"language":190,"meta":77,"style":77},"public class GCMIntentService extends GCMBaseIntentService {\n",[79,614,615],{"__ignoreMap":77},[82,616,617],{"class":84,"line":85},[82,618,612],{},[23,620,621],{},"Now implement all the necessary methods. The only method we will use for this little test is onMessage(). We want to\nquickly see if we get a message for this app, so that we can confirm that it works. So we just create a notification\nwith the Notification Builder.",[23,623,624],{},"Because we are on an older minimum version of Android, we need to add the support library to have access to the\nNotification Builder. Add it by right clicking the project -> Android tools -> Add Support Library.",[23,626,627],{},"First in the onMessage() method, we need to get access to the Main Thread of our App.",[72,629,631],{"className":188,"code":630,"language":190,"meta":77,"style":77},"Handler h = new Handler(Looper.getMainLooper());\nh.post(new Runnable() {\n public void run() {\n }\n}\n",[79,632,633,638,643,648,652],{"__ignoreMap":77},[82,634,635],{"class":84,"line":85},[82,636,637],{},"Handler h = new Handler(Looper.getMainLooper());\n",[82,639,640],{"class":84,"line":200},[82,641,642],{},"h.post(new Runnable() {\n",[82,644,645],{"class":84,"line":207},[82,646,647],{}," public void run() {\n",[82,649,650],{"class":84,"line":213},[82,651,252],{},[82,653,654],{"class":84,"line":219},[82,655,656],{},"}\n",[23,658,659],{},"In the run() method, we get us an Intent from our MainActivity",[72,661,663],{"className":188,"code":662,"language":190,"meta":77,"style":77},"Intent notificationIntent = new Intent(context, CloudMessageTestActivity.class);\n",[79,664,665],{"__ignoreMap":77},[82,666,667],{"class":84,"line":85},[82,668,662],{},[23,670,671],{},"And then wrap it with a PendingIntent for the NotificationBuilder",[72,673,675],{"className":188,"code":674,"language":190,"meta":77,"style":77},"PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,\n notificationIntent, 0);\n",[79,676,677,682],{"__ignoreMap":77},[82,678,679],{"class":84,"line":85},[82,680,681],{},"PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,\n",[82,683,684],{"class":84,"line":200},[82,685,686],{}," notificationIntent, 0);\n",[23,688,689],{},"Finally, use the NotificationBuilder to create and send the notification",[72,691,693],{"className":188,"code":692,"language":190,"meta":77,"style":77},"NotificationCompat.Builder builder = new NotificationCompat.Builder(\n context);\nbuilder.setContentIntent(pendingIntent);\nbuilder.setAutoCancel(true);\nbuilder.setSmallIcon(R.drawable.ic_launcher);\n//this is added on the server side\nString text = intent.getStringExtra(\"text\");\nbuilder.setContentText(text);\nbuilder.setContentTitle(\"New message from the cloud!\");\nNotification noti = builder.build();\nNotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);\n//just set the mId to 1, because we don't care about it in this case\nmNotificationManager.notify(1, noti);\n",[79,694,695,700,705,710,715,720,725,730,735,740,745,750,755],{"__ignoreMap":77},[82,696,697],{"class":84,"line":85},[82,698,699],{},"NotificationCompat.Builder builder = new NotificationCompat.Builder(\n",[82,701,702],{"class":84,"line":200},[82,703,704],{}," context);\n",[82,706,707],{"class":84,"line":207},[82,708,709],{},"builder.setContentIntent(pendingIntent);\n",[82,711,712],{"class":84,"line":213},[82,713,714],{},"builder.setAutoCancel(true);\n",[82,716,717],{"class":84,"line":219},[82,718,719],{},"builder.setSmallIcon(R.drawable.ic_launcher);\n",[82,721,722],{"class":84,"line":225},[82,723,724],{},"//this is added on the server side\n",[82,726,727],{"class":84,"line":231},[82,728,729],{},"String text = intent.getStringExtra(\"text\");\n",[82,731,732],{"class":84,"line":237},[82,733,734],{},"builder.setContentText(text);\n",[82,736,737],{"class":84,"line":243},[82,738,739],{},"builder.setContentTitle(\"New message from the cloud!\");\n",[82,741,742],{"class":84,"line":249},[82,743,744],{},"Notification noti = builder.build();\n",[82,746,747],{"class":84,"line":255},[82,748,749],{},"NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);\n",[82,751,752],{"class":84,"line":328},[82,753,754],{},"//just set the mId to 1, because we don't care about it in this case\n",[82,756,757],{"class":84,"line":334},[82,758,759],{},"mNotificationManager.notify(1, noti);\n",[23,761,762],{},"That’ it with the GCMIntentService.",[23,764,765],{},"Now we let the app register itself with GCM in our MainActivity, which is fairly easy:",[72,767,769],{"className":188,"code":768,"language":190,"meta":77,"style":77},"//set your senderId from the API here!\n private static final String SENDER_ID = \"1234567890\";\n@Override\nprotected void onCreate(Bundle savedInstanceState) {\n GCMRegistrar.checkDevice(this);\n GCMRegistrar.checkManifest(this);\n final String regId = GCMRegistrar.getRegistrationId(this);\n // if we don't have a regId yet, register at gcm\n if (regId.equals(\"\")) {\n GCMRegistrar.register(this, SENDER_ID);\n Toast.makeText(getApplicationContext(), \"Registered GCM!\", Toast.LENGTH_LONG).show();\n // just log the registrationId for this test case.\n Log.i(this.getClass().getName(), \"id: \" + GCMRegistrar.getRegistrationId(this));\n } else {\n Log.i(this.getClass().getName(), \"Already registered\");\n Toast.makeText(getApplicationContext(), \"Already registered at GCM!\", Toast.LENGTH_LONG).show();\n Log.i(this.getClass().getName(), \"id: \" + GCMRegistrar.getRegistrationId(this));\n }\n}\n",[79,770,771,776,781,786,791,796,801,806,811,816,821,826,831,836,841,846,852,857,863],{"__ignoreMap":77},[82,772,773],{"class":84,"line":85},[82,774,775],{},"//set your senderId from the API here!\n",[82,777,778],{"class":84,"line":200},[82,779,780],{}," private static final String SENDER_ID = \"1234567890\";\n",[82,782,783],{"class":84,"line":207},[82,784,785],{},"@Override\n",[82,787,788],{"class":84,"line":213},[82,789,790],{},"protected void onCreate(Bundle savedInstanceState) {\n",[82,792,793],{"class":84,"line":219},[82,794,795],{}," GCMRegistrar.checkDevice(this);\n",[82,797,798],{"class":84,"line":225},[82,799,800],{}," GCMRegistrar.checkManifest(this);\n",[82,802,803],{"class":84,"line":231},[82,804,805],{}," final String regId = GCMRegistrar.getRegistrationId(this);\n",[82,807,808],{"class":84,"line":237},[82,809,810],{}," // if we don't have a regId yet, register at gcm\n",[82,812,813],{"class":84,"line":243},[82,814,815],{}," if (regId.equals(\"\")) {\n",[82,817,818],{"class":84,"line":249},[82,819,820],{}," GCMRegistrar.register(this, SENDER_ID);\n",[82,822,823],{"class":84,"line":255},[82,824,825],{}," Toast.makeText(getApplicationContext(), \"Registered GCM!\", Toast.LENGTH_LONG).show();\n",[82,827,828],{"class":84,"line":328},[82,829,830],{}," // just log the registrationId for this test case.\n",[82,832,833],{"class":84,"line":334},[82,834,835],{}," Log.i(this.getClass().getName(), \"id: \" + GCMRegistrar.getRegistrationId(this));\n",[82,837,838],{"class":84,"line":339},[82,839,840],{}," } else {\n",[82,842,843],{"class":84,"line":344},[82,844,845],{}," Log.i(this.getClass().getName(), \"Already registered\");\n",[82,847,849],{"class":84,"line":848},16,[82,850,851],{}," Toast.makeText(getApplicationContext(), \"Already registered at GCM!\", Toast.LENGTH_LONG).show();\n",[82,853,855],{"class":84,"line":854},17,[82,856,835],{},[82,858,860],{"class":84,"line":859},18,[82,861,862],{}," }\n",[82,864,866],{"class":84,"line":865},19,[82,867,656],{},[23,869,870],{},"Don’t forget to replace the SENDER_ID with yours!",[23,872,873],{},"I haven’t implemented a way to let the server know the registrationId, because reading it from the log seemed sufficient\nfor me in this case.",[23,875,876],{},"With this, we finished our small app and can begin implementing the server part.",[18,878,880],{"id":879},"the-web-application","The Web Application",[23,882,883],{},"For the Web Application, I created a maven web project with spring-webmvc and named it ‘GCMTestServer’. I’ll leave out\nthe config stuff for now, as everyone can use his/her favorite stack for this. The full sources with the configs are\nattached at the end of the blogpost.",[23,885,886,887,891],{},"Instead of just copying the GCM server library into the project, I searched a bit and found someone, who created a\nrepository for\nit. (",[99,888,889],{"href":889,"rel":890},"https://github.com/slorber/gcm-server-repository",[103],")",[23,893,894],{},"We start with creating the Sender class, which isn’t that hard either.",[72,896,898],{"className":188,"code":897,"language":190,"meta":77,"style":77},"public class GCMSender {\n public String apiKey = null;\n public GCMSender(String apiKey) {\n this.apiKey = apiKey;\n }\n public String send(String text, String id) throws IOException {\n Sender sender = new Sender(apiKey);\n Builder builder = new Message.Builder();\n builder.addData(\"text\", text);\n Result result = sender.send(builder.build(), id, 5);\n if (result.getMessageId() != null) {\n String canonicalRegId = result.getCanonicalRegistrationId();\n if (canonicalRegId != null) {\n // same device has more than on registration ID: update database\n return \"same device has more than on registration ID: update database\";\n }\n } else {\n String error = result.getErrorCodeName();\n if (error.equals(Constants.ERROR_NOT_REGISTERED)) {\n // application has been removed from device - unregister database\n return \"application has been removed from device - unregister database\";\n }\n }\n return null;\n }\n}\n",[79,899,900,905,910,915,920,925,930,935,940,945,950,955,960,965,970,975,980,985,990,995,1001,1007,1012,1017,1023,1028],{"__ignoreMap":77},[82,901,902],{"class":84,"line":85},[82,903,904],{},"public class GCMSender {\n",[82,906,907],{"class":84,"line":200},[82,908,909],{}," public String apiKey = null;\n",[82,911,912],{"class":84,"line":207},[82,913,914],{}," public GCMSender(String apiKey) {\n",[82,916,917],{"class":84,"line":213},[82,918,919],{}," this.apiKey = apiKey;\n",[82,921,922],{"class":84,"line":219},[82,923,924],{}," }\n",[82,926,927],{"class":84,"line":225},[82,928,929],{}," public String send(String text, String id) throws IOException {\n",[82,931,932],{"class":84,"line":231},[82,933,934],{}," Sender sender = new Sender(apiKey);\n",[82,936,937],{"class":84,"line":237},[82,938,939],{}," Builder builder = new Message.Builder();\n",[82,941,942],{"class":84,"line":243},[82,943,944],{}," builder.addData(\"text\", text);\n",[82,946,947],{"class":84,"line":249},[82,948,949],{}," Result result = sender.send(builder.build(), id, 5);\n",[82,951,952],{"class":84,"line":255},[82,953,954],{}," if (result.getMessageId() != null) {\n",[82,956,957],{"class":84,"line":328},[82,958,959],{}," String canonicalRegId = result.getCanonicalRegistrationId();\n",[82,961,962],{"class":84,"line":334},[82,963,964],{}," if (canonicalRegId != null) {\n",[82,966,967],{"class":84,"line":339},[82,968,969],{}," // same device has more than on registration ID: update database\n",[82,971,972],{"class":84,"line":344},[82,973,974],{}," return \"same device has more than on registration ID: update database\";\n",[82,976,977],{"class":84,"line":848},[82,978,979],{}," }\n",[82,981,982],{"class":84,"line":854},[82,983,984],{}," } else {\n",[82,986,987],{"class":84,"line":859},[82,988,989],{}," String error = result.getErrorCodeName();\n",[82,991,992],{"class":84,"line":865},[82,993,994],{}," if (error.equals(Constants.ERROR_NOT_REGISTERED)) {\n",[82,996,998],{"class":84,"line":997},20,[82,999,1000],{}," // application has been removed from device - unregister database\n",[82,1002,1004],{"class":84,"line":1003},21,[82,1005,1006],{}," return \"application has been removed from device - unregister database\";\n",[82,1008,1010],{"class":84,"line":1009},22,[82,1011,979],{},[82,1013,1015],{"class":84,"line":1014},23,[82,1016,862],{},[82,1018,1020],{"class":84,"line":1019},24,[82,1021,1022],{}," return null;\n",[82,1024,1026],{"class":84,"line":1025},25,[82,1027,924],{},[82,1029,1031],{"class":84,"line":1030},26,[82,1032,656],{},[23,1034,1035],{},"To send messages from the server, I created a small jsp page where I can enter the text and the RegistrationId of the\nuser to send the message to:",[72,1037,1041],{"className":1038,"code":1039,"language":1040,"meta":77,"style":77},"language-html shiki shiki-themes github-light github-dark","\u003C%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %> \u003C%@page\ncontentType=\"text/html\" pageEncoding=\"UTF-8\"%>\n\u003C!DOCTYPE html>\n\u003Chtml>\n \u003Chead>\n \u003Cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n \u003Clink\n rel=\"stylesheet\"\n type=\"text/css\"\n href=\"/GCMTestServer/frontend_resources/style.css\"\n media=\"screen\"\n />\n \u003Ctitle>GCM Sender\u003C/title>\n \u003C/head>\n \u003Cbody>\n \u003Ch1>GCM Sender\u003C/h1>\n \u003Cc:if test=\"${success == true}\">\n \u003Cdiv class=\"success\">sending successful!\u003C/div>\n \u003C/c:if>\n \u003Cc:if test=\"${error == true}\">\n \u003Cdiv class=\"error\">\n Error at sending!\n \u003Cp>${errormessage}\u003C/p>\n \u003C/div>\n \u003C/c:if>\n \u003Cform method=\"POST\">\n \u003Clabel for=\"text\">Text\u003C/label\n >\u003Cinput name=\"text\" id=\"text\" type=\"text\" />\u003Cbr />\n \u003Clabel for=\"id\">Registration-Id\u003C/label\n >\u003Cinput name=\"id\" id=\"id\" type=\"text\" />\u003Cbr />\n \u003Cinput type=\"submit\" />\n \u003C/form>\n \u003C/body>\n\u003C/html>\n","html",[79,1042,1043,1058,1063,1079,1087,1097,1126,1133,1143,1153,1163,1173,1178,1192,1201,1210,1222,1239,1262,1271,1286,1301,1306,1320,1329,1337,1354,1376,1414,1433,1464,1480,1489,1498],{"__ignoreMap":77},[82,1044,1045,1049,1053,1055],{"class":84,"line":85},[82,1046,1048],{"class":1047},"s7hpK","\u003C",[82,1050,1052],{"class":1051},"sVt8B","%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %> ",[82,1054,1048],{"class":1047},[82,1056,1057],{"class":1051},"%@page\n",[82,1059,1060],{"class":84,"line":200},[82,1061,1062],{"class":1051},"contentType=\"text/html\" pageEncoding=\"UTF-8\"%>\n",[82,1064,1065,1068,1072,1076],{"class":84,"line":207},[82,1066,1067],{"class":1051},"\u003C!",[82,1069,1071],{"class":1070},"s9eBZ","DOCTYPE",[82,1073,1075],{"class":1074},"sScJk"," html",[82,1077,1078],{"class":1051},">\n",[82,1080,1081,1083,1085],{"class":84,"line":213},[82,1082,1048],{"class":1051},[82,1084,1040],{"class":1070},[82,1086,1078],{"class":1051},[82,1088,1089,1092,1095],{"class":84,"line":219},[82,1090,1091],{"class":1051}," \u003C",[82,1093,1094],{"class":1070},"head",[82,1096,1078],{"class":1051},[82,1098,1099,1102,1105,1108,1111,1115,1118,1120,1123],{"class":84,"line":225},[82,1100,1101],{"class":1051}," \u003C",[82,1103,1104],{"class":1070},"meta",[82,1106,1107],{"class":1074}," http-equiv",[82,1109,1110],{"class":1051},"=",[82,1112,1114],{"class":1113},"sZZnC","\"Content-Type\"",[82,1116,1117],{"class":1074}," content",[82,1119,1110],{"class":1051},[82,1121,1122],{"class":1113},"\"text/html; charset=UTF-8\"",[82,1124,1125],{"class":1051}," />\n",[82,1127,1128,1130],{"class":84,"line":231},[82,1129,1101],{"class":1051},[82,1131,1132],{"class":1070},"link\n",[82,1134,1135,1138,1140],{"class":84,"line":237},[82,1136,1137],{"class":1074}," rel",[82,1139,1110],{"class":1051},[82,1141,1142],{"class":1113},"\"stylesheet\"\n",[82,1144,1145,1148,1150],{"class":84,"line":243},[82,1146,1147],{"class":1074}," type",[82,1149,1110],{"class":1051},[82,1151,1152],{"class":1113},"\"text/css\"\n",[82,1154,1155,1158,1160],{"class":84,"line":249},[82,1156,1157],{"class":1074}," href",[82,1159,1110],{"class":1051},[82,1161,1162],{"class":1113},"\"/GCMTestServer/frontend_resources/style.css\"\n",[82,1164,1165,1168,1170],{"class":84,"line":255},[82,1166,1167],{"class":1074}," media",[82,1169,1110],{"class":1051},[82,1171,1172],{"class":1113},"\"screen\"\n",[82,1174,1175],{"class":84,"line":328},[82,1176,1177],{"class":1051}," />\n",[82,1179,1180,1182,1185,1188,1190],{"class":84,"line":334},[82,1181,1101],{"class":1051},[82,1183,1184],{"class":1070},"title",[82,1186,1187],{"class":1051},">GCM Sender\u003C/",[82,1189,1184],{"class":1070},[82,1191,1078],{"class":1051},[82,1193,1194,1197,1199],{"class":84,"line":339},[82,1195,1196],{"class":1051}," \u003C/",[82,1198,1094],{"class":1070},[82,1200,1078],{"class":1051},[82,1202,1203,1205,1208],{"class":84,"line":344},[82,1204,1091],{"class":1051},[82,1206,1207],{"class":1070},"body",[82,1209,1078],{"class":1051},[82,1211,1212,1214,1216,1218,1220],{"class":84,"line":848},[82,1213,1101],{"class":1051},[82,1215,14],{"class":1070},[82,1217,1187],{"class":1051},[82,1219,14],{"class":1070},[82,1221,1078],{"class":1051},[82,1223,1224,1226,1229,1232,1234,1237],{"class":84,"line":854},[82,1225,1101],{"class":1051},[82,1227,1228],{"class":1047},"c:if",[82,1230,1231],{"class":1074}," test",[82,1233,1110],{"class":1051},[82,1235,1236],{"class":1113},"\"${success == true}\"",[82,1238,1078],{"class":1051},[82,1240,1241,1244,1247,1250,1252,1255,1258,1260],{"class":84,"line":859},[82,1242,1243],{"class":1051}," \u003C",[82,1245,1246],{"class":1070},"div",[82,1248,1249],{"class":1074}," class",[82,1251,1110],{"class":1051},[82,1253,1254],{"class":1113},"\"success\"",[82,1256,1257],{"class":1051},">sending successful!\u003C/",[82,1259,1246],{"class":1070},[82,1261,1078],{"class":1051},[82,1263,1264,1267,1269],{"class":84,"line":865},[82,1265,1266],{"class":1051}," \u003C/",[82,1268,1228],{"class":1047},[82,1270,1078],{"class":1051},[82,1272,1273,1275,1277,1279,1281,1284],{"class":84,"line":997},[82,1274,1101],{"class":1051},[82,1276,1228],{"class":1047},[82,1278,1231],{"class":1074},[82,1280,1110],{"class":1051},[82,1282,1283],{"class":1113},"\"${error == true}\"",[82,1285,1078],{"class":1051},[82,1287,1288,1290,1292,1294,1296,1299],{"class":84,"line":1003},[82,1289,1243],{"class":1051},[82,1291,1246],{"class":1070},[82,1293,1249],{"class":1074},[82,1295,1110],{"class":1051},[82,1297,1298],{"class":1113},"\"error\"",[82,1300,1078],{"class":1051},[82,1302,1303],{"class":84,"line":1009},[82,1304,1305],{"class":1051}," Error at sending!\n",[82,1307,1308,1311,1313,1316,1318],{"class":84,"line":1014},[82,1309,1310],{"class":1051}," \u003C",[82,1312,23],{"class":1070},[82,1314,1315],{"class":1051},">${errormessage}\u003C/",[82,1317,23],{"class":1070},[82,1319,1078],{"class":1051},[82,1321,1322,1325,1327],{"class":84,"line":1019},[82,1323,1324],{"class":1051}," \u003C/",[82,1326,1246],{"class":1070},[82,1328,1078],{"class":1051},[82,1330,1331,1333,1335],{"class":84,"line":1025},[82,1332,1266],{"class":1051},[82,1334,1228],{"class":1047},[82,1336,1078],{"class":1051},[82,1338,1339,1341,1344,1347,1349,1352],{"class":84,"line":1030},[82,1340,1101],{"class":1051},[82,1342,1343],{"class":1070},"form",[82,1345,1346],{"class":1074}," method",[82,1348,1110],{"class":1051},[82,1350,1351],{"class":1113},"\"POST\"",[82,1353,1078],{"class":1051},[82,1355,1357,1359,1362,1365,1367,1370,1373],{"class":84,"line":1356},27,[82,1358,1243],{"class":1051},[82,1360,1361],{"class":1070},"label",[82,1363,1364],{"class":1074}," for",[82,1366,1110],{"class":1051},[82,1368,1369],{"class":1113},"\"text\"",[82,1371,1372],{"class":1051},">Text\u003C/",[82,1374,1375],{"class":1070},"label\n",[82,1377,1379,1382,1385,1388,1390,1392,1395,1397,1399,1402,1404,1406,1409,1412],{"class":84,"line":1378},28,[82,1380,1381],{"class":1051}," >\u003C",[82,1383,1384],{"class":1070},"input",[82,1386,1387],{"class":1074}," name",[82,1389,1110],{"class":1051},[82,1391,1369],{"class":1113},[82,1393,1394],{"class":1074}," id",[82,1396,1110],{"class":1051},[82,1398,1369],{"class":1113},[82,1400,1401],{"class":1074}," type",[82,1403,1110],{"class":1051},[82,1405,1369],{"class":1113},[82,1407,1408],{"class":1051}," />\u003C",[82,1410,1411],{"class":1070},"br",[82,1413,1125],{"class":1051},[82,1415,1417,1419,1421,1423,1425,1428,1431],{"class":84,"line":1416},29,[82,1418,1243],{"class":1051},[82,1420,1361],{"class":1070},[82,1422,1364],{"class":1074},[82,1424,1110],{"class":1051},[82,1426,1427],{"class":1113},"\"id\"",[82,1429,1430],{"class":1051},">Registration-Id\u003C/",[82,1432,1375],{"class":1070},[82,1434,1436,1438,1440,1442,1444,1446,1448,1450,1452,1454,1456,1458,1460,1462],{"class":84,"line":1435},30,[82,1437,1381],{"class":1051},[82,1439,1384],{"class":1070},[82,1441,1387],{"class":1074},[82,1443,1110],{"class":1051},[82,1445,1427],{"class":1113},[82,1447,1394],{"class":1074},[82,1449,1110],{"class":1051},[82,1451,1427],{"class":1113},[82,1453,1401],{"class":1074},[82,1455,1110],{"class":1051},[82,1457,1369],{"class":1113},[82,1459,1408],{"class":1051},[82,1461,1411],{"class":1070},[82,1463,1125],{"class":1051},[82,1465,1467,1469,1471,1473,1475,1478],{"class":84,"line":1466},31,[82,1468,1243],{"class":1051},[82,1470,1384],{"class":1070},[82,1472,1401],{"class":1074},[82,1474,1110],{"class":1051},[82,1476,1477],{"class":1113},"\"submit\"",[82,1479,1125],{"class":1051},[82,1481,1483,1485,1487],{"class":84,"line":1482},32,[82,1484,1266],{"class":1051},[82,1486,1343],{"class":1070},[82,1488,1078],{"class":1051},[82,1490,1492,1494,1496],{"class":84,"line":1491},33,[82,1493,1196],{"class":1051},[82,1495,1207],{"class":1070},[82,1497,1078],{"class":1051},[82,1499,1501,1504,1506],{"class":84,"line":1500},34,[82,1502,1503],{"class":1051},"\u003C/",[82,1505,1040],{"class":1070},[82,1507,1078],{"class":1051},[23,1509,1510],{},"In the corresponding Controller to process the request, send the message:",[72,1512,1514],{"className":188,"code":1513,"language":190,"meta":77,"style":77}," @RequestMapping(value = \"send\", method = RequestMethod.POST)\n public String send(Model model,\n @RequestParam(\"text\") String text,\n @RequestParam(\"id\") String id) {\n String error = null;\n try {\n error = gcmSender.send(text, id);\n } catch (IOException ex) {\n model.addAttribute(\"error\", true);\n model.addAttribute(\"errormessage\", ex.getMessage());\n }\n if (error == null) {\n model.addAttribute(\"success\", true);\n } else {\n model.addAttribute(\"error\", true);\n model.addAttribute(\"errormessage\", error);\n }\n return \"sender\";\n }\n",[79,1515,1516,1521,1526,1531,1536,1541,1546,1551,1556,1561,1566,1570,1575,1580,1584,1588,1593,1597,1602],{"__ignoreMap":77},[82,1517,1518],{"class":84,"line":85},[82,1519,1520],{}," @RequestMapping(value = \"send\", method = RequestMethod.POST)\n",[82,1522,1523],{"class":84,"line":200},[82,1524,1525],{}," public String send(Model model,\n",[82,1527,1528],{"class":84,"line":207},[82,1529,1530],{}," @RequestParam(\"text\") String text,\n",[82,1532,1533],{"class":84,"line":213},[82,1534,1535],{}," @RequestParam(\"id\") String id) {\n",[82,1537,1538],{"class":84,"line":219},[82,1539,1540],{}," String error = null;\n",[82,1542,1543],{"class":84,"line":225},[82,1544,1545],{}," try {\n",[82,1547,1548],{"class":84,"line":231},[82,1549,1550],{}," error = gcmSender.send(text, id);\n",[82,1552,1553],{"class":84,"line":237},[82,1554,1555],{}," } catch (IOException ex) {\n",[82,1557,1558],{"class":84,"line":243},[82,1559,1560],{}," model.addAttribute(\"error\", true);\n",[82,1562,1563],{"class":84,"line":249},[82,1564,1565],{}," model.addAttribute(\"errormessage\", ex.getMessage());\n",[82,1567,1568],{"class":84,"line":255},[82,1569,246],{},[82,1571,1572],{"class":84,"line":328},[82,1573,1574],{}," if (error == null) {\n",[82,1576,1577],{"class":84,"line":334},[82,1578,1579],{}," model.addAttribute(\"success\", true);\n",[82,1581,1582],{"class":84,"line":339},[82,1583,234],{},[82,1585,1586],{"class":84,"line":344},[82,1587,1560],{},[82,1589,1590],{"class":84,"line":848},[82,1591,1592],{}," model.addAttribute(\"errormessage\", error);\n",[82,1594,1595],{"class":84,"line":854},[82,1596,246],{},[82,1598,1599],{"class":84,"line":859},[82,1600,1601],{}," return \"sender\";\n",[82,1603,1604],{"class":84,"line":865},[82,1605,252],{},[23,1607,1608],{},"Now we are ready to test it!",[23,1610,1611],{},"Start the app, copy the RegistrationId from the Logs, start the Server, enter the RegistrationId and a small text, and\nthere you go:",[23,1613,1614],{},[1615,1616],"img",{"alt":1617,"src":1618},"\"notification\"","https://media.synyx.de/uploads//2012/12/notification-300x221.jpg",[23,1620,1621],{},"To get a better understanding, you can also read the rest of the starting guide and the other documentation.",[23,1623,1624],{},"All together, it’s really easy to use the GCM libraries and the messages are beeing sent to the user very fast (around\none second for me). I haven’t tried to use it in a greater context with more users yet, but I don’t think google will\nfail on this behalf 😛",[23,1626,1627,1628],{},"As promised, here are the full sources:",[99,1629,1632],{"href":1630,"rel":1631},"https://media.synyx.de/uploads//2012/12/CloudMessageTest.zip",[103],"CloudMessageTest",[401,1634,1635],{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":77,"searchDepth":200,"depth":200,"links":1637},[1638,1639],{"id":466,"depth":200,"text":467},{"id":879,"depth":200,"text":880},[1641,1642],"mobile-blog","tutorial","2013-01-08T08:21:24","https://synyx.de/blog/a-small-look-into-google-cloud-messages/",{},"/blog/a-small-look-into-google-cloud-messages",{"title":440,"description":450},"blog/a-small-look-into-google-cloud-messages",[1650,1651,1652,1653,1654,432,1655],"android","cloud","gcm","google-cloud","messages","push-notification","Within the scope of some Android R&D I took a look at Google’s Cloud Message Service, GCM. Well, the starter guide at http://developer.android.com/google/gcm/gs.html is almost all you need to get started,…","Zo3lVe4ZoQawpHyu6_t-mMTQUwODaiJpqsdkWTxts5M",[1659,1662,1665,1668,1671,1674,1677,1680,1683,1686,1689,1692,1695,1698,1701,1704,1707,1710,1713,1716,1719,1722,1724,1727,1730,1733,1736,1738,1741,1744,1747,1750,1753,1756,1759,1762,1765,1768,1771,1774,1777,1780,1783,1786,1789,1792,1795,1798,1801,1804,1807,1809,1812,1815,1818,1821,1824,1827,1830,1833,1836,1839,1842,1844,1847,1850,1853,1856,1859,1862,1865,1868,1871,1874,1877,1880,1883,1886,1889,1892,1895,1898,1901,1904,1907,1910,1913,1916,1919,1922,1925,1928,1931,1934,1937,1940,1943,1946,1949,1951,1954,1957,1960,1963,1965,1968,1971,1974,1977,1980,1983,1986,1989,1992,1995,1998,2001,2004,2007,2010,2013,2016,2019,2022,2025,2028,2031,2034,2037,2040,2042,2045,2048,2051,2054,2057,2060,2063,2066,2069,2072,2075],{"slug":1660,"name":1661},"abel","Jennifer Abel",{"slug":1663,"name":1664},"allmendinger","Otto Allmendinger",{"slug":1666,"name":1667},"antony","Ben Antony",{"slug":1669,"name":1670},"arrasz","Joachim Arrasz",{"slug":1672,"name":1673},"bauer","David Bauer",{"slug":1675,"name":1676},"bechtold","Janine Bechtold",{"slug":1678,"name":1679},"boersig","Jasmin Börsig",{"slug":1681,"name":1682},"buch","Fabian Buch",{"slug":1684,"name":1685},"buchloh","Aljona Buchloh",{"slug":1687,"name":1688},"burgard","Julia Burgard",{"slug":1690,"name":1691},"caspar-schwedes","Caspar Schwedes",{"slug":1693,"name":1694},"christina-schmitt","Christina Schmitt",{"slug":1696,"name":1697},"clausen","Michael Clausen",{"slug":1699,"name":1700},"contargo_poetzsch","Thomas Pötzsch",{"slug":1702,"name":1703},"damrath","Sebastian Damrath",{"slug":1705,"name":1706},"daniel","Markus Daniel",{"slug":1708,"name":1709},"dasch","Julia Dasch",{"slug":1711,"name":1712},"denman","Joffrey Denman",{"slug":1714,"name":1715},"dfuchs","Daniel Fuchs",{"slug":1717,"name":1718},"dobler","Max Dobler",{"slug":1720,"name":1721},"dobriakov","Vladimir Dobriakov",{"slug":1723,"name":1723},"dreiqbik",{"slug":1725,"name":1726},"dschaefer","Denise Schäfer",{"slug":1728,"name":1729},"dschneider","Dominik Schneider",{"slug":1731,"name":1732},"duerlich","Isabell Duerlich",{"slug":1734,"name":1735},"dutkowski","Bernd Dutkowski",{"slug":1737,"name":1737},"eifler",{"slug":1739,"name":1740},"essig","Tim Essig",{"slug":1742,"name":1743},"ferstl","Maximilian Ferstl",{"slug":1745,"name":1746},"fey","Prisca Fey",{"slug":1748,"name":1749},"frank","Leonard Frank",{"slug":1751,"name":1752},"franke","Arnold Franke",{"slug":1754,"name":1755},"frischer","Nicolette Rudmann",{"slug":1757,"name":1758},"fuchs","Petra Fuchs",{"slug":1760,"name":1761},"gari","Sarah Gari",{"slug":1763,"name":1764},"gast","Gast",{"slug":1766,"name":1767},"graf","Johannes Graf",{"slug":1769,"name":1770},"grammlich","Daniela Grammlich",{"slug":1772,"name":1773},"guthardt","Sabrina Guthardt",{"slug":1775,"name":1776},"haeussler","Johannes Häussler",{"slug":1778,"name":1779},"hammann","Daniel Hammann",{"slug":1781,"name":1782},"heetel","Julian Heetel",{"slug":1784,"name":1785},"heft","Florian Heft",{"slug":1787,"name":1788},"heib","Sebastian Heib",{"slug":1790,"name":1791},"heisler","Ida Heisler",{"slug":1793,"name":1794},"helm","Patrick Helm",{"slug":1796,"name":1797},"herbold","Michael Herbold",{"slug":1799,"name":1800},"hofmann","Peter Hofmann",{"slug":1802,"name":1803},"hopf","Florian Hopf",{"slug":1805,"name":1806},"jaud","Alina Jaud",{"slug":9,"name":1808},"Robin De Silva Jayasinghe",{"slug":1810,"name":1811},"jbuch","Jonathan Buch",{"slug":1813,"name":1814},"junghanss","Gitta Junghanß",{"slug":1816,"name":1817},"kadyietska","Khrystyna Kadyietska",{"slug":1819,"name":1820},"kannegiesser","Marc Kannegiesser",{"slug":1822,"name":1823},"karoly","Robert Károly",{"slug":1825,"name":1826},"karrasz","Katja Arrasz-Schepanski",{"slug":1828,"name":1829},"kaufmann","Florian Kaufmann",{"slug":1831,"name":1832},"kesler","Mike Kesler",{"slug":1834,"name":1835},"kirchgaessner","Bettina Kirchgäßner",{"slug":1837,"name":1838},"klem","Yannic Klem",{"slug":1840,"name":1841},"klenk","Timo Klenk",{"slug":442,"name":1843},"Tobias Knell",{"slug":1845,"name":1846},"knoll","Anna-Lena Knoll",{"slug":1848,"name":1849},"knorre","Matthias Knorre",{"slug":1851,"name":1852},"koenig","Melanie König",{"slug":1854,"name":1855},"kraft","Thomas Kraft",{"slug":1857,"name":1858},"krupicka","Florian Krupicka",{"slug":1860,"name":1861},"kuehn","Christian Kühn",{"slug":1863,"name":1864},"lange","Christian Lange",{"slug":1866,"name":1867},"larrasz","Luca Arrasz",{"slug":1869,"name":1870},"leist","Sascha Leist",{"slug":1872,"name":1873},"lihs","Michael Lihs",{"slug":1875,"name":1876},"linsin","David Linsin",{"slug":1878,"name":1879},"maniyar","Christian Maniyar",{"slug":1881,"name":1882},"martin","Björnie",{"slug":1884,"name":1885},"martin-koch","Martin Koch",{"slug":1887,"name":1888},"matt","Tobias Matt",{"slug":1890,"name":1891},"mennerich","Christian Mennerich",{"slug":1893,"name":1894},"menz","Alexander Menz",{"slug":1896,"name":1897},"meseck","Frederick Meseck",{"slug":1899,"name":1900},"messner","Oliver Messner",{"slug":1902,"name":1903},"michael-ploed","Michael Plöd",{"slug":1905,"name":1906},"mies","Marius Mies",{"slug":1908,"name":1909},"mihai","Alina Mihai",{"slug":1911,"name":1912},"moeller","Jörg Möller",{"slug":1914,"name":1915},"mohr","Rebecca Mohr",{"slug":1917,"name":1918},"moretti","David Moretti",{"slug":1920,"name":1921},"mueller","Sven Müller",{"slug":1923,"name":1924},"muessig","Alexander Müssig",{"slug":1926,"name":1927},"neupokoev","Grigory Neupokoev",{"slug":1929,"name":1930},"nussbaecher","Carmen Nussbächer",{"slug":1932,"name":1933},"ochs","Pascal Ochs",{"slug":1935,"name":1936},"oelhoff","Jan Oelhoff",{"slug":1938,"name":1939},"oengel","Yasin Öngel",{"slug":1941,"name":1942},"oezsoy","Enis Özsoy",{"slug":1944,"name":1945},"posch","Maya Posch",{"slug":1947,"name":1948},"ralfmueller","Ralf Müller",{"slug":1950,"name":1950},"redakteur",{"slug":1952,"name":1953},"reich","Michael Reich",{"slug":1955,"name":1956},"reinhard","Karl-Ludwig Reinhard",{"slug":1958,"name":1959},"rmueller","Rebecca Müller",{"slug":1961,"name":1962},"rosum","Jan Rosum",{"slug":1964,"name":1964},"rueckert",{"slug":1966,"name":1967},"ruessel","Sascha Rüssel",{"slug":1969,"name":1970},"sauter","Moritz Sauter",{"slug":1972,"name":1973},"schaefer","Julian Schäfer",{"slug":1975,"name":1976},"scherer","Petra Scherer",{"slug":1978,"name":1979},"schlicht","Anne Schlicht",{"slug":1981,"name":1982},"schmidt","Jürgen Schmidt",{"slug":1984,"name":1985},"schneider","Tobias Schneider",{"slug":1987,"name":1988},"seber","Benjamin Seber",{"slug":1990,"name":1991},"sommer","Marc Sommer",{"slug":1993,"name":1994},"speaker-fels","Jakob Fels",{"slug":1996,"name":1997},"speaker-gierke","Oliver Gierke",{"slug":1999,"name":2000},"speaker-krupa","Malte Krupa",{"slug":2002,"name":2003},"speaker-mader","Jochen Mader",{"slug":2005,"name":2006},"speaker-meusel","Tim Meusel",{"slug":2008,"name":2009},"speaker-milke","Oliver Milke",{"slug":2011,"name":2012},"speaker-paluch","Mark Paluch",{"slug":2014,"name":2015},"speaker-schad","Jörg Schad",{"slug":2017,"name":2018},"speaker-schalanda","Jochen Schalanda",{"slug":2020,"name":2021},"speaker-schauder","Jens Schauder",{"slug":2023,"name":2024},"speaker-unterstein","Johannes Unterstein",{"slug":2026,"name":2027},"speaker-wolff","Eberhard Wolff",{"slug":2029,"name":2030},"speaker-zoerner","Stefan Zörner",{"slug":2032,"name":2033},"stefan-belger","Stefan Belger",{"slug":2035,"name":2036},"steinegger","Roland Steinegger",{"slug":2038,"name":2039},"stern","sternchen synyx",{"slug":2041,"name":2041},"synyx",{"slug":2043,"name":2044},"szulc","Mateusz Szulc",{"slug":2046,"name":2047},"tamara","Tamara Tunczinger",{"slug":2049,"name":2050},"theuer","Tobias Theuer",{"slug":2052,"name":2053},"thieme","Sandra Thieme",{"slug":2055,"name":2056},"thies-clasen","Marudor",{"slug":2058,"name":2059},"toernstroem","Olle Törnström",{"slug":2061,"name":2062},"ullinger","Max Ullinger",{"slug":2064,"name":2065},"ulrich","Stephan Ulrich",{"slug":2067,"name":2068},"wagner","Stefan Wagner",{"slug":2070,"name":2071},"weigel","Andreas Weigel",{"slug":2073,"name":2074},"werner","Fabian Werner",{"slug":2076,"name":2077},"wolke","Sören Wolke",["Reactive",2079],{"$scookieConsent":2080,"$ssite-config":2082},{"functional":2081,"analytics":2081},false,{"_priority":2083,"env":2087,"name":2088,"url":2089},{"name":2084,"env":2085,"url":2086},-10,-15,0,"production","nuxt-app","https://synyx.de",["Set"],["ShallowReactive",2092],{"category-messaging":-1,"authors":-1},"/blog/tags/messaging"]