{"id":4039,"date":"2012-12-16T08:21:43","date_gmt":"2012-12-16T04:21:43","guid":{"rendered":"http:\/\/blog.denivip.ru\/?p=4039"},"modified":"2013-08-05T14:10:35","modified_gmt":"2013-08-05T10:10:35","slug":"how-to-use-google-cloud-messaging-in-adobe-air-applications","status":"publish","type":"post","link":"http:\/\/blog.denivip.ru\/index.php\/2012\/12\/how-to-use-google-cloud-messaging-in-adobe-air-applications\/?lang=en","title":{"rendered":"How to Use Google Cloud Messaging in Adobe AIR Applications"},"content":{"rendered":"<p><center><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/12\/MobilePushNotifications.jpg\" alt=\"Using \\Google Cloud Messaging in Adobe AIR applications\" title=\"Using Google Cloud Messaging in Adobe AIR applications\" width=\"418\" height=\"287\" class=\"aligncenter size-full wp-image-3913\" srcset=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/12\/MobilePushNotifications.jpg 418w, http:\/\/blog.denivip.ru\/wp-content\/uploads\/2012\/12\/MobilePushNotifications-300x205.jpg 300w\" sizes=\"(max-width: 418px) 100vw, 418px\" \/><\/center><\/p>\n<p>However nice the multi-platform nature of AIR is, still it is a double-edged sword. On the one hand, we can write a Flex or ActionScript application that would work correctly on all possible platforms supported by AIR. On the other hand, developers feel much restricted by that AIR sometimes fails to provide all tools to fully use the functionality unique to a particular platform or device. Fortunately, we can write native extensions for a particular platform to implement features specific to this environment only. Such extensions are called Native Extensions and are attached to the AIR project as external libraries. <\/p>\n<p>In our work, we often use such extensions. Here we are going to discuss the <a href=\"https:\/\/github.com\/pwalczyszyn\/as3c2dm\">as3c2dm extension developed by Piotr Walczyszyn<\/a>. It allows you to receive push-messages and display them in the notification bar. In our work, we are actively using the extension. As we have detected a number of errors and inconveniences in it, we have tried to correct them. <!--more--><\/p>\n<p>The main error that we have faced is invalid application icon in the system tray if the application was built using captive runtime package. We often build applications so as to be able to install and use them on devices that do not have Adobe AIR. We have corrected this error.<\/p>\n<p>With our  update, the extension also allows you to split the logic of push-messages and their display in the notification bar. This way you can avoid displaying notifications each time a push-message arrives and do it later, whenever needed. Please feel free to use our update <a href=\"https:\/\/github.com\/denivip\/AIR-C2DM-android-native-extension\">on github.<\/a><\/p>\n<h3>Adding Extension to the Project<\/h3>\n<p>To use push-messages in the application project, connect c2dm.ane (Project Properties \u2192 Flex Build Path \u2192 &#171;Native Extensions&#187; tab \u2192 &#171;Add ANE &#8230;&#187; button).<\/p>\n<p>Next, in the XML file describing the application, among other things, specify:<\/p>\n<div class=\"codecolorer-container xml default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><div class=\"xml codecolorer\"><span class=\"sc3\">&lt;!\u2014 TODO: \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0435\u0437\u0434\u0435 \u0433\u0434\u0435 \u0434\u0430\u043b\u0435\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f ru.myDomain.myAppName \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0412\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u201cair\u201d. --<span class=\"re2\">&gt;<\/span><\/span> <br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;id<span class=\"re2\">&gt;<\/span><\/span><\/span>ru.myDomain.myAppName<span class=\"sc3\"><span class=\"re1\">&lt;\/id<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;android<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc3\"><span class=\"re1\">&lt;manifestAdditions<span class=\"re2\">&gt;<\/span><\/span><\/span><span class=\"sc2\">&lt;![CDATA[<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &lt;manifest android:installLocation=&quot;auto&quot;&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;permission android:protectionLevel=&quot;signature&quot; android:name=&quot;air. ru.myDomain.myAppName.permission.C2D_MESSAGE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;uses-permission android:name=&quot;air.ru.myDomain.myAppName.permission.C2D_MESSAGE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;uses-permission android:name=&quot;com.google.android.c2dm.permission.RECEIVE&quot; \/&gt;<\/span><br \/>\n<br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;application android:hardwareAccelerated=&quot;true&quot;&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;receiver android:name=&quot;com.riaspace.c2dm.C2DMBroadcastReceiver&quot; android:permission=&quot;com.google.android.c2dm.permission.SEND&quot;&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;action android:name=&quot;com.google.android.c2dm.intent.RECEIVE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;category android:name=&quot;air.ru.myDomain.myAppName&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;action android:name=&quot;com.google.android.c2dm.intent.REGISTRATION&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;category android:name=&quot;air.ru.myDomain.myAppName&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/receiver&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/application&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &lt;\/manifest&gt; <\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; ]]&gt;<\/span><span class=\"sc3\"><span class=\"re1\">&lt;\/manifestAdditions<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;\/android<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;extensions<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc3\"><span class=\"re1\">&lt;extensionID<span class=\"re2\">&gt;<\/span><\/span><\/span>com.riaspace.c2dm<span class=\"sc3\"><span class=\"re1\">&lt;\/extensionID<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;\/extensions<span class=\"re2\">&gt;<\/span><\/span><\/span><\/div><\/div>\n<p>And, naturally, you&#8217;ll need to add relevant code to the application. We are going to discuss this below.<\/p>\n<h3>Automatic Notification Display<\/h3>\n<p>We have decided to also leave the old functionality that automatically displays a message in the notification bar. By default, this functionality is disabled. To enable it, call <code class=\"codecolorer text default\"><span class=\"text\">enableAutoNotify()<\/span><\/code> from the <code class=\"codecolorer text default\"><span class=\"text\">C2DM<\/span><\/code> class:<\/p>\n<div class=\"codecolorer-container actionscript3 default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/><\/div><\/td><td><div class=\"actionscript3 codecolorer\"><span class=\"kw2\">var<\/span> c2dm<span class=\"sy0\">:<\/span>C2DM = <span class=\"kw1\">new<\/span> &nbsp;C2DM<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\nc2dm<span class=\"sy0\">.<\/span>enableAutoNotify<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>To disable automatic notification display, the <code class=\"codecolorer text default\"><span class=\"text\">disableAutoNotify()<\/span><\/code> method is used:<\/p>\n<div class=\"codecolorer-container actionscript3 default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"actionscript3 codecolorer\">c2dm<span class=\"sy0\">.<\/span>disableAutoNotify<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>When automatic notification display is disabled, the application should receive an event notifying it of a push-message received, and, by analyzing its parameters, be able to make a decision on what to do next: show a notification to the user, ignore it, show a popup, etc.<\/p>\n<h3>Required Fields on Sending Push Messages<\/h3>\n<p>To run the extension properly, the data object shall be passed with valid property names.<\/p>\n<p>For automatic notifications, Piotr Walczyszyn has provided the following data fields:<\/p>\n<ul>\n<li><code class=\"codecolorer text default\"><span class=\"text\">tickerText<\/span><\/code> &#8212; a message that briefly appears in the status bar at the time of receipt of the notification<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">contentTitle<\/span><\/code> &#8212; a message title shown when the notification panel is open<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">contentText<\/span><\/code> &#8212; message text<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">parameters<\/span><\/code> &#8212; parameters passed to the application when the user opens notification.<\/li>\n<\/ul>\n<p>More detailed information on the extension using automatic notifications can be found <a href=\"http:\/\/www.riaspace.com\/2011\/09\/as3c2dm-air-native-extension-to-push-notifications-with-c2dm\/\">here.<\/a><\/p>\n<p>When automatic notification display is disabled, we decided to use other fields:<\/p>\n<ul>\n<li><code class=\"codecolorer text default\"><span class=\"text\">messageType<\/span><\/code> &#8212; is the message type. By specifying this option, we can classify messages into different groups;<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">itemName<\/span><\/code> &#8212; is the name of the element contained in the notification<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">itemId<\/span><\/code> &#8212; ID of the element contained in the notification<\/li>\n<\/ul>\n<p>The <code class=\"codecolorer text default\"><span class=\"text\">itemName<\/span><\/code> and <code class=\"codecolorer text default\"><span class=\"text\">itemId<\/span><\/code> parameters are used in the event that a notification contains a certain element. For example, a Championship League match begins (message type &#8212; broadcast start), or Week&#8217;s subscription has ended (message type &#8212; subscription end). <\/p>\n<h3>Notification Arrival to the Application<\/h3>\n<p>Immediately after receiving a notification the <code class=\"codecolorer text default\"><span class=\"text\">C2DM<\/span><\/code> class  instance generates the <code class=\"codecolorer text default\"><span class=\"text\">C2DMMessageEvent.MESSAGE<\/span><\/code> event. To get details of the push-message, in the handler of the event use the <code class=\"codecolorer text default\"><span class=\"text\">message()<\/span><\/code> method from class <code class=\"codecolorer text default\"><span class=\"text\">C2DM<\/span><\/code> returning an instance of the <code class=\"codecolorer text default\"><span class=\"text\">C2DMMessage<\/span><\/code> class containing the message details.<\/p>\n<p>The <code class=\"codecolorer text default\"><span class=\"text\">C2DMMessage<\/span><\/code> class includes properties to contain the data sent in the push message that we have already mentioned above: <code class=\"codecolorer text default\"><span class=\"text\">messageType, itemName, itemId<\/span><\/code>.<\/p>\n<h3>Display a Message in the Notification Bar<\/h3>\n<p>To display a message in the notification bar, from the <code class=\"codecolorer text default\"><span class=\"text\">C2DM<\/span><\/code> class we have taken the <code class=\"codecolorer text default\"><span class=\"text\">showNotification(tickerText:String, contentTitle:String, contentText:String, parameters:String)<\/span><\/code> method accepting the following parameters:<\/p>\n<ul>\n<li><code class=\"codecolorer text default\"><span class=\"text\">tickerText<\/span><\/code> &#8212; the text that appears briefly in the status bar<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">contentTitle<\/span><\/code> &#8212; message title<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">contentText<\/span><\/code> &#8212; message text<\/li>\n<li><code class=\"codecolorer text default\"><span class=\"text\">parameters<\/span><\/code> &#8212; a string with custom parameters passed to the application when the user opens the message.<\/li>\n<\/ul>\n<p>Using this method, we can display a notification at any time, even for events not related to receiving of push-messages, and this is a very nice bonus.<\/p>\n<p>Here is an example of code that processes the push-message received, generates a notification, and, subsequently, shows it in the notification bar.<\/p>\n<div class=\"codecolorer-container actionscript3 default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/><\/div><\/td><td><div class=\"actionscript3 codecolorer\"><span class=\"kw1\">private<\/span> <span class=\"kw2\">var<\/span> c2dm<span class=\"sy0\">:<\/span>C2DM<span class=\"sy0\">;<\/span> <span class=\"kw1\">private<\/span> <span class=\"kw3\">function<\/span> <span class=\"kw7\">init<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><span class=\"kw1\">void<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n<span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>C2DM<span class=\"sy0\">.<\/span>isSupported<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; c2dm = <span class=\"kw1\">new<\/span> C2DM<span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">...........................................<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"sy0\">\/<\/span> <span class=\"sy0\">\/<\/span> Listen to events of arrival of push<span class=\"sy0\">-<\/span><span class=\"kw7\">message<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; c2dm<span class=\"sy0\">.<\/span><span class=\"kw7\">addEventListener<\/span><span class=\"br0\">&#40;<\/span>C2DMMessageEvent<span class=\"sy0\">.<\/span>MESSAGE<span class=\"sy0\">,<\/span> onMessage<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"kw1\">private<\/span> <span class=\"kw3\">function<\/span> onMessage<span class=\"br0\">&#40;<\/span>event<span class=\"sy0\">:<\/span>C2DMMessageEvent<span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><span class=\"kw1\">void<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> msg<span class=\"sy0\">:<\/span>C2DMMessage = c2dm<span class=\"sy0\">.<\/span><span class=\"kw7\">message<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> notifyTickerText<span class=\"sy0\">:<\/span><span class=\"kw5\">String<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> notifyContentTitle<span class=\"sy0\">:<\/span><span class=\"kw5\">String<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw2\">var<\/span> notifyContentText<span class=\"sy0\">:<\/span><span class=\"kw5\">String<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">switch<\/span> <span class=\"br0\">&#40;<\/span>msg <span class=\"sy0\">.<\/span>messageType<span class=\"br0\">&#41;<\/span> <br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ broadcast start<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">case<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">:<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyTickerText = <span class=\"st0\">&quot;Starting broadcast &quot;<\/span> <span class=\"sy0\">+<\/span> msg<span class=\"sy0\">.<\/span>itemName<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyContentTitle = <span class=\"st0\">&quot;Starting broadcast &quot;<\/span><span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyContentText = <span class=\"st0\">&quot;Starting broadcast &quot;<\/span> <span class=\"sy0\">+<\/span> msg<span class=\"sy0\">.<\/span>itemName <span class=\"sy0\">+<\/span> <span class=\"st0\">&quot;. View it? &quot;<\/span><span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">break<\/span><span class=\"sy0\">;<\/span> <br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/end subscription<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">case<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">:<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyTickerText = <span class=\"st0\">&quot;End of subscription&quot;<\/span><span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyContentTitle = <span class=\"st0\">&quot;End of subscription&quot;<\/span><span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; notifyContentText = <span class=\"st0\">&quot;End of subscription <span class=\"es0\">\\\u00ab<\/span>&quot;<\/span><span class=\"sy0\">+<\/span> msg<span class=\"sy0\">.<\/span>itemName<span class=\"sy0\">+<\/span><span class=\"st0\">&quot; <span class=\"es0\">\\ <\/span>\u00bb.&quot;<\/span><span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">break<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">default<\/span><span class=\"sy0\">:<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">break<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/ If all settings are correct, let's show the message in the notification bar<\/span><br \/>\n&nbsp; &nbsp; <span class=\"co1\">\/\/ Pass parameters containing message type and element ID as JSON string <\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>notifyTickerText <span class=\"sy0\">&amp;&amp;<\/span> notifyContentTitle <span class=\"sy0\">&amp;&amp;<\/span> notifyContentText<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; c2dm<span class=\"sy0\">.<\/span>showNotification<span class=\"br0\">&#40;<\/span>notifyTickerText<span class=\"sy0\">,<\/span>notifyContentTitle<span class=\"sy0\">,<\/span>notifyContentText<span class=\"sy0\">,<\/span> JSON<span class=\"sy0\">.<\/span>stringify<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#123;<\/span><span class=\"kw7\">type<\/span><span class=\"sy0\">:<\/span> msg<span class=\"sy0\">.<\/span>messageType<span class=\"sy0\">,<\/span> itemId<span class=\"sy0\">:<\/span> msg<span class=\"sy0\">.<\/span>itemId<span class=\"br0\">&#125;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<h3>Opening of Notification by User<\/h3>\n<p>In the example above, for the <code class=\"codecolorer text default\"><span class=\"text\">parameters<\/span><\/code> parameter we passed a JSON string encoding the object by its message type and ID of the element referred in the message. When a user opens notification, this string will be decoded into an object, analyzed and a decision made as to what to do next. For example, when a user opens a message that a UEFA Champions League match begins, we&#8217;ll need to open the video player to watch the match. Also, when a user opens the subscription end message, we should invoke a window with a proposal to extend  subscription, etc. <\/p>\n<p>In <code class=\"codecolorer text default\"><span class=\"text\">parameters<\/span><\/code> you should not necessarily pass a JSON string. We even can use one string if it contains a single parameter, or pass comma-separated values. It&#8217;s all up to the developer.<\/p>\n<p>Here is an example of how an application can handle event of user opening the notification:<\/p>\n<div class=\"codecolorer-container actionscript3 default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/><\/div><\/td><td><div class=\"actionscript3 codecolorer\"><span class=\"kw1\">private<\/span> <span class=\"kw3\">function<\/span> <span class=\"kw7\">init<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><span class=\"kw1\">void<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>C2DM<span class=\"sy0\">.<\/span>isSupported<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; \u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026\u2026<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ Subscribe to the event of user opening of notification NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onApplicationInvoke);<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"kw1\">private<\/span> <span class=\"kw3\">function<\/span> onApplicationInvoke<span class=\"br0\">&#40;<\/span>event<span class=\"sy0\">:<\/span>InvokeEvent<span class=\"br0\">&#41;<\/span><span class=\"sy0\">:<\/span><span class=\"kw1\">void<\/span><br \/>\n<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">if<\/span> <span class=\"br0\">&#40;<\/span>event<span class=\"sy0\">.<\/span><span class=\"kw5\">arguments<\/span><span class=\"sy0\">.<\/span><span class=\"kw7\">length<\/span> <span class=\"sy0\">&gt;<\/span> <span class=\"nu0\">0<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ decode the resulting string into an object to receive the passed parameters <\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">var<\/span> result<span class=\"sy0\">:<\/span><span class=\"kw5\">Object<\/span> = JSON<span class=\"sy0\">.<\/span><span class=\"kw7\">parse<\/span><span class=\"br0\">&#40;<\/span>event<span class=\"sy0\">.<\/span><span class=\"kw5\">arguments<\/span><span class=\"br0\">&#91;<\/span><span class=\"nu0\">0<\/span><span class=\"br0\">&#93;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">var<\/span> <span class=\"kw7\">type<\/span><span class=\"sy0\">:<\/span><span class=\"kw5\">String<\/span> = result<span class=\"sy0\">.<\/span><span class=\"kw7\">type<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">var<\/span> itemId<span class=\"sy0\">:<\/span><span class=\"kw5\">String<\/span> = result<span class=\"sy0\">.<\/span>itemId<span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">switch<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw5\">int<\/span><span class=\"br0\">&#40;<\/span><span class=\"kw7\">type<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ broadcast start<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">case<\/span> <span class=\"nu0\">0<\/span><span class=\"sy0\">:<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ Display the video player, passing to it an itemId containing the broadcast identifier <\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">break<\/span><span class=\"sy0\">;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ subscription ended <\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">case<\/span> <span class=\"nu0\">1<\/span><span class=\"sy0\">:<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#123;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ Display a window suggesting to extend subscription itemId<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">break<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span> <br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Therefore, even if there is a large number of unread messages in the notification bar, we can identify each of them when they are opened by the user.<\/p>\n<h3>Debugging of Application that have Received Push-Messages<\/h3>\n<p>In his video <a href=\"http:\/\/www.riaspace.com\/2012\/01\/as3c2dm-getting-started\/\">as3c2dm getting started<\/a>, Piotr Walczyszyn provides much detail on how to debug push-messages.<\/p>\n<p>Let&#8217;s view a short extract from the video.<\/p>\n<p>Among other properties, the xml-file that describes the application uses the the <code class=\"codecolorer text default\"><span class=\"text\">&lt;id&gt;<\/span><\/code> tag to set an unique identifier for each application:<\/p>\n<div class=\"codecolorer-container xml default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"xml codecolorer\"><span class=\"sc3\"><span class=\"re1\">&lt;id<span class=\"re2\">&gt;<\/span><\/span><\/span>ru.myDomain.myAppName<span class=\"sc3\"><span class=\"re1\">&lt;\/id<span class=\"re2\">&gt;<\/span><\/span><\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>AIR will automatically add the <i>air<\/i> prefix to this identifier. When the application is run in the debug mode, the main specifics is that this identifier is automatically extended with the &#171;debug&#187; suffix. So in case you need to debug your application, you have to amend the application description file by adding &#171;.debug&#187; wherever you find the application ID, except inside <code class=\"codecolorer text default\"><span class=\"text\">&lt;id&gt;<\/span><\/code>:<\/p>\n<div class=\"codecolorer-container xml default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><div class=\"xml codecolorer\">&nbsp;<span class=\"sc3\">&lt;!\u2014 TODO: Replace all occurrences of &nbsp;ru.myDomain.myAppName to your application ID, without forgetting the <span class=\"st0\">&quot;air&quot;<\/span> prefix. --<span class=\"re2\">&gt;<\/span><\/span> <br \/>\n<br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;id<span class=\"re2\">&gt;<\/span><\/span><\/span>ru.myDomain.myAppName<span class=\"sc3\"><span class=\"re1\">&lt;\/id<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;android<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc3\"><span class=\"re1\">&lt;manifestAdditions<span class=\"re2\">&gt;<\/span><\/span><\/span><span class=\"sc2\">&lt;![CDATA[<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &lt;manifest android:installLocation=&quot;auto&quot;&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;permission android:protectionLevel=&quot;signature&quot; android:name=&quot;air. ru.myDomain.myAppName.debug.permission.C2D_MESSAGE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;uses-permission android:name=&quot;air.ru.myDomain.myAppName.debug.permission.C2D_MESSAGE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;uses-permission android:name=&quot;com.google.android.c2dm.permission.RECEIVE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;application android:hardwareAccelerated=&quot;true&quot;&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;receiver android:name=&quot;com.riaspace.c2dm.C2DMBroadcastReceiver&quot; android:permission=&quot;com.google.android.c2dm.permission.SEND&quot;&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;action android:name=&quot;com.google.android.c2dm.intent.RECEIVE&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;category android:name=&quot;air.ru.myDomain.debug.myAppName &quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;action android:name=&quot;com.google.android.c2dm.intent.REGISTRATION&quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;category android:name=&quot;air.ru.myDomain.debug.myAppName &quot; \/&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/intent-filter&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/receiver&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;\/application&gt;<\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; &nbsp; &nbsp; &lt;\/manifest&gt; <\/span><br \/>\n<span class=\"sc2\">&nbsp; &nbsp; ]]&gt;<\/span><span class=\"sc3\"><span class=\"re1\">&lt;\/manifestAdditions<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;\/android<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;extensions<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n&nbsp; &nbsp; <span class=\"sc3\"><span class=\"re1\">&lt;extensionID<span class=\"re2\">&gt;<\/span><\/span><\/span>com.riaspace.c2dm<span class=\"sc3\"><span class=\"re1\">&lt;\/extensionID<span class=\"re2\">&gt;<\/span><\/span><\/span><br \/>\n<span class=\"sc3\"><span class=\"re1\">&lt;\/extensions<span class=\"re2\">&gt;<\/span><\/span><\/span><\/div><\/div>\n<p>For convenience, next to the description file we store two twin files with parameters to run the application with\/without the debug mode.<\/p>\n<p>We hope that our enhancements will help you write applications based on Google Cloud Messaging.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>However nice the multi-platform nature of AIR is, still it is a double-edged sword. On the one hand, we can write a Flex or ActionScript application that would work correctly on all possible platforms supported by AIR. On the other hand, developers feel much restricted by that AIR sometimes fails to provide all tools to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[455,451,355,20],"tags":[523,408,481,521,448,478],"_links":{"self":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/4039"}],"collection":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/comments?post=4039"}],"version-history":[{"count":6,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/4039\/revisions"}],"predecessor-version":[{"id":4836,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/4039\/revisions\/4836"}],"wp:attachment":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/media?parent=4039"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/categories?post=4039"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/tags?post=4039"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}