Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add PushSampleApp for BB10

  • Loading branch information...
commit 4ee6c0b3429558429e8e4fe9a92d40d14f0badc4 1 parent e5936bc
Eduardo Pelegri-Llopart pelegri authored

Showing 53 changed files with 5,410 additions and 16 deletions. Show diff stats Hide diff stats

  1. +75 0 PushSampleApp/.actionScriptProperties
  2. +25 0 PushSampleApp/.project
  3. +3 0  PushSampleApp/.settings/org.eclipse.core.resources.prefs
  4. +132 0 PushSampleApp/README.md
  5. +48 0 PushSampleApp/src/PushReceiver-app.xml
  6. BIN  PushSampleApp/src/PushReceiver-icon.png
  7. BIN  PushSampleApp/src/PushReceiver-splash.png
  8. +581 0 PushSampleApp/src/PushReceiver.as
  9. +44 0 PushSampleApp/src/bar-descriptor.xml
  10. BIN  PushSampleApp/src/browser.png
  11. BIN  PushSampleApp/src/configicon.png
  12. BIN  PushSampleApp/src/deleteallicon.png
  13. BIN  PushSampleApp/src/markallicon.png
  14. BIN  PushSampleApp/src/memo.png
  15. +66 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/BaseDAOImpl.as
  16. +44 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/ConfigurationDAO.as
  17. +206 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/ConfigurationDAOImpl.as
  18. +44 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/PushDAO.as
  19. +246 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/PushDAOImpl.as
  20. +38 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/PushHistoryDAO.as
  21. +140 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/PushHistoryDAOImpl.as
  22. +41 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/UserDAO.as
  23. +170 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/UserDAOImpl.as
  24. +54 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/events/ConfigurationDialogEvent.as
  25. +33 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/events/SubscribeToPushInitiatorErrorEvent.as
  26. +33 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/events/SubscribeToPushInitiatorSuccessEvent.as
  27. +33 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/events/UnsubscribeFromPushInitiatorErrorEvent.as
  28. +33 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/events/UnsubscribeFromPushInitiatorSuccessEvent.as
  29. +50 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/ConfigurationService.as
  30. +72 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/ConfigurationServiceImpl.as
  31. +107 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/PushHandler.as
  32. +88 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/PushNotificationService.as
  33. +318 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/PushNotificationServiceImpl.as
  34. +229 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/RegisterHandler.as
  35. +219 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/service/UnregisterHandler.as
  36. +820 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/ActionBarHelper.as
  37. +199 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/ListContainer.as
  38. +259 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/dialog/ConfigurationDialog.as
  39. +77 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/dialog/HtmlContentDialog.as
  40. +107 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/dialog/ProgressAlertDialog.as
  41. +137 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/dialog/PushContentDialog.as
  42. +99 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/renderer/DateHeadingRenderer.as
  43. +340 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/ui/renderer/PushRenderer.as
  44. +59 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/vo/Configuration.as
  45. +66 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/vo/Push.as
  46. +38 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/vo/PushHistoryItem.as
  47. +35 0 PushSampleApp/src/net/rim/blackberry/pushreceiver/vo/User.as
  48. BIN  PushSampleApp/src/pictures.png
  49. BIN  PushSampleApp/src/registericon.png
  50. BIN  PushSampleApp/src/trash.png
  51. BIN  PushSampleApp/src/trashhighlight.png
  52. BIN  PushSampleApp/src/unregistericon.png
  53. +2 16 README.md
75 PushSampleApp/.actionScriptProperties
... ... @@ -0,0 +1,75 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<actionScriptProperties analytics="false" mainApplicationPath="PushReceiver.as" projectUUID="88d03bf1-7a97-4946-9bb6-1cdf29b6ea05" version="10">
  3 + <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="false" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="false" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="true" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
  4 + <compilerSourcePath/>
  5 + <libraryPath defaultLinkType="0">
  6 + <libraryPathEntry kind="4" path="">
  7 + <excludedEntries>
  8 + <libraryPathEntry kind="1" linkType="1" path="${PROJECT_FRAMEWORKS}/locale/{locale}"/>
  9 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/advancedgrids.swc" useDefaultLinkType="false"/>
  10 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_air.swc" useDefaultLinkType="false"/>
  11 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/charts.swc" useDefaultLinkType="false"/>
  12 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/netmon.swc" useDefaultLinkType="false"/>
  13 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="false"/>
  14 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
  15 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/>
  16 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/>
  17 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/>
  18 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/>
  19 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/authoringsupport.swc" useDefaultLinkType="false"/>
  20 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp.swc" useDefaultLinkType="false"/>
  21 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/framework.swc" useDefaultLinkType="false"/>
  22 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/airspark.swc" useDefaultLinkType="false"/>
  23 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/mx/mx.swc" useDefaultLinkType="false"/>
  24 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/applicationupdater.swc" useDefaultLinkType="false"/>
  25 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/utilities.swc" useDefaultLinkType="false"/>
  26 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
  27 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark_dmv.swc" useDefaultLinkType="false"/>
  28 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
  29 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
  30 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/>
  31 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/applicationupdater_ui.swc" useDefaultLinkType="false"/>
  32 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/air/airframework.swc" useDefaultLinkType="false"/>
  33 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/mobile/mobilecomponents.swc" useDefaultLinkType="false"/>
  34 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
  35 + </excludedEntries>
  36 + </libraryPathEntry>
  37 + <libraryPathEntry kind="3" linkType="2" path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/air/qnx-air.swc" useDefaultLinkType="false"/>
  38 + <libraryPathEntry kind="3" linkType="1" path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/qnx/qnxui.swc" useDefaultLinkType="false"/>
  39 + <libraryPathEntry kind="5" linkType="2" path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/blackberry/ane/BlackBerryPushService.ane"/>
  40 + <libraryPathEntry kind="5" linkType="2" path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/qnx/ane/QNXDevice.ane"/>
  41 + <libraryPathEntry kind="5" linkType="2" path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/qnx/ane/QNXSkins.ane"/>
  42 + </libraryPath>
  43 + <sourceAttachmentPath/>
  44 + </compiler>
  45 + <applications>
  46 + <application path="PushReceiver.as">
  47 + <airExcludes/>
  48 + </application>
  49 + </applications>
  50 + <modules/>
  51 + <buildCSSFiles/>
  52 + <flashCatalyst validateFlashCatalystCompatibility="false"/>
  53 + <buildTargets>
  54 + <buildTarget buildTargetName="com.qnx.flexide.multiplatform.qnx.platform" extraPackagingOptions="" signBarFile="true">
  55 + <airSettings airCertificatePath="" airTimestamp="true" anePathSet="true" version="1">
  56 + <airExcludes/>
  57 + <anePaths>
  58 + <anePathEntry path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/blackberry/ane/BlackBerryPushService.ane"/>
  59 + <anePathEntry path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/qnx/ane/QNXDevice.ane"/>
  60 + <anePathEntry path="C:/Developer/SDKs/blackberry-tablet-sdk-3.0.0/frameworks/libs/qnx/ane/QNXSkins.ane"/>
  61 + </anePaths>
  62 + </airSettings>
  63 + <multiPlatformSettings enabled="true" includePlatformLibs="false" platformID="com.qnx.flexide.multiplatform.qnx.platform" version="2"/>
  64 + <actionScriptSettings version="1"/>
  65 + </buildTarget>
  66 + <buildTarget buildTargetName="default">
  67 + <airSettings airCertificatePath="" airTimestamp="true" anePathSet="false" version="1">
  68 + <airExcludes/>
  69 + <anePaths/>
  70 + </airSettings>
  71 + <multiPlatformSettings enabled="false" includePlatformLibs="false" platformID="default" version="2"/>
  72 + <actionScriptSettings version="1"/>
  73 + </buildTarget>
  74 + </buildTargets>
  75 +</actionScriptProperties>
25 PushSampleApp/.project
... ... @@ -0,0 +1,25 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<projectDescription>
  3 + <name>PushReceiver</name>
  4 + <comment></comment>
  5 + <projects>
  6 + </projects>
  7 + <buildSpec>
  8 + <buildCommand>
  9 + <name>com.adobe.flexbuilder.project.flexbuilder</name>
  10 + <arguments>
  11 + </arguments>
  12 + </buildCommand>
  13 + <buildCommand>
  14 + <name>com.adobe.flexbuilder.project.apollobuilder</name>
  15 + <arguments>
  16 + </arguments>
  17 + </buildCommand>
  18 + </buildSpec>
  19 + <natures>
  20 + <nature>com.adobe.flexide.project.multiplatform.multiplatformasnature</nature>
  21 + <nature>com.adobe.flexide.project.multiplatform.multiplatformnature</nature>
  22 + <nature>com.adobe.flexbuilder.project.apollonature</nature>
  23 + <nature>com.adobe.flexbuilder.project.actionscriptnature</nature>
  24 + </natures>
  25 +</projectDescription>
3  PushSampleApp/.settings/org.eclipse.core.resources.prefs
... ... @@ -0,0 +1,3 @@
  1 +#Tue Jul 24 11:11:59 EDT 2012
  2 +eclipse.preferences.version=1
  3 +encoding/<project>=utf-8
132 PushSampleApp/README.md
Source Rendered
... ... @@ -0,0 +1,132 @@
  1 +# Push Receiver Sample Application Description #
  2 +
  3 +The Push Receiver sample application demonstrates how to write a BlackBerry 10 Adobe AIR application that is able to receive pushes.
  4 +
  5 +Consult the **net.rim.blackberry.push** package from the API reference for useful examples and a full description of how to use the
  6 +push APIs. The API reference can be found [here while in beta](https://developer.blackberry.com/air/beta/apis/) or, if no longer in beta,
  7 +[here](https://developer.blackberry.com/air/apis).
  8 +
  9 +There is also a very valuable developer guide for this sample push-enabled application that you can find [here](https://developer.blackberry.com/air/beta/documentation/overview_air_1976130_11.html)
  10 +
  11 +The developer guide offers the following topics:
  12 +
  13 +1. An overview of push and the Push Service architecture
  14 +2. The requirements for creating a full push solution
  15 +3. How to setup Adobe Flash Builder 4.6 to work with the Push Receiver sample application (This is also described below.)
  16 +4. How to use the sample application when it's loaded on your BlackBerry 10 device (This is also described below.)
  17 +5. Code samples to help you write your own push application using the BlackBerry 10 AIR SDK
  18 +
  19 +The sample code for this application is Open Source under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html).
  20 +
  21 +
  22 +**Applies To**
  23 +
  24 +* [BlackBerry 10 SDK for Adobe AIR Beta 2](https://developer.blackberry.com/air)
  25 +
  26 +**Author(s)**
  27 +
  28 +* [Matthew D'Andrea](https://github.com/mdandrea)
  29 +* [Marco Di Cesare](https://github.com/mdicesare)
  30 +
  31 +**To contribute code to this repository you must be [signed up as an official contributor](http://blackberry.github.com/howToContribute.html).**
  32 +
  33 +## How to Deploy
  34 +
  35 +If you downloaded the sample application as a zip you can deploy the pre-compiled Push Receiver sample application by:
  36 +
  37 +1. Take the provided PushReceiver.bar and deploy it using blackberry-deploy (or blackberry-deploy.bat) available from your BlackBerry 10 SDK for Adobe AIR install:
  38 +Adobe-AIR-SDK-install-directory/bin/blackberry-deploy
  39 +2. Deploy the application using the following syntax:
  40 +``blackberry-deploy -installApp -password <device password> -device <IP_address> -package <BAR file path>/PushReceiver.bar``
  41 +
  42 +
  43 +## How to Build
  44 +
  45 +The project files supplied are for Flash Builder 4.6 [http://www.adobe.com/products/flash-builder.html](http://www.adobe.com/products/flash-builder.html)
  46 +
  47 +Note: You will need to first download the [BlackBerry 10 SDK for Adobe AIR Beta 2](https://developer.blackberry.com/air).
  48 +
  49 +You can import the existing project files in Adobe Flash Builder 4.6 and build/deploy it from there:
  50 +
  51 +1. In Flash Builder select File > Import and select the root folder.
  52 +2. Run the **PushReceiver** project by right-clicking on the project and going to **Run As/Debug As > Mobile Application**.
  53 +
  54 +Or, you can create a brand new project in Adobe Flash Builder 4.6 and build/deploy it from there, for example:
  55 +
  56 +1. Start Adobe Flash Builder.
  57 +2. Click **File > New > ActionScript Mobile Project**.
  58 +3. In the Project Name field, type **PushReceiver**.
  59 +4. Clear the **Use default location** check box and browse to the **pushReceiver** folder you unzipped in step 3. Also, make sure that the default SDK is the Adobe Flex SDK 4.6.
  60 +5. Click **Next**.
  61 +6. In the **Target platforms** list, select **BlackBerry Tablet OS**.
  62 +7. Click **Next**.
  63 +8. On the **Library** path tab, perform the following actions:
  64 + 1. Click **Add SWC**.
  65 + 2. Locate and add Adobe-AIR-SDK-install-directory\frameworks\libs\qnx\qnxui.swc, where Adobe-AIR-SDK-install-directory is the directory where the BlackBerry 10 SDK for Adobe AIR is installed.
  66 + 3. Click **Add SWC**.
  67 + 4. Locate and add Adobe-AIR-SDK-install-directory\frameworks\libs\air\qnx-air.swc.
  68 + 5. Change the link type to **External**.
  69 +9. On the **Native Extensions** tab, perform the following actions:
  70 + 1. Click **Add ANE**.
  71 + 2. Locate and add Adobe-AIR-SDK-install-directory\frameworks\libs\blackberry\ane\BlackBerryPushService.ane.
  72 + 3. Locate and add Adobe-AIR-SDK-install-directory\frameworks\libs\qnx\ane\QNXDevice.ane.
  73 + 4. Locate and add Adobe-AIR-SDK-install-directory\frameworks\libs\qnx\ane\QNXSkins.ane.
  74 +10. Click **Finish**.
  75 +11. Run the **PushReceiver** project by right-clicking on the project and going to **Run As/Debug As > Mobile Application**.
  76 +
  77 +
  78 +## How to send a push
  79 +
  80 +In order to be able to send pushes to the Push Receiver sample app, you will need to write a server-side push application (called a Push Initiator) to send out pushes with.
  81 +Luckily, this is fairly easy to do using the Push Service SDK available [here](https://developer.blackberry.com/services/push).
  82 +
  83 +You'll find all the documentation for the Push Service SDK [here](http://docs.blackberry.com/en/developers/subcategories/?userType=21&category=Push+Service).
  84 +
  85 +Note that in order to use the Push Service for developing an application for the general public, you will have to first register [here](https://www.blackberry.com/profile/?eventId=8121).
  86 +
  87 +
  88 +## How to receive a push
  89 +
  90 +1. Start the Push Receiver sample application (if you haven't done so already).
  91 +2. Tap the **Config** action at the bottom of the device screen. The configuration dialog will appear.
  92 +3. Click **Public/BIS** if the PPG is the BlackBerry Internet Service or **Enterprise/BES** if the PPG is the BlackBerry Enterprise Server.
  93 +4. Clear the **Use Push Service SDK as Push Initiator** check box if one of the following is true:
  94 + * You implemented a Push Initiator that does not use the Push Service SDK.
  95 + * Your Push Initiator only uses the low-level APIs without subscription support from the Push Service SDK.
  96 +5. If the **Use Push Service SDK as Push Initiator** check box is selected, in the **Application ID** field, perform one of the
  97 +following actions:
  98 + * If you are using the BlackBerry Internet Service as the PPG, type the application ID specified in the confirmation
  99 +email message that you received from RIM.
  100 + * If you are using the BlackBerry Enterprise Server as the PPG, type a unique application ID of your choosing. If you
  101 +clear the **Use Push Service SDK as Push Initiator** check box, you cannot type an application ID. In this case, the
  102 +Push Service APIs create an application ID for you automatically.
  103 +6. If you are using the BlackBerry Internet Service as the PPG, in the **PPG URL** field, type the PPG base URL specified in
  104 +the confirmation email message. The sample application uses this URL to create a channel to the PPG. For an
  105 +evaluation environment, the URL is http://cp{cpid}.pushapi.eval.blackberry.com, where {cpid} is your content
  106 +provider ID. For a production environment, the URL is http://cp{cpid}.pushapi.na.blackberry.com.
  107 +7. If the **Use Push Service SDK as Push Initiator** check box is selected, in the **Push Initiator URL** field,
  108 +type https://{server_address}/pushsdk, where {server_address} is the address of the server where the pushsdk helper
  109 +application is deployed. The SDK includes the pushsdk helper application that is deployed on a server, such as the
  110 +Apache Tomcat server. The URL must be accessible from the Internet. Of course, you can also point to your own
  111 +running Push Initiator application instead of the provided pushsdk helper one.
  112 +8. Click the **Launch App on New Push** check box if you want to start the sample application if it is not already started
  113 +when a new push message arrives. Leave the check box unchecked if you do not want to start the sample application
  114 +when a new push message arrives.
  115 +9. Click **Save**.
  116 +10. Tap the **Register** action at the bottom of the device screen.
  117 +11. If you had previously checked the **Use Push Service SDK as Push Initiator** check box, you will be required to enter a username and password.
  118 +These will be mapped, after authentication, to a subscriber ID in your Push Initiator. If the **Use Push Service SDK as Push Initiator** check box
  119 +had not been checked, then it will jump straight into the register (i.e. create channel) operation.
  120 +12. You're all set to receive pushes!
  121 +
  122 +
  123 +## More Info
  124 +
  125 +* [BlackBerry 10 SDK for Adobe AIR Beta 2](https://developer.blackberry.com/air)
  126 +* [Push Service SDK Download](https://developer.blackberry.com/services/push)
  127 +* [Push Service SDK Development Guides](http://docs.blackberry.com/en/developers/subcategories/?userType=21&category=Push+Service)
  128 +* [Push Service Registration Form](https://www.blackberry.com/profile/?eventId=8121)
  129 +
  130 +## Disclaimer
  131 +
  132 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 PushSampleApp/src/PushReceiver-app.xml
... ... @@ -0,0 +1,48 @@
  1 +<?xml version="1.0" encoding="utf-8" standalone="no"?>
  2 +
  3 +<!--
  4 +/*
  5 +* Copyright (c) 2012 Research In Motion Limited.
  6 +*
  7 +* Licensed under the Apache License, Version 2.0 (the "License");
  8 +* you may not use this file except in compliance with the License.
  9 +* You may obtain a copy of the License at
  10 +*
  11 +* http://www.apache.org/licenses/LICENSE-2.0
  12 +*
  13 +* Unless required by applicable law or agreed to in writing, software
  14 +* distributed under the License is distributed on an "AS IS" BASIS,
  15 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 +* See the License for the specific language governing permissions and
  17 +* limitations under the License.
  18 +*/
  19 + -->
  20 +<application xmlns="http://ns.adobe.com/air/application/3.1">
  21 +
  22 + <id>sample.push.PushReceiver</id>
  23 + <versionNumber>1.0.0</versionNumber>
  24 + <filename>PushReceiver</filename>
  25 + <name>Push Receiver</name>
  26 + <description/>
  27 + <copyright/>
  28 +
  29 + <initialWindow>
  30 + <content>PushReceiver.swf</content>
  31 + <aspectRatio>portrait</aspectRatio>
  32 + <systemChrome>standard</systemChrome>
  33 + <transparent>false</transparent>
  34 + <visible>true</visible>
  35 + <fullScreen>false</fullScreen>
  36 + <autoOrients>false</autoOrients>
  37 + <renderMode>auto</renderMode>
  38 + </initialWindow>
  39 +
  40 + <supportedProfiles>mobileDevice</supportedProfiles>
  41 +
  42 + <extensions>
  43 + <extensionID>net.rim.blackberry.PushService</extensionID>
  44 + <extensionID>qnx.system.QNXDevice</extensionID>
  45 + <extensionID>qnx.fuse.ui.skins.QNXSkins</extensionID>
  46 + </extensions>
  47 +
  48 +</application>
BIN  PushSampleApp/src/PushReceiver-icon.png
BIN  PushSampleApp/src/PushReceiver-splash.png
581 PushSampleApp/src/PushReceiver.as
... ... @@ -0,0 +1,581 @@
  1 +/*
  2 +* Copyright (c) 2012 Research In Motion Limited.
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +*
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +*
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +*/
  16 +
  17 +package
  18 +{
  19 + import flash.display.Sprite;
  20 + import flash.display.StageAlign;
  21 + import flash.display.StageScaleMode;
  22 + import flash.events.Event;
  23 +
  24 + import net.rim.blackberry.events.PushServiceErrorEvent;
  25 + import net.rim.blackberry.events.PushServiceEvent;
  26 + import net.rim.blackberry.push.PushPayload;
  27 + import net.rim.blackberry.pushreceiver.events.*;
  28 + import net.rim.blackberry.pushreceiver.service.*;
  29 + import net.rim.blackberry.pushreceiver.ui.ActionBarHelper;
  30 + import net.rim.blackberry.pushreceiver.ui.ListContainer;
  31 + import net.rim.blackberry.pushreceiver.vo.*;
  32 +
  33 + import qnx.crypto.Base64;
  34 + import qnx.events.InvokeEvent;
  35 + import qnx.fuse.ui.actionbar.ActionBar;
  36 + import qnx.fuse.ui.actionbar.ActionPlacement;
  37 + import qnx.fuse.ui.core.Action;
  38 + import qnx.fuse.ui.core.Container;
  39 + import qnx.fuse.ui.core.SizeOptions;
  40 + import qnx.fuse.ui.dialog.AlertDialog;
  41 + import qnx.fuse.ui.events.ActionEvent;
  42 + import qnx.fuse.ui.layouts.Align;
  43 + import qnx.fuse.ui.layouts.gridLayout.GridData;
  44 + import qnx.fuse.ui.layouts.gridLayout.GridLayout;
  45 + import qnx.fuse.ui.text.Label;
  46 + import qnx.fuse.ui.text.TextFormat;
  47 + import qnx.fuse.ui.text.TextFormatStyle;
  48 + import qnx.fuse.ui.utils.ImageCache;
  49 + import qnx.invoke.InvokeAction;
  50 + import qnx.invoke.InvokeManager;
  51 + import qnx.invoke.InvokeRequest;
  52 + import qnx.system.FontSettings;
  53 +
  54 + /**
  55 + * The main class which handles the construction of all the UI components,
  56 + * and provides functions for handling an incoming push and a SIM card change.
  57 + *
  58 + * As a push developer you will want to focus on where and how creating a push session happens
  59 + * and how to handle incoming push messages and SIM card change events.
  60 + */
  61 + public class PushReceiver extends Sprite
  62 + {
  63 + // Label to be displayed when there are no items currently in the list container
  64 + public static var noPushesLabel:Label = new Label();
  65 +
  66 + // Shared cache for caching images used by the application
  67 + public static var imageCache:ImageCache = new ImageCache();
  68 +
  69 + // The max. number of attempts to create the push session before returning an error
  70 + private static const MAX_CREATE_SESSION_FAILURES:uint = 5;
  71 +
  72 + // The service classes
  73 + private static var configService:ConfigurationService = ConfigurationServiceImpl.getConfigurationService();
  74 + private static var pushNotificationService:PushNotificationService = PushNotificationServiceImpl.getPushNotificationService();
  75 +
  76 + // Tracks the current number of create push session attempts
  77 + private static var numCreateSessionFailures:uint = 0;
  78 +
  79 + // The view (container) holding the list of push items
  80 + private static var listContainer:ListContainer = ListContainer.getListContainer();
  81 +
  82 + public function PushReceiver()
  83 + {
  84 + // Add an invoke event handler to handle incoming push notifications
  85 + // We will ignore non-push invoke events
  86 + InvokeManager.invokeManager.addEventListener(InvokeEvent.INVOKE, invokeHandler);
  87 +
  88 + super();
  89 +
  90 + // Indicate that we are using the user defined font settings on the device
  91 + FontSettings.fontSettings.useUserSettings = true;
  92 + // Listen for font changes and update the appropriate UI components
  93 + FontSettings.fontSettings.addEventListener(Event.CHANGE, fontSettingsChangeHandler);
  94 +
  95 + stage.align = StageAlign.TOP_LEFT;
  96 + stage.scaleMode = StageScaleMode.NO_SCALE;
  97 +
  98 + // Listen for a SIM card change (and handle it)
  99 + pushNotificationService.addEventListener(PushServiceEvent.SIM_CHANGE, simChange);
  100 +
  101 + initializeUI();
  102 +
  103 + // Initialize the push session if a configuration has already been saved
  104 + initializePushSession();
  105 + }
  106 +
  107 + /**
  108 + * Actions to perform when creating a push session is successful.
  109 + * @param e a create session success event
  110 + */
  111 + public static function createSessionSuccess(e:PushServiceEvent):void
  112 + {
  113 + var config:Configuration = configService.getConfiguration();
  114 +
  115 + // We will just perform these calls here, but won't bother checking
  116 + // to see if they were successful or unsuccessful
  117 + if (config.launchApplicationOnPush) {
  118 + pushNotificationService.registerToLaunch();
  119 + } else {
  120 + pushNotificationService.unregisterFromLaunch();
  121 + }
  122 + }
  123 +
  124 + /**
  125 + * Actions to perform when creating a push session has failed.
  126 + * @param e a create session error event
  127 + */
  128 + public static function createSessionError(e:PushServiceErrorEvent):void
  129 + {
  130 + numCreateSessionFailures++;
  131 +
  132 + if (numCreateSessionFailures >= MAX_CREATE_SESSION_FAILURES) {
  133 + // Typically in your own application you wouldn't want to display this error to your users
  134 + var msg:String = "Unable to create push session. (Error code: " + e.errorID + ")";
  135 + if (e.text) {
  136 + msg += " Reason: " + e.text;
  137 + }
  138 +
  139 + var alertDialog:AlertDialog = new AlertDialog();
  140 + alertDialog.title = "Push Receiver";
  141 + alertDialog.message = msg;
  142 + alertDialog.addButton("Ok");
  143 + alertDialog.show();
  144 + } else {
  145 + // Try it again (consider using an exponential backoff retry)
  146 + pushNotificationService.createSession();
  147 + }
  148 + }
  149 +
  150 + /**
  151 + * Updates the list container to have the current list of pushes.
  152 + */
  153 + public static function updateListContainerWithCurrentPushes():void
  154 + {
  155 + var pushes:Array = pushNotificationService.getAllPushes();
  156 +
  157 + if (pushes) {
  158 + var pushDates:Array = getDateHeadings(pushes);
  159 +
  160 + listContainer.addDateHeadings(pushDates);
  161 +
  162 + var lastIndex:uint = 0;
  163 + for (var i:uint = 0; i < pushDates.length; i++) {
  164 + var pushDate:String = pushDates[i].label as String;
  165 +
  166 + // Now, add the pushes that have that date
  167 + for (var j:uint = lastIndex; j < pushes.length; j++) {
  168 + var push:Push = pushes[j] as Push;
  169 +
  170 + if (push.pushDate == pushDate) {
  171 + listContainer.addPushToDateHeading(push, pushDates[i]);
  172 + } else {
  173 + lastIndex = j;
  174 + break;
  175 + }
  176 + }
  177 + }
  178 + }
  179 + }
  180 +
  181 + /**
  182 + * Handles incoming invoke events. We will just be concerned with push-related invoke events
  183 + * and ignore all others.
  184 + * @param e an invoke event
  185 + */
  186 + private function invokeHandler(e:InvokeEvent):void
  187 + {
  188 + if (configService.hasConfiguration()) {
  189 + // The underling net.rim.blackberry.push.PushService instance might not have been
  190 + // initialized when an invoke first comes in
  191 + // Make sure that we initialize it here if it hasn't been already
  192 + // It requires an application ID (for consumer applications) so we have to check
  193 + // that configuration settings have already been stored
  194 + pushNotificationService.initializePushService();
  195 +
  196 + var invokeRequest:InvokeRequest = InvokeManager.invokeManager.startupRequest;
  197 +
  198 + if (invokeRequest.action == InvokeAction.PUSH) {
  199 + var pushPayload:PushPayload = pushNotificationService.extractPushPayload(invokeRequest);
  200 +
  201 + pushNotificationHandler(pushPayload);
  202 + }
  203 + }
  204 + }
  205 +
  206 + private function fontSettingsChangeHandler(e:Event):void
  207 + {
  208 + /*
  209 + noPushesLabel.updateFontSettings();
  210 + listContainer.updateFontSettings();
  211 + */
  212 + }
  213 +
  214 + /**
  215 + * Initializes the main UI components.
  216 + */
  217 + private function initializeUI():void
  218 + {
  219 + var actionBar : ActionBar = new ActionBar();
  220 + actionBar.showTabsFirstOnBar(false);
  221 +
  222 + var configAction:Action = new Action(ActionBarHelper.CONFIG_ACTION_LABEL, "configicon.png");
  223 + actionBar.addAction(configAction);
  224 +
  225 + var registerAction:Action = new Action(ActionBarHelper.REGISTER_ACTION_LABEL, "registericon.png");
  226 + actionBar.addAction(registerAction);
  227 +
  228 + var unregisterAction:Action = new Action(ActionBarHelper.UNREGISTER_ACTION_LABEL, "unregistericon.png");
  229 + actionBar.addAction(unregisterAction);
  230 +
  231 + var markAllAction:Action = new Action(ActionBarHelper.MARK_ALL_OPEN_ACTION_LABEL, "markallicon.png");
  232 + markAllAction.actionBarPlacement = ActionPlacement.IN_OVERFLOW;
  233 + actionBar.addAction(markAllAction);
  234 +
  235 + var deleteAllAction:Action = new Action(ActionBarHelper.DELETE_ALL_OPEN_ACTION_LABEL, "deleteallicon.png");
  236 + deleteAllAction.actionBarPlacement = ActionPlacement.IN_OVERFLOW;
  237 + actionBar.addAction(deleteAllAction);
  238 +
  239 + actionBar.y = stage.stageHeight - actionBar.height;
  240 + actionBar.addEventListener(ActionEvent.ACTION_SELECTED, onActionSelected);
  241 +
  242 + addChild(actionBar);
  243 +
  244 + var noPushesContainer:Container = new Container();
  245 + noPushesContainer.setActualSize(stage.stageWidth, actionBar.y);
  246 +
  247 + var noPushesGrid:GridLayout = new GridLayout();
  248 + noPushesGrid.verticalPadding = 30;
  249 + noPushesGrid.numColumns = 1;
  250 + noPushesContainer.layout = noPushesGrid;
  251 +
  252 + var noPushesGridData:GridData = new GridData();
  253 + noPushesGridData.hAlign = Align.CENTER;
  254 + noPushesGridData.vAlign = Align.BEGIN;
  255 + noPushesGridData.setOptions(SizeOptions.RESIZE_BOTH);
  256 + noPushesLabel.layoutData = noPushesGridData;
  257 +
  258 + var format:TextFormat = new TextFormat();
  259 + format.style = TextFormatStyle.CONTENT;
  260 + format.bold = true;
  261 +
  262 + noPushesLabel.format = format;
  263 + noPushesLabel.text = "There are currently no pushes.";
  264 +
  265 + noPushesContainer.addChild(noPushesLabel);
  266 + addChild(noPushesContainer);
  267 +
  268 + listContainer.setActualSize(stage.stageWidth, actionBar.y);
  269 +
  270 + addChild(listContainer);
  271 +
  272 + updateListContainerWithCurrentPushes();
  273 + }
  274 +
  275 +
  276 + private function onActionSelected(actionEvent:ActionEvent):void
  277 + {
  278 + if(actionEvent.action.label == ActionBarHelper.CONFIG_ACTION_LABEL) {
  279 + ActionBarHelper.getActionBarHelper().showConfigDialog();
  280 + } else if(actionEvent.action.label == ActionBarHelper.REGISTER_ACTION_LABEL) {
  281 + ActionBarHelper.getActionBarHelper().showRegisterDialog();
  282 + } else if(actionEvent.action.label == ActionBarHelper.UNREGISTER_ACTION_LABEL) {
  283 + ActionBarHelper.getActionBarHelper().showUnregisterDialog();
  284 + } else if(actionEvent.action.label == ActionBarHelper.MARK_ALL_OPEN_ACTION_LABEL) {
  285 + ActionBarHelper.getActionBarHelper().performMarkAllAsOpen();
  286 + } else if(actionEvent.action.label == ActionBarHelper.DELETE_ALL_OPEN_ACTION_LABEL) {
  287 + ActionBarHelper.getActionBarHelper().performDeleteAll();
  288 + }
  289 + }
  290 +
  291 + /**
  292 + * Initializes the push session if a configuration has already been saved.
  293 + */
  294 + private function initializePushSession():void
  295 + {
  296 + if (configService.hasConfiguration()) {
  297 + // If the app already has config info saved, just create the session and listen to see if creating a push session was successful or failed
  298 + pushNotificationService.addEventListener(PushServiceEvent.CREATE_SESSION_SUCCESS, createSessionSuccess);
  299 + pushNotificationService.addEventListener(PushServiceErrorEvent.CREATE_SESSION_ERROR, createSessionError);
  300 +
  301 + pushNotificationService.createSession();
  302 + }
  303 + }
  304 +
  305 + /**
  306 + * Returns all the different dates for the pushes in the database.
  307 + * @param pushes all the pushes in the database
  308 + * @return the unique dates corresponding to the pushes in the database
  309 + */
  310 + private static function getDateHeadings(pushes:Array):Array
  311 + {
  312 + var pushDates:Array = [];
  313 +
  314 + for (var i:uint = 0; i < pushes.length; i++) {
  315 + var isFound:Boolean = false;
  316 +
  317 + var push:Push = pushes[i] as Push;
  318 +
  319 + for (var j:uint = 0; j < pushDates.length; j++) {
  320 + var pushDate:String = pushDates[j].label as String;
  321 +
  322 + if (pushDate == push.pushDate) {
  323 + isFound = true;
  324 + break;
  325 + }
  326 + }
  327 +
  328 + if (!isFound) {
  329 + var dateHeading:Object = new Object();
  330 + dateHeading.label = push.pushDate;
  331 +
  332 + pushDates.push(dateHeading);
  333 + }
  334 + }
  335 +
  336 + return pushDates;
  337 + }
  338 +
  339 + /**
  340 + * Actions to perform after a SIM card change has occurred.
  341 + * @param e a SIM card change event
  342 + */
  343 + private function simChange(e:PushServiceEvent):void
  344 + {
  345 + // Remove the currently registered user (if there is one)
  346 + // and unsubscribe the user from the Push Initiator since
  347 + // switching SIMs might indicate we are dealing with
  348 + // a different user
  349 + pushNotificationService.handleSimChange();
  350 +
  351 + var simChangeDialog:AlertDialog = new AlertDialog();
  352 + simChangeDialog.title = "Push Receiver";
  353 + simChangeDialog.message = "The SIM card was changed and, as a result, the current user has been unregistered. Would you like to re-register?";
  354 + simChangeDialog.addButton("Yes");
  355 + simChangeDialog.addButton("No");
  356 + simChangeDialog.addEventListener(Event.SELECT, simChangeDialogClicked);
  357 + simChangeDialog.show();
  358 + }
  359 +
  360 + /**
  361 + * Actions to perform after the SIM change dialog is clicked.
  362 + * @param event a dialog event
  363 + */
  364 + private function simChangeDialogClicked(event:Event):void
  365 + {
  366 + if (event.target.selectedIndex == 0) {
  367 + // The "Yes" button was clicked, show the register dialog
  368 + ActionBarHelper.getActionBarHelper().showRegisterDialog();
  369 + }
  370 + }
  371 +
  372 +
  373 + /**
  374 + * Actions to perform when a new push comes in.
  375 + * @param pushPayload a push payload
  376 + */
  377 + private function pushNotificationHandler(pushPayload:PushPayload):void
  378 + {
  379 + // Check for a duplicate push
  380 + var pushHistoryItem:PushHistoryItem = new PushHistoryItem();
  381 + pushHistoryItem.itemId = pushPayload.id;
  382 +
  383 + if (pushNotificationService.checkForDuplicatePush(pushHistoryItem)) {
  384 + // A duplicate was found, stop processing. Silently discard this push from the user
  385 + trace("Duplicate push was found with ID: " + pushPayload.id + ".");
  386 + return;
  387 + }
  388 +
  389 + // Hide this message since there will be pushes visible
  390 + noPushesLabel.visible = false;
  391 +
  392 + var contentTypeHeaderVal:String = pushPayload.getHeader("Content-Type");
  393 + var currentTime:Date = new Date();
  394 +
  395 + // Convert from PushPayload to Push so that it can be stored in the database
  396 + var push:Push = new Push();
  397 + push.contentType = getPushContentType(contentTypeHeaderVal);
  398 + push.fileExtension = getPushContentFileExtension(contentTypeHeaderVal);
  399 + push.pushDate = getPushDate(currentTime);
  400 + push.pushTime = getPushTime(currentTime);
  401 + push.content = Base64.encode(pushPayload.data);
  402 + push.unread = true;
  403 +
  404 + // Store the push and set the sequence number (ID) of the push
  405 + push.seqNum = pushNotificationService.storePush(push);
  406 +
  407 + // Add the push to the push list being displayed
  408 + listContainer.addPush(push);
  409 +
  410 + // If an acknowledgement of the push is required (that is, the push was sent as a confirmed push
  411 + // - which is equivalent terminology to the push being sent with application level reliability),
  412 + // then you must either accept the push or reject the push
  413 + if (pushPayload.isAckRequired) {
  414 + // In our sample, we always accept the push, but situations might arise where an application
  415 + // might want to reject the push (for example, after looking at the headers that came with the push
  416 + // or the data of the push, we might decide that the push received did not match what we expected
  417 + // and so we might want to reject it)
  418 + pushNotificationService.acceptPush(pushPayload.id);
  419 + }
  420 + }
  421 +
  422 + /**
  423 + * Retrieves the content type of a push. If the content type header was missing or not recognized a content type of 'text' will be assumed. It
  424 + * is a best practice to always send a Content-Type header with the push message.
  425 + *
  426 + * @param contentTypeHeaderValue the value of the Content-Type header
  427 + * @return the content type based on the Content-Type header value
  428 + */
  429 + private function getPushContentType(contentTypeHeaderValue:String):String
  430 + {
  431 + if(!contentTypeHeaderValue) {
  432 + return Push.CONTENT_TYPE_TEXT;
  433 + }
  434 +
  435 + if (contentTypeHeaderValue.indexOf("image") >= 0) {
  436 + return Push.CONTENT_TYPE_IMAGE;
  437 + } else if (contentTypeHeaderValue.match("^text/html") || contentTypeHeaderValue.match("^application/xml")) {
  438 + return Push.CONTENT_TYPE_XML;
  439 + } else {
  440 + return Push.CONTENT_TYPE_TEXT;
  441 + }
  442 + }
  443 +
  444 + /**
  445 + * Retrieves the file extension of a push. If the content type header was missing or not recognized a file extension of null will be returned. It
  446 + * is a best practice to always send a Content-Type header with the push message.
  447 + *
  448 + * @param contentTypeHeaderValue the value of the Content-Type header
  449 + * @return the file extension based on the Content-Type header value
  450 + */
  451 + private function getPushContentFileExtension(contentTypeHeaderValue:String):String
  452 + {
  453 + if(!contentTypeHeaderValue) {
  454 + return null;
  455 + }
  456 +
  457 + if (contentTypeHeaderValue.match("^application/xml")) {
  458 + return Push.FILE_EXTENSION_XML;
  459 + } else if (contentTypeHeaderValue.match("^text/html")) {
  460 + return Push.FILE_EXTENSION_HTML;
  461 + } else if (contentTypeHeaderValue.match("^image/jpeg")) {
  462 + return Push.FILE_EXTENSION_JPEG;
  463 + } else if (contentTypeHeaderValue.match("^image/gif")) {
  464 + return Push.FILE_EXTENSION_GIF;
  465 + } else if (contentTypeHeaderValue.match("^image/png")) {
  466 + return Push.FILE_EXTENSION_PNG;
  467 + } else if (contentTypeHeaderValue.match("^text/plain")) {
  468 + return Push.FILE_EXTENSION_TEXT;
  469 + } else {
  470 + trace("File extension is unknown for Content-Type header value: " + contentTypeHeaderValue + ".");
  471 + return null;
  472 + }
  473 + }
  474 +
  475 + /**
  476 + * Retrieves the date of a push.
  477 + * @param currentTime the current date
  478 + * @return the push's date (e.g. Mon, Oct 31, 2011)
  479 + */
  480 + private function getPushDate(currentTime:Date):String
  481 + {
  482 + var dayOfWeek:String = getDayOfWeekText(currentTime.getDay());
  483 + var month:String = getMonthText(currentTime.getMonth());
  484 + var dayOfMonth:Number = currentTime.getDate();
  485 + var year:Number = currentTime.getFullYear();
  486 +
  487 + return dayOfWeek + ", " + month + " " + dayOfMonth + ", " + year;
  488 + }
  489 +
  490 + /**
  491 + * Retrieves an English abbreviation for the day of the week.
  492 + * @param dayOfWeek a day of the week (from 0-5)
  493 + * @return a day of the week's English abbreviation
  494 + *
  495 + */
  496 + private function getDayOfWeekText(dayOfWeek:Number):String
  497 + {
  498 + if (dayOfWeek == 0) {
  499 + return "Sun";
  500 + } else if (dayOfWeek == 1) {
  501 + return "Mon";
  502 + } else if (dayOfWeek == 2) {
  503 + return "Tue";
  504 + } else if (dayOfWeek == 3) {
  505 + return "Wed";
  506 + } else if (dayOfWeek == 4) {
  507 + return "Thu";
  508 + } else if (dayOfWeek == 5) {
  509 + return "Fri";
  510 + } else {
  511 + return "Sat";
  512 + }
  513 + }
  514 +
  515 + /**
  516 + * Retrieves an English abbreviation for the month of the year.
  517 + * @param month a month (from 0-11)
  518 + * @return a month's English abbreviation
  519 + */
  520 + private function getMonthText(month:Number):String
  521 + {
  522 + if (month == 0) {
  523 + return "Jan";
  524 + } else if (month == 1) {
  525 + return "Feb";
  526 + } else if (month == 2) {
  527 + return "Mar";
  528 + } else if (month == 3) {
  529 + return "Apr";
  530 + } else if (month == 4) {
  531 + return "May";
  532 + } else if (month == 5) {
  533 + return "Jun";
  534 + } else if (month == 6) {
  535 + return "Jul";
  536 + } else if (month == 7) {
  537 + return "Aug";
  538 + } else if (month == 8) {
  539 + return "Sep";
  540 + } else if (month == 9) {
  541 + return "Oct";
  542 + } else if (month == 10) {
  543 + return "Nov";
  544 + } else {
  545 + return "Dec";
  546 + }
  547 + }
  548 +
  549 + /**
  550 + * Retrieves the time of a push.
  551 + * @param currentTime the current date
  552 + * @return the push time using a 12-hour clock (e.g. 2:38p, e.g. 11:22a)
  553 + */
  554 + private function getPushTime(currentTime:Date):String
  555 + {
  556 + var hours:Number = currentTime.getHours();
  557 + var minutes:String = "" + currentTime.getMinutes();
  558 + var timeOfDay:String = "a";
  559 +
  560 + // We want all minutes less than 10 to add a "0" in front since,
  561 + // for example, 5:8 for a time is incorrect (it should be 5:08)
  562 + if (currentTime.getMinutes() < 10) {
  563 + minutes = "0" + minutes;
  564 + }
  565 +
  566 + if (hours >= 12) {
  567 + timeOfDay = "p";
  568 + }
  569 +
  570 + if (hours >= 13) {
  571 + hours -= 12;
  572 + }
  573 +
  574 + if (hours == 0) {
  575 + hours += 12;
  576 + }
  577 +
  578 + return hours + ":" + minutes + timeOfDay;
  579 + }
  580 + }
  581 +}
44 PushSampleApp/src/bar-descriptor.xml
... ... @@ -0,0 +1,44 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +
  3 +<!--
  4 +/*
  5 +* Copyright (c) 2012 Research In Motion Limited.
  6 +*
  7 +* Licensed under the Apache License, Version 2.0 (the "License");
  8 +* you may not use this file except in compliance with the License.
  9 +* You may obtain a copy of the License at
  10 +*
  11 +* http://www.apache.org/licenses/LICENSE-2.0
  12 +*
  13 +* Unless required by applicable law or agreed to in writing, software
  14 +* distributed under the License is distributed on an "AS IS" BASIS,
  15 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 +* See the License for the specific language governing permissions and
  17 +* limitations under the License.
  18 +*/
  19 +-->
  20 +<qnx>
  21 + <author>RIM</author>
  22 + <buildId>1</buildId>
  23 + <platformVersion>10.0.0.0</platformVersion>
  24 +
  25 + <icon>
  26 + <image>PushReceiver-icon.png</image>
  27 + </icon>
  28 +
  29 + <splashscreen>:PushReceiver-splash.png</splashscreen>
  30 +
  31 + <permission>read_device_identifying_information</permission>
  32 + <action system="true">run_air_native</action>
  33 +
  34 + <!-- Need to put an invoke entry here for push -->
  35 + <!-- The id here must match the invokeTargetID in the net.rim.push.PushService constructor -->
  36 + <invoke-target id="sample.pushreceiver.invoke.target">
  37 + <entry-point>1</entry-point>
  38 + <type>APPLICATION</type>
  39 + <filter>
  40 + <action>bb.action.PUSH</action>
  41 + <mime-type>application/vnd.push</mime-type>
  42 + </filter>
  43 + </invoke-target>
  44 +</qnx>
BIN  PushSampleApp/src/browser.png
BIN  PushSampleApp/src/configicon.png
BIN  PushSampleApp/src/deleteallicon.png
BIN  PushSampleApp/src/markallicon.png
BIN  PushSampleApp/src/memo.png
66 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/BaseDAOImpl.as
... ... @@ -0,0 +1,66 @@
  1 +/*
  2 +* Copyright (c) 2012 Research In Motion Limited.
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +*
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +*
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +*/
  16 +
  17 +package net.rim.blackberry.pushreceiver.dao
  18 +{
  19 + import flash.data.SQLConnection;
  20 + import flash.events.ErrorEvent;
  21 + import flash.events.Event;
  22 + import flash.filesystem.File;
  23 +
  24 + import net.rim.blackberry.pushreceiver.ui.ListContainer;
  25 +
  26 + import qnx.fuse.ui.dialog.AlertDialog;
  27 +
  28 + /**
  29 + * The base class for the DAO (Data Access Object) classes.
  30 + */
  31 + public class BaseDAOImpl
  32 + {
  33 + protected var connection:SQLConnection;
  34 +
  35 + public function BaseDAOImpl()
  36 + {
  37 + }
  38 +
  39 + public function getSQLConnection():SQLConnection {
  40 + if (connection) {
  41 + return connection;
  42 + }
  43 +
  44 + connection = new SQLConnection();
  45 +
  46 + var database:File = File.applicationStorageDirectory.resolvePath("pushreceiver.db");
  47 +
  48 + try
  49 + {
  50 + connection.open(database);
  51 + }
  52 + catch (error:ErrorEvent)
  53 + {
  54 + var alertDialog:AlertDialog = new AlertDialog();
  55 + alertDialog.title = "Database Error (" + error.errorID + ")";
  56 + alertDialog.message = "Error: " + error.text;
  57 + alertDialog.addButton("Ok");
  58 + alertDialog.show();
  59 +
  60 + connection = null;
  61 + }
  62 +
  63 + return connection;
  64 + }
  65 + }
  66 +}
44 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/ConfigurationDAO.as
... ... @@ -0,0 +1,44 @@
  1 +/*
  2 +* Copyright (c) 2012 Research In Motion Limited.
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +*
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +*
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +*/
  16 +
  17 +package net.rim.blackberry.pushreceiver.dao
  18 +{
  19 + import net.rim.blackberry.pushreceiver.vo.Configuration;
  20 +
  21 + /**
  22 + * DAO related to the configuration settings of the application.
  23 + * Note: In our application, we expose the configuration settings to the user.
  24 + * However, in an actual push application, you would likely have these settings
  25 + * hard coded under the covers. We expose them in our application for testing /
  26 + * debugging purposes.
  27 + */
  28 + public interface ConfigurationDAO
  29 + {
  30 + function createConfigurationTable():void;
  31 +
  32 + function addOrUpdateConfiguration(config:Configuration):void;
  33 +
  34 + function addConfiguration(config:Configuration):void;
  35 +
  36 + function updateConfiguration(config:Configuration):void;
  37 +
  38 + function removeConfiguration():void;
  39 +
  40 + function getConfiguration():Configuration;
  41 +
  42 + function hasExistingConfiguration():Boolean;
  43 + }
  44 +}
206 PushSampleApp/src/net/rim/blackberry/pushreceiver/dao/ConfigurationDAOImpl.as
... ... @@ -0,0 +1,206 @@
  1 +/*
  2 +* Copyright (c) 2012 Research In Motion Limited.
  3 +*
  4 +* Licensed under the Apache License, Version 2.0 (the "License");
  5 +* you may not use this file except in compliance with the License.
  6 +* You may obtain a copy of the License at
  7 +*
  8 +* http://www.apache.org/licenses/LICENSE-2.0
  9 +*
  10 +* Unless required by applicable law or agreed to in writing, software
  11 +* distributed under the License is distributed on an "AS IS" BASIS,
  12 +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 +* See the License for the specific language governing permissions and
  14 +* limitations under the License.
  15 +*/
  16 +
  17 +package net.rim.blackberry.pushreceiver.dao
  18 +{
  19 + import flash.data.SQLStatement;
  20 +
  21 + import net.rim.blackberry.pushreceiver.vo.Configuration;
  22 +
  23 + /**
  24 + * DAO related to the configuration settings of the application.
  25 + * Note: In our application, we expose the configuration settings to the user.
  26 + * However, in an actual push application, you would likely have these settings
  27 + * hard coded under the covers. We expose them in our application for testing /
  28 + * debugging purposes.
  29 + */
  30 + public class ConfigurationDAOImpl extends BaseDAOImpl implements ConfigurationDAO
  31 + {
  32 + public function ConfigurationDAOImpl()
  33 + {
  34 + super();
  35 + }
  36 +
  37 + public function createConfigurationTable():void
  38 + {
  39 + var sql:String = "CREATE TABLE IF NOT EXISTS configuration (appid TEXT, piurl TEXT, ppgurl TEXT, launchapp BIT, usingpublicppg BIT);";
  40