\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",[79,970,971,975,980,985,990,995,1000,1005,1010,1015,1020,1025,1030],{"__ignoreMap":77},[82,972,973],{"class":84,"line":85},[82,974,643],{"emptyLinePlaceholder":490},[82,976,977],{"class":84,"line":109},[82,978,979],{},"\u003Cpermission\n",[82,981,982],{"class":84,"line":133},[82,983,984],{}," android:name=\"com.synyx.cloudmessagetest.permission.C2D_MESSAGE\"\n",[82,986,987],{"class":84,"line":154},[82,988,989],{}," android:protectionLevel=\"signature\"/>\n",[82,991,992],{"class":84,"line":163},[82,993,994],{},"\u003Cuses-permission android:name=\"com.synyx.cloudmessagetest.permission.C2D_MESSAGE\"/>\n",[82,996,997],{"class":84,"line":232},[82,998,999],{}," \u003C!-- App receives GCM messages. -->\n",[82,1001,1002],{"class":84,"line":620},[82,1003,1004],{},"\u003Cuses-permission android:name=\"com.google.android.c2dm.permission.RECEIVE\"/>\n",[82,1006,1007],{"class":84,"line":676},[82,1008,1009],{}," \u003C!-- GCM connects to Google Services. -->\n",[82,1011,1012],{"class":84,"line":738},[82,1013,1014],{},"\u003Cuses-permission android:name=\"android.permission.INTERNET\"/>\n",[82,1016,1017],{"class":84,"line":744},[82,1018,1019],{}," \u003C!-- GCM requires a Google account. -->\n",[82,1021,1022],{"class":84,"line":750},[82,1023,1024],{},"\u003Cuses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>\n",[82,1026,1027],{"class":84,"line":756},[82,1028,1029],{}," \u003C!-- Keeps the processor from sleeping when a message is received. -->\n",[82,1031,1032],{"class":84,"line":762},[82,1033,1034],{},"\u003Cuses-permission android:name=\"android.permission.WAKE_LOCK\"/>\n",[18,1036,1037],{},"And declare a GCM broadcast receiver within the application tag:",[72,1039,1041],{"className":691,"code":1040,"language":693,"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,1042,1043,1047,1052,1057,1062,1067,1072,1077,1082,1087,1092],{"__ignoreMap":77},[82,1044,1045],{"class":84,"line":85},[82,1046,643],{"emptyLinePlaceholder":490},[82,1048,1049],{"class":84,"line":109},[82,1050,1051],{},"\u003Creceiver\n",[82,1053,1054],{"class":84,"line":133},[82,1055,1056],{}," android:name=\"com.google.android.gcm.GCMBroadcastReceiver\"\n",[82,1058,1059],{"class":84,"line":154},[82,1060,1061],{}," android:permission=\"com.google.android.c2dm.permission.SEND\">\n",[82,1063,1064],{"class":84,"line":163},[82,1065,1066],{}," \u003Cintent-filter>\n",[82,1068,1069],{"class":84,"line":232},[82,1070,1071],{}," \u003Caction android:name=\"com.google.android.c2dm.intent.RECEIVE\"/>\n",[82,1073,1074],{"class":84,"line":620},[82,1075,1076],{}," \u003Caction android:name=\"com.google.android.c2dm.intent.REGISTRATION\"/>\n",[82,1078,1079],{"class":84,"line":676},[82,1080,1081],{}," \u003Ccategory android:name=\"com.synyx.cloudmessagetest\"/>\n",[82,1083,1084],{"class":84,"line":738},[82,1085,1086],{}," \u003C/intent-filter>\n",[82,1088,1089],{"class":84,"line":744},[82,1090,1091],{},"\u003C/receiver>\n",[82,1093,1094],{"class":84,"line":750},[82,1095,1096],{},"\u003Cservice android:name=\".GCMIntentService\"/>\n",[18,1098,1099],{},"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,1101,1103],{"className":583,"code":1102,"language":585,"meta":77,"style":77},"public class GCMIntentService extends GCMBaseIntentService {\n",[79,1104,1105],{"__ignoreMap":77},[82,1106,1107],{"class":84,"line":85},[82,1108,1102],{},[18,1110,1111],{},"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.",[18,1113,1114],{},"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.",[18,1116,1117],{},"First in the onMessage() method, we need to get access to the Main Thread of our App.",[72,1119,1121],{"className":583,"code":1120,"language":585,"meta":77,"style":77},"Handler h = new Handler(Looper.getMainLooper());\nh.post(new Runnable() {\n public void run() {\n }\n}\n",[79,1122,1123,1128,1133,1138,1143],{"__ignoreMap":77},[82,1124,1125],{"class":84,"line":85},[82,1126,1127],{},"Handler h = new Handler(Looper.getMainLooper());\n",[82,1129,1130],{"class":84,"line":109},[82,1131,1132],{},"h.post(new Runnable() {\n",[82,1134,1135],{"class":84,"line":133},[82,1136,1137],{}," public void run() {\n",[82,1139,1140],{"class":84,"line":154},[82,1141,1142],{}," }\n",[82,1144,1145],{"class":84,"line":163},[82,1146,1147],{},"}\n",[18,1149,1150],{},"In the run() method, we get us an Intent from our MainActivity",[72,1152,1154],{"className":583,"code":1153,"language":585,"meta":77,"style":77},"Intent notificationIntent = new Intent(context, CloudMessageTestActivity.class);\n",[79,1155,1156],{"__ignoreMap":77},[82,1157,1158],{"class":84,"line":85},[82,1159,1153],{},[18,1161,1162],{},"And then wrap it with a PendingIntent for the NotificationBuilder",[72,1164,1166],{"className":583,"code":1165,"language":585,"meta":77,"style":77},"PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,\n notificationIntent, 0);\n",[79,1167,1168,1173],{"__ignoreMap":77},[82,1169,1170],{"class":84,"line":85},[82,1171,1172],{},"PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,\n",[82,1174,1175],{"class":84,"line":109},[82,1176,1177],{}," notificationIntent, 0);\n",[18,1179,1180],{},"Finally, use the NotificationBuilder to create and send the notification",[72,1182,1184],{"className":583,"code":1183,"language":585,"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,1185,1186,1191,1196,1201,1206,1211,1216,1221,1226,1231,1236,1241,1246],{"__ignoreMap":77},[82,1187,1188],{"class":84,"line":85},[82,1189,1190],{},"NotificationCompat.Builder builder = new NotificationCompat.Builder(\n",[82,1192,1193],{"class":84,"line":109},[82,1194,1195],{}," context);\n",[82,1197,1198],{"class":84,"line":133},[82,1199,1200],{},"builder.setContentIntent(pendingIntent);\n",[82,1202,1203],{"class":84,"line":154},[82,1204,1205],{},"builder.setAutoCancel(true);\n",[82,1207,1208],{"class":84,"line":163},[82,1209,1210],{},"builder.setSmallIcon(R.drawable.ic_launcher);\n",[82,1212,1213],{"class":84,"line":232},[82,1214,1215],{},"//this is added on the server side\n",[82,1217,1218],{"class":84,"line":620},[82,1219,1220],{},"String text = intent.getStringExtra(\"text\");\n",[82,1222,1223],{"class":84,"line":676},[82,1224,1225],{},"builder.setContentText(text);\n",[82,1227,1228],{"class":84,"line":738},[82,1229,1230],{},"builder.setContentTitle(\"New message from the cloud!\");\n",[82,1232,1233],{"class":84,"line":744},[82,1234,1235],{},"Notification noti = builder.build();\n",[82,1237,1238],{"class":84,"line":750},[82,1239,1240],{},"NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);\n",[82,1242,1243],{"class":84,"line":756},[82,1244,1245],{},"//just set the mId to 1, because we don't care about it in this case\n",[82,1247,1248],{"class":84,"line":762},[82,1249,1250],{},"mNotificationManager.notify(1, noti);\n",[18,1252,1253],{},"That’ it with the GCMIntentService.",[18,1255,1256],{},"Now we let the app register itself with GCM in our MainActivity, which is fairly easy:",[72,1258,1260],{"className":583,"code":1259,"language":585,"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,1261,1262,1267,1272,1277,1282,1287,1292,1297,1302,1307,1312,1317,1322,1327,1332,1337,1342,1346,1351],{"__ignoreMap":77},[82,1263,1264],{"class":84,"line":85},[82,1265,1266],{},"//set your senderId from the API here!\n",[82,1268,1269],{"class":84,"line":109},[82,1270,1271],{}," private static final String SENDER_ID = \"1234567890\";\n",[82,1273,1274],{"class":84,"line":133},[82,1275,1276],{},"@Override\n",[82,1278,1279],{"class":84,"line":154},[82,1280,1281],{},"protected void onCreate(Bundle savedInstanceState) {\n",[82,1283,1284],{"class":84,"line":163},[82,1285,1286],{}," GCMRegistrar.checkDevice(this);\n",[82,1288,1289],{"class":84,"line":232},[82,1290,1291],{}," GCMRegistrar.checkManifest(this);\n",[82,1293,1294],{"class":84,"line":620},[82,1295,1296],{}," final String regId = GCMRegistrar.getRegistrationId(this);\n",[82,1298,1299],{"class":84,"line":676},[82,1300,1301],{}," // if we don't have a regId yet, register at gcm\n",[82,1303,1304],{"class":84,"line":738},[82,1305,1306],{}," if (regId.equals(\"\")) {\n",[82,1308,1309],{"class":84,"line":744},[82,1310,1311],{}," GCMRegistrar.register(this, SENDER_ID);\n",[82,1313,1314],{"class":84,"line":750},[82,1315,1316],{}," Toast.makeText(getApplicationContext(), \"Registered GCM!\", Toast.LENGTH_LONG).show();\n",[82,1318,1319],{"class":84,"line":756},[82,1320,1321],{}," // just log the registrationId for this test case.\n",[82,1323,1324],{"class":84,"line":762},[82,1325,1326],{}," Log.i(this.getClass().getName(), \"id: \" + GCMRegistrar.getRegistrationId(this));\n",[82,1328,1329],{"class":84,"line":768},[82,1330,1331],{}," } else {\n",[82,1333,1334],{"class":84,"line":774},[82,1335,1336],{}," Log.i(this.getClass().getName(), \"Already registered\");\n",[82,1338,1339],{"class":84,"line":780},[82,1340,1341],{}," Toast.makeText(getApplicationContext(), \"Already registered at GCM!\", Toast.LENGTH_LONG).show();\n",[82,1343,1344],{"class":84,"line":786},[82,1345,1326],{},[82,1347,1348],{"class":84,"line":791},[82,1349,1350],{}," }\n",[82,1352,1353],{"class":84,"line":797},[82,1354,1147],{},[18,1356,1357],{},"Don’t forget to replace the SENDER_ID with yours!",[18,1359,1360],{},"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.",[18,1362,1363],{},"With this, we finished our small app and can begin implementing the server part.",[522,1365,1367],{"id":1366},"the-web-application","The Web Application",[18,1369,1370],{},"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.",[18,1372,1373,1374,1378],{},"Instead of just copying the GCM server library into the project, I searched a bit and found someone, who created a\nrepository for\nit. (",[22,1375,1376],{"href":1376,"rel":1377},"https://github.com/slorber/gcm-server-repository",[26],")",[18,1380,1381],{},"We start with creating the Sender class, which isn’t that hard either.",[72,1383,1385],{"className":583,"code":1384,"language":585,"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,1386,1387,1392,1397,1402,1407,1412,1417,1422,1427,1432,1437,1442,1447,1452,1457,1462,1467,1472,1477,1482,1487,1492,1496,1500,1505,1509],{"__ignoreMap":77},[82,1388,1389],{"class":84,"line":85},[82,1390,1391],{},"public class GCMSender {\n",[82,1393,1394],{"class":84,"line":109},[82,1395,1396],{}," public String apiKey = null;\n",[82,1398,1399],{"class":84,"line":133},[82,1400,1401],{}," public GCMSender(String apiKey) {\n",[82,1403,1404],{"class":84,"line":154},[82,1405,1406],{}," this.apiKey = apiKey;\n",[82,1408,1409],{"class":84,"line":163},[82,1410,1411],{}," }\n",[82,1413,1414],{"class":84,"line":232},[82,1415,1416],{}," public String send(String text, String id) throws IOException {\n",[82,1418,1419],{"class":84,"line":620},[82,1420,1421],{}," Sender sender = new Sender(apiKey);\n",[82,1423,1424],{"class":84,"line":676},[82,1425,1426],{}," Builder builder = new Message.Builder();\n",[82,1428,1429],{"class":84,"line":738},[82,1430,1431],{}," builder.addData(\"text\", text);\n",[82,1433,1434],{"class":84,"line":744},[82,1435,1436],{}," Result result = sender.send(builder.build(), id, 5);\n",[82,1438,1439],{"class":84,"line":750},[82,1440,1441],{}," if (result.getMessageId() != null) {\n",[82,1443,1444],{"class":84,"line":756},[82,1445,1446],{}," String canonicalRegId = result.getCanonicalRegistrationId();\n",[82,1448,1449],{"class":84,"line":762},[82,1450,1451],{}," if (canonicalRegId != null) {\n",[82,1453,1454],{"class":84,"line":768},[82,1455,1456],{}," // same device has more than on registration ID: update database\n",[82,1458,1459],{"class":84,"line":774},[82,1460,1461],{}," return \"same device has more than on registration ID: update database\";\n",[82,1463,1464],{"class":84,"line":780},[82,1465,1466],{}," }\n",[82,1468,1469],{"class":84,"line":786},[82,1470,1471],{}," } else {\n",[82,1473,1474],{"class":84,"line":791},[82,1475,1476],{}," String error = result.getErrorCodeName();\n",[82,1478,1479],{"class":84,"line":797},[82,1480,1481],{}," if (error.equals(Constants.ERROR_NOT_REGISTERED)) {\n",[82,1483,1484],{"class":84,"line":802},[82,1485,1486],{}," // application has been removed from device - unregister database\n",[82,1488,1489],{"class":84,"line":807},[82,1490,1491],{}," return \"application has been removed from device - unregister database\";\n",[82,1493,1494],{"class":84,"line":812},[82,1495,1466],{},[82,1497,1498],{"class":84,"line":817},[82,1499,1350],{},[82,1501,1502],{"class":84,"line":823},[82,1503,1504],{}," return null;\n",[82,1506,1507],{"class":84,"line":828},[82,1508,1411],{},[82,1510,1511],{"class":84,"line":834},[82,1512,1147],{},[18,1514,1515],{},"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,1517,1521],{"className":1518,"code":1519,"language":1520,"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,1522,1523,1537,1542,1557,1565,1575,1603,1610,1620,1630,1640,1650,1655,1669,1678,1687,1699,1716,1739,1748,1763,1778,1783,1797,1806,1814,1831,1852,1889,1907,1937,1953,1962,1971],{"__ignoreMap":77},[82,1524,1525,1529,1532,1534],{"class":84,"line":85},[82,1526,1528],{"class":1527},"s7hpK","\u003C",[82,1530,1531],{"class":221},"%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %> ",[82,1533,1528],{"class":1527},[82,1535,1536],{"class":221},"%@page\n",[82,1538,1539],{"class":84,"line":109},[82,1540,1541],{"class":221},"contentType=\"text/html\" pageEncoding=\"UTF-8\"%>\n",[82,1543,1544,1547,1551,1554],{"class":84,"line":133},[82,1545,1546],{"class":221},"\u003C!",[82,1548,1550],{"class":1549},"s9eBZ","DOCTYPE",[82,1552,1553],{"class":88}," html",[82,1555,1556],{"class":221},">\n",[82,1558,1559,1561,1563],{"class":84,"line":154},[82,1560,1528],{"class":221},[82,1562,1520],{"class":1549},[82,1564,1556],{"class":221},[82,1566,1567,1570,1573],{"class":84,"line":163},[82,1568,1569],{"class":221}," \u003C",[82,1571,1572],{"class":1549},"head",[82,1574,1556],{"class":221},[82,1576,1577,1580,1583,1586,1589,1592,1595,1597,1600],{"class":84,"line":232},[82,1578,1579],{"class":221}," \u003C",[82,1581,1582],{"class":1549},"meta",[82,1584,1585],{"class":88}," http-equiv",[82,1587,1588],{"class":221},"=",[82,1590,1591],{"class":92},"\"Content-Type\"",[82,1593,1594],{"class":88}," content",[82,1596,1588],{"class":221},[82,1598,1599],{"class":92},"\"text/html; charset=UTF-8\"",[82,1601,1602],{"class":221}," />\n",[82,1604,1605,1607],{"class":84,"line":620},[82,1606,1579],{"class":221},[82,1608,1609],{"class":1549},"link\n",[82,1611,1612,1615,1617],{"class":84,"line":676},[82,1613,1614],{"class":88}," rel",[82,1616,1588],{"class":221},[82,1618,1619],{"class":92},"\"stylesheet\"\n",[82,1621,1622,1625,1627],{"class":84,"line":738},[82,1623,1624],{"class":88}," type",[82,1626,1588],{"class":221},[82,1628,1629],{"class":92},"\"text/css\"\n",[82,1631,1632,1635,1637],{"class":84,"line":744},[82,1633,1634],{"class":88}," href",[82,1636,1588],{"class":221},[82,1638,1639],{"class":92},"\"/GCMTestServer/frontend_resources/style.css\"\n",[82,1641,1642,1645,1647],{"class":84,"line":750},[82,1643,1644],{"class":88}," media",[82,1646,1588],{"class":221},[82,1648,1649],{"class":92},"\"screen\"\n",[82,1651,1652],{"class":84,"line":756},[82,1653,1654],{"class":221}," />\n",[82,1656,1657,1659,1662,1665,1667],{"class":84,"line":762},[82,1658,1579],{"class":221},[82,1660,1661],{"class":1549},"title",[82,1663,1664],{"class":221},">GCM Sender\u003C/",[82,1666,1661],{"class":1549},[82,1668,1556],{"class":221},[82,1670,1671,1674,1676],{"class":84,"line":768},[82,1672,1673],{"class":221}," \u003C/",[82,1675,1572],{"class":1549},[82,1677,1556],{"class":221},[82,1679,1680,1682,1685],{"class":84,"line":774},[82,1681,1569],{"class":221},[82,1683,1684],{"class":1549},"body",[82,1686,1556],{"class":221},[82,1688,1689,1691,1693,1695,1697],{"class":84,"line":780},[82,1690,1579],{"class":221},[82,1692,14],{"class":1549},[82,1694,1664],{"class":221},[82,1696,14],{"class":1549},[82,1698,1556],{"class":221},[82,1700,1701,1703,1706,1709,1711,1714],{"class":84,"line":786},[82,1702,1579],{"class":221},[82,1704,1705],{"class":1527},"c:if",[82,1707,1708],{"class":88}," test",[82,1710,1588],{"class":221},[82,1712,1713],{"class":92},"\"${success == true}\"",[82,1715,1556],{"class":221},[82,1717,1718,1721,1724,1727,1729,1732,1735,1737],{"class":84,"line":791},[82,1719,1720],{"class":221}," \u003C",[82,1722,1723],{"class":1549},"div",[82,1725,1726],{"class":88}," class",[82,1728,1588],{"class":221},[82,1730,1731],{"class":92},"\"success\"",[82,1733,1734],{"class":221},">sending successful!\u003C/",[82,1736,1723],{"class":1549},[82,1738,1556],{"class":221},[82,1740,1741,1744,1746],{"class":84,"line":797},[82,1742,1743],{"class":221}," \u003C/",[82,1745,1705],{"class":1527},[82,1747,1556],{"class":221},[82,1749,1750,1752,1754,1756,1758,1761],{"class":84,"line":802},[82,1751,1579],{"class":221},[82,1753,1705],{"class":1527},[82,1755,1708],{"class":88},[82,1757,1588],{"class":221},[82,1759,1760],{"class":92},"\"${error == true}\"",[82,1762,1556],{"class":221},[82,1764,1765,1767,1769,1771,1773,1776],{"class":84,"line":807},[82,1766,1720],{"class":221},[82,1768,1723],{"class":1549},[82,1770,1726],{"class":88},[82,1772,1588],{"class":221},[82,1774,1775],{"class":92},"\"error\"",[82,1777,1556],{"class":221},[82,1779,1780],{"class":84,"line":812},[82,1781,1782],{"class":221}," Error at sending!\n",[82,1784,1785,1788,1790,1793,1795],{"class":84,"line":817},[82,1786,1787],{"class":221}," \u003C",[82,1789,18],{"class":1549},[82,1791,1792],{"class":221},">${errormessage}\u003C/",[82,1794,18],{"class":1549},[82,1796,1556],{"class":221},[82,1798,1799,1802,1804],{"class":84,"line":823},[82,1800,1801],{"class":221}," \u003C/",[82,1803,1723],{"class":1549},[82,1805,1556],{"class":221},[82,1807,1808,1810,1812],{"class":84,"line":828},[82,1809,1743],{"class":221},[82,1811,1705],{"class":1527},[82,1813,1556],{"class":221},[82,1815,1816,1818,1821,1824,1826,1829],{"class":84,"line":834},[82,1817,1579],{"class":221},[82,1819,1820],{"class":1549},"form",[82,1822,1823],{"class":88}," method",[82,1825,1588],{"class":221},[82,1827,1828],{"class":92},"\"POST\"",[82,1830,1556],{"class":221},[82,1832,1833,1835,1838,1841,1843,1846,1849],{"class":84,"line":839},[82,1834,1720],{"class":221},[82,1836,1837],{"class":1549},"label",[82,1839,1840],{"class":88}," for",[82,1842,1588],{"class":221},[82,1844,1845],{"class":92},"\"text\"",[82,1847,1848],{"class":221},">Text\u003C/",[82,1850,1851],{"class":1549},"label\n",[82,1853,1854,1857,1860,1863,1865,1867,1870,1872,1874,1877,1879,1881,1884,1887],{"class":84,"line":844},[82,1855,1856],{"class":221}," >\u003C",[82,1858,1859],{"class":1549},"input",[82,1861,1862],{"class":88}," name",[82,1864,1588],{"class":221},[82,1866,1845],{"class":92},[82,1868,1869],{"class":88}," id",[82,1871,1588],{"class":221},[82,1873,1845],{"class":92},[82,1875,1876],{"class":88}," type",[82,1878,1588],{"class":221},[82,1880,1845],{"class":92},[82,1882,1883],{"class":221}," />\u003C",[82,1885,1886],{"class":1549},"br",[82,1888,1602],{"class":221},[82,1890,1891,1893,1895,1897,1899,1902,1905],{"class":84,"line":850},[82,1892,1720],{"class":221},[82,1894,1837],{"class":1549},[82,1896,1840],{"class":88},[82,1898,1588],{"class":221},[82,1900,1901],{"class":92},"\"id\"",[82,1903,1904],{"class":221},">Registration-Id\u003C/",[82,1906,1851],{"class":1549},[82,1908,1909,1911,1913,1915,1917,1919,1921,1923,1925,1927,1929,1931,1933,1935],{"class":84,"line":856},[82,1910,1856],{"class":221},[82,1912,1859],{"class":1549},[82,1914,1862],{"class":88},[82,1916,1588],{"class":221},[82,1918,1901],{"class":92},[82,1920,1869],{"class":88},[82,1922,1588],{"class":221},[82,1924,1901],{"class":92},[82,1926,1876],{"class":88},[82,1928,1588],{"class":221},[82,1930,1845],{"class":92},[82,1932,1883],{"class":221},[82,1934,1886],{"class":1549},[82,1936,1602],{"class":221},[82,1938,1940,1942,1944,1946,1948,1951],{"class":84,"line":1939},31,[82,1941,1720],{"class":221},[82,1943,1859],{"class":1549},[82,1945,1876],{"class":88},[82,1947,1588],{"class":221},[82,1949,1950],{"class":92},"\"submit\"",[82,1952,1602],{"class":221},[82,1954,1956,1958,1960],{"class":84,"line":1955},32,[82,1957,1743],{"class":221},[82,1959,1820],{"class":1549},[82,1961,1556],{"class":221},[82,1963,1965,1967,1969],{"class":84,"line":1964},33,[82,1966,1673],{"class":221},[82,1968,1684],{"class":1549},[82,1970,1556],{"class":221},[82,1972,1974,1977,1979],{"class":84,"line":1973},34,[82,1975,1976],{"class":221},"\u003C/",[82,1978,1520],{"class":1549},[82,1980,1556],{"class":221},[18,1982,1983],{},"In the corresponding Controller to process the request, send the message:",[72,1985,1987],{"className":583,"code":1986,"language":585,"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,1988,1989,1994,1999,2004,2009,2014,2019,2024,2029,2034,2039,2044,2049,2054,2059,2063,2068,2072,2077],{"__ignoreMap":77},[82,1990,1991],{"class":84,"line":85},[82,1992,1993],{}," @RequestMapping(value = \"send\", method = RequestMethod.POST)\n",[82,1995,1996],{"class":84,"line":109},[82,1997,1998],{}," public String send(Model model,\n",[82,2000,2001],{"class":84,"line":133},[82,2002,2003],{}," @RequestParam(\"text\") String text,\n",[82,2005,2006],{"class":84,"line":154},[82,2007,2008],{}," @RequestParam(\"id\") String id) {\n",[82,2010,2011],{"class":84,"line":163},[82,2012,2013],{}," String error = null;\n",[82,2015,2016],{"class":84,"line":232},[82,2017,2018],{}," try {\n",[82,2020,2021],{"class":84,"line":620},[82,2022,2023],{}," error = gcmSender.send(text, id);\n",[82,2025,2026],{"class":84,"line":676},[82,2027,2028],{}," } catch (IOException ex) {\n",[82,2030,2031],{"class":84,"line":738},[82,2032,2033],{}," model.addAttribute(\"error\", true);\n",[82,2035,2036],{"class":84,"line":744},[82,2037,2038],{}," model.addAttribute(\"errormessage\", ex.getMessage());\n",[82,2040,2041],{"class":84,"line":750},[82,2042,2043],{}," }\n",[82,2045,2046],{"class":84,"line":756},[82,2047,2048],{}," if (error == null) {\n",[82,2050,2051],{"class":84,"line":762},[82,2052,2053],{}," model.addAttribute(\"success\", true);\n",[82,2055,2056],{"class":84,"line":768},[82,2057,2058],{}," } else {\n",[82,2060,2061],{"class":84,"line":774},[82,2062,2033],{},[82,2064,2065],{"class":84,"line":780},[82,2066,2067],{}," model.addAttribute(\"errormessage\", error);\n",[82,2069,2070],{"class":84,"line":786},[82,2071,2043],{},[82,2073,2074],{"class":84,"line":791},[82,2075,2076],{}," return \"sender\";\n",[82,2078,2079],{"class":84,"line":797},[82,2080,1142],{},[18,2082,2083],{},"Now we are ready to test it!",[18,2085,2086],{},"Start the app, copy the RegistrationId from the Logs, start the Server, enter the RegistrationId and a small text, and\nthere you go:",[18,2088,2089],{},[444,2090],{"alt":2091,"src":2092},"\"notification\"","https://media.synyx.de/uploads//2012/12/notification-300x221.jpg",[18,2094,2095],{},"To get a better understanding, you can also read the rest of the starting guide and the other documentation.",[18,2097,2098],{},"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 😛",[18,2100,2101,2102],{},"As promised, here are the full sources:",[22,2103,2106],{"href":2104,"rel":2105},"https://media.synyx.de/uploads//2012/12/CloudMessageTest.zip",[26],"CloudMessageTest",[470,2108,2109],{},"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":109,"depth":109,"links":2111},[2112,2113],{"id":958,"depth":109,"text":959},{"id":1366,"depth":109,"text":1367},[2115,2116],"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":931,"description":941},{"loc":2120},"blog/a-small-look-into-google-cloud-messages",[2125,497,2126,2127,2128,2129,2130],"android","gcm","google-cloud","messages","messaging","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,…","kCPNVJ7BR1Cf_TWPma5H3tiKHo8VBAfn-zZVG4oTlow",[2134,2137,2140,2143,2146,2149,2152,2155,2158,2161,2164,2167,2170,2173,2176,2179,2182,2185,2188,2191,2194,2197,2199,2202,2205,2208,2211,2213,2216,2219,2222,2225,2228,2231,2234,2237,2240,2243,2246,2249,2252,2255,2258,2261,2264,2267,2270,2273,2276,2279,2282,2285,2288,2291,2294,2296,2299,2302,2305,2308,2311,2314,2317,2319,2322,2325,2328,2331,2334,2337,2340,2343,2346,2349,2352,2355,2358,2361,2364,2367,2370,2373,2376,2379,2382,2385,2388,2391,2394,2397,2400,2403,2406,2409,2412,2415,2418,2421,2424,2426,2429,2432,2435,2438,2440,2443,2446,2449,2452,2455,2458,2461,2464,2467,2470,2473,2476,2479,2482,2485,2488,2491,2494,2497,2500,2503,2506,2509,2512,2515,2517,2520,2523,2526,2529,2532,2535,2538,2541,2544,2547,2550],{"slug":2135,"name":2136},"abel","Jennifer Abel",{"slug":2138,"name":2139},"allmendinger","Otto Allmendinger",{"slug":2141,"name":2142},"antony","Ben Antony",{"slug":2144,"name":2145},"arrasz","Joachim Arrasz",{"slug":2147,"name":2148},"bauer","David Bauer",{"slug":2150,"name":2151},"bechtold","Janine Bechtold",{"slug":2153,"name":2154},"boersig","Jasmin Börsig",{"slug":2156,"name":2157},"buch","Fabian Buch",{"slug":2159,"name":2160},"buchloh","Aljona Buchloh",{"slug":2162,"name":2163},"burgard","Julia Burgard",{"slug":2165,"name":2166},"caspar-schwedes","Caspar Schwedes",{"slug":2168,"name":2169},"christina-schmitt","Christina Schmitt",{"slug":2171,"name":2172},"clausen","Michael Clausen",{"slug":2174,"name":2175},"contargo_poetzsch","Thomas Pötzsch",{"slug":2177,"name":2178},"damrath","Sebastian Damrath",{"slug":2180,"name":2181},"daniel","Markus Daniel",{"slug":2183,"name":2184},"dasch","Julia Dasch",{"slug":2186,"name":2187},"denman","Joffrey Denman",{"slug":2189,"name":2190},"dfuchs","Daniel Fuchs",{"slug":2192,"name":2193},"dobler","Max Dobler",{"slug":2195,"name":2196},"dobriakov","Vladimir Dobriakov",{"slug":2198,"name":2198},"dreiqbik",{"slug":2200,"name":2201},"dschaefer","Denise Schäfer",{"slug":2203,"name":2204},"dschneider","Dominik Schneider",{"slug":2206,"name":2207},"duerlich","Isabell Duerlich",{"slug":2209,"name":2210},"dutkowski","Bernd Dutkowski",{"slug":2212,"name":2212},"eifler",{"slug":2214,"name":2215},"essig","Tim Essig",{"slug":2217,"name":2218},"ferstl","Maximilian Ferstl",{"slug":2220,"name":2221},"fey","Prisca Fey",{"slug":2223,"name":2224},"frank","Leonard Frank",{"slug":2226,"name":2227},"franke","Arnold Franke",{"slug":2229,"name":2230},"frischer","Nicolette Rudmann",{"slug":2232,"name":2233},"fuchs","Petra Fuchs",{"slug":2235,"name":2236},"gari","Sarah Gari",{"slug":2238,"name":2239},"gast","Gast",{"slug":2241,"name":2242},"graf","Johannes Graf",{"slug":2244,"name":2245},"grammlich","Daniela Grammlich",{"slug":2247,"name":2248},"guthardt","Sabrina Guthardt",{"slug":2250,"name":2251},"haeussler","Johannes Häussler",{"slug":2253,"name":2254},"hammann","Daniel Hammann",{"slug":2256,"name":2257},"heetel","Julian Heetel",{"slug":2259,"name":2260},"heft","Florian Heft",{"slug":2262,"name":2263},"heib","Sebastian Heib",{"slug":2265,"name":2266},"heisler","Ida Heisler",{"slug":2268,"name":2269},"helm","Patrick Helm",{"slug":2271,"name":2272},"herbold","Michael Herbold",{"slug":2274,"name":2275},"hofmann","Peter Hofmann",{"slug":2277,"name":2278},"hopf","Florian Hopf",{"slug":2280,"name":2281},"jaud","Alina Jaud",{"slug":2283,"name":2284},"jayasinghe","Robin De Silva Jayasinghe",{"slug":2286,"name":2287},"jbuch","Jonathan Buch",{"slug":2289,"name":2290},"junghanss","Gitta Junghanß",{"slug":2292,"name":2293},"kadyietska","Khrystyna Kadyietska",{"slug":9,"name":2295},"Marc Kannegiesser",{"slug":2297,"name":2298},"karoly","Robert Károly",{"slug":2300,"name":2301},"karrasz","Katja Arrasz-Schepanski",{"slug":2303,"name":2304},"kaufmann","Florian Kaufmann",{"slug":2306,"name":2307},"kesler","Mike Kesler",{"slug":2309,"name":2310},"kirchgaessner","Bettina Kirchgäßner",{"slug":2312,"name":2313},"klem","Yannic Klem",{"slug":2315,"name":2316},"klenk","Timo Klenk",{"slug":933,"name":2318},"Tobias Knell",{"slug":2320,"name":2321},"knoll","Anna-Lena Knoll",{"slug":2323,"name":2324},"knorre","Matthias Knorre",{"slug":2326,"name":2327},"koenig","Melanie König",{"slug":2329,"name":2330},"kraft","Thomas Kraft",{"slug":2332,"name":2333},"krupicka","Florian Krupicka",{"slug":2335,"name":2336},"kuehn","Christian Kühn",{"slug":2338,"name":2339},"lange","Christian Lange",{"slug":2341,"name":2342},"larrasz","Luca Arrasz",{"slug":2344,"name":2345},"leist","Sascha Leist",{"slug":2347,"name":2348},"lihs","Michael Lihs",{"slug":2350,"name":2351},"linsin","David Linsin",{"slug":2353,"name":2354},"maniyar","Christian Maniyar",{"slug":2356,"name":2357},"martin","Björnie",{"slug":2359,"name":2360},"martin-koch","Martin Koch",{"slug":2362,"name":2363},"matt","Tobias Matt",{"slug":2365,"name":2366},"mennerich","Christian Mennerich",{"slug":2368,"name":2369},"menz","Alexander Menz",{"slug":2371,"name":2372},"meseck","Frederick Meseck",{"slug":2374,"name":2375},"messner","Oliver Messner",{"slug":2377,"name":2378},"michael-ploed","Michael Plöd",{"slug":2380,"name":2381},"mies","Marius Mies",{"slug":2383,"name":2384},"mihai","Alina Mihai",{"slug":2386,"name":2387},"moeller","Jörg Möller",{"slug":2389,"name":2390},"mohr","Rebecca Mohr",{"slug":2392,"name":2393},"moretti","David Moretti",{"slug":2395,"name":2396},"mueller","Sven Müller",{"slug":2398,"name":2399},"muessig","Alexander Müssig",{"slug":2401,"name":2402},"neupokoev","Grigory Neupokoev",{"slug":2404,"name":2405},"nussbaecher","Carmen Nussbächer",{"slug":2407,"name":2408},"ochs","Pascal Ochs",{"slug":2410,"name":2411},"oelhoff","Jan Oelhoff",{"slug":2413,"name":2414},"oengel","Yasin Öngel",{"slug":2416,"name":2417},"oezsoy","Enis Özsoy",{"slug":2419,"name":2420},"posch","Maya Posch",{"slug":2422,"name":2423},"ralfmueller","Ralf Müller",{"slug":2425,"name":2425},"redakteur",{"slug":2427,"name":2428},"reich","Michael Reich",{"slug":2430,"name":2431},"reinhard","Karl-Ludwig Reinhard",{"slug":2433,"name":2434},"rmueller","Rebecca Müller",{"slug":2436,"name":2437},"rosum","Jan Rosum",{"slug":2439,"name":2439},"rueckert",{"slug":2441,"name":2442},"ruessel","Sascha Rüssel",{"slug":2444,"name":2445},"sauter","Moritz Sauter",{"slug":2447,"name":2448},"schaefer","Julian Schäfer",{"slug":2450,"name":2451},"scherer","Petra Scherer",{"slug":2453,"name":2454},"schlicht","Anne Schlicht",{"slug":2456,"name":2457},"schmidt","Jürgen Schmidt",{"slug":2459,"name":2460},"schneider","Tobias Schneider",{"slug":2462,"name":2463},"seber","Benjamin Seber",{"slug":2465,"name":2466},"sommer","Marc Sommer",{"slug":2468,"name":2469},"speaker-fels","Jakob Fels",{"slug":2471,"name":2472},"speaker-gierke","Oliver Gierke",{"slug":2474,"name":2475},"speaker-krupa","Malte Krupa",{"slug":2477,"name":2478},"speaker-mader","Jochen Mader",{"slug":2480,"name":2481},"speaker-meusel","Tim Meusel",{"slug":2483,"name":2484},"speaker-milke","Oliver Milke",{"slug":2486,"name":2487},"speaker-paluch","Mark Paluch",{"slug":2489,"name":2490},"speaker-schad","Jörg Schad",{"slug":2492,"name":2493},"speaker-schalanda","Jochen Schalanda",{"slug":2495,"name":2496},"speaker-schauder","Jens Schauder",{"slug":2498,"name":2499},"speaker-unterstein","Johannes Unterstein",{"slug":2501,"name":2502},"speaker-wolff","Eberhard Wolff",{"slug":2504,"name":2505},"speaker-zoerner","Stefan Zörner",{"slug":2507,"name":2508},"stefan-belger","Stefan Belger",{"slug":2510,"name":2511},"steinegger","Roland Steinegger",{"slug":2513,"name":2514},"stern","sternchen synyx",{"slug":2516,"name":2516},"synyx",{"slug":2518,"name":2519},"szulc","Mateusz Szulc",{"slug":2521,"name":2522},"tamara","Tamara Tunczinger",{"slug":2524,"name":2525},"theuer","Tobias Theuer",{"slug":2527,"name":2528},"thieme","Sandra Thieme",{"slug":2530,"name":2531},"thies-clasen","Marudor",{"slug":2533,"name":2534},"toernstroem","Olle Törnström",{"slug":2536,"name":2537},"ullinger","Max Ullinger",{"slug":2539,"name":2540},"ulrich","Stephan Ulrich",{"slug":2542,"name":2543},"wagner","Stefan Wagner",{"slug":2545,"name":2546},"weigel","Andreas Weigel",{"slug":2548,"name":2549},"werner","Fabian Werner",{"slug":2551,"name":2552},"wolke","Sören Wolke",["Reactive",2554],{"$scookieConsent":2555,"$ssite-config":2557},{"functional":2556,"analytics":2556},false,{"_priority":2558,"env":2562,"name":2563,"url":2564},{"name":2559,"env":2560,"url":2561},-10,-15,0,"production","nuxt-app","https://synyx.de",["Set"],["ShallowReactive",2567],{"category-cloud":-1,"blog-authors":-1},"/blog/tags/cloud"]