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