Using the Local Notification ANE

This component allows sending Local Notifications that will trigger on a later date. It lets you specify message text, buttons, sound to play, a date to trigger, the interval between notifications, and more…

Now I’m going to explain how to use my modified version of Local Notification ANE using Flash CS5.5/CS6 and Flash Builder 4.6. If you want to improve the ANE with your own source code see instructions in my previous post here. You will also find a list of the added features there.

Important!
The Android version doesn’t support custom icons and sounds.

Prerequisites

Set up your path variables

I’m new to Mac so I don’t know a lot of stuff, hence I used absolute paths to reference AIR SDK tools. I didn’t had to do anything for JAVA on Mac. I don’t know if Macs come with JAVA pre-installed, or if the path is already configured for you when you install JAVA. For Windows you must add the following path variables:

  1. Add a system’s path variable to point to AIR SDK command line tools. Open Windows Start Menu, type “path” and choose “edit environment variables for your account” (Windows 7). Choose “Path Variable” and click “Edit”. Type or paste in the path to your downloaded AIR SDK’s bin directory at the end of the current path. Use a semicolon (without any spaces) between any path’s that are already in the variable.
    For example: ;C:\AIR SDK 3.3\bin
  2. Set up your system’s path variable to point to your JAVA command line tools in the same manner as the previous step. The ADT tool needs JAVA.
    For example: ;C:\Program Files\Java\jre7\bin

Overlay AIR SDK in Flash Professional/Flash Builder

Overlay AIR SDK 3.3 or later first. Without doing this, all editors use an old version of the SDK:

Using the ANE on Flash Professional CS5.5/CS6

This is a simple iOS app with three buttons and a textfield. The first button will schedule a notification to trigger after 15 seconds. You can press this button an quit the application to see how the notification triggers. The second button simply cancels the previously scheduled notification and the third button clears the debug textfield and resets the application badge number to zero.

  1. Create a new Flash document called sample.fla
  2. Copy the LocalNotificationLib.ane file from /bin folder, and paste it next to your FLA file.
  3. For Flash CS5.5 only, change the LocalNotificationLib.ane file extension to .swc.
  4. Go to File > Actionscript Settings, and choose the Library Path tab.
  5. Click the plus (+) button to add a new entry.
  6. Import the ANE file:
    • On Flash CS5.5:
      1. Click the “Browse to SWC” button and browse to the LocalNotificationLib.swc file you renamed.
      2. While the imported SWC is selected press the “Set linkage options for a library” button (info icon).
      3. In “Link type” select “External”. Press OK twice.
    • On Flash CS 6.0 click “Browse To Native Extension (ANE) File” and Browse to the LocalNotificationLib.ane file you copied and press OK.
  7. Go to File > Publish Settings:
    • On Flash CS5.5 change the Player to AIR for Android/iOS.
    • On Flash CS6 change the Player to AIR 3.3.0.xxxx or higher for Android/iOS.
  8. On Flash CS6 only, go to File > Air for iOS Settings, then to the Deployment tab:
    1. Browse to your developer certificate .p12 file in the Certificate field.
    2. Type your certificate password and select the “Remember password for this session” option to avoid writing the password every time.
    3. Browse to your provisioning profile file in the Provisioning profile field.
    4. Write a valid App ID.
      You’ll find information on how to get all needed assets from Apple here.
  9. Create three buttons in the Stage and give them instance names “button1”, “button2” and “button3”.
  10. Create a TextField in the Stage and give it an instance name “notificationTF”.
  11. In the Properties Panel, set the document Class to “FlaSample”.
  12. Click the pencil icon to open “FlaSample”, erase all current code, and paste:
    package  {
      import flash.display.MovieClip;
      import flash.display.SimpleButton;
      import com.juankpro.ane.localnotif.NotificationManager;
      import flash.events.MouseEvent;
      import com.juankpro.ane.localnotif.Notification;
      import com.juankpro.ane.localnotif.NotificationEvent;
      import flash.text.TextField;
    
      public class FlaSample extends MovieClip {
        private var notificationManager:NotificationManager;
    
        public var button1:SimpleButton;
        public var button2:SimpleButton;
        public var button3:SimpleButton;
        public var notificationTF:TextField;
    
        private static const NOTIFICATION_CODE:String = "NOTIFICATION_CODE_001";
    
        public function FlaSample() {
          if(NotificationManager.isSupported) {
            notificationManager = new NotificationManager();
    
            notificationManager.addEventListener( NotificationEvent.NOTIFICATION_ACTION, notificationActionHandler);
            button1.addEventListener(MouseEvent.CLICK, buttonClickHandler);
            button2.addEventListener(MouseEvent.CLICK, buttonClickHandler);
            button3.addEventListener(MouseEvent.CLICK, buttonClickHandler);
          }
        }
    
        private function buttonClickHandler(event:MouseEvent):void {
          switch(event.target) {
          case button1:
            var notification:Notification = new Notification();
            notification.actionLabel = "OK";
            notification.body = "Body sample";
            notification.title = "Title";
            notification.fireDate = new Date((new Date()).time + (15 * 1000));
            notification.numberAnnotation = 1;
            notification.actionData = {sampleData:"Hello World!"}
    
            notificationManager.notifyUser(NOTIFICATION_CODE, notification);
            break;
          case button2:
            notificationManager.cancel(NOTIFICATION_CODE);
            break;
          case button3:
            notificationManager.applicationBadgeNumber = 0;
            notificationTF.text = "";
            break;
          }
        }
    
        private function notificationActionHandler(event:NotificationEvent):void {
          notificationTF.text = "Notification Code: " + event.notificationCode + "\nSample Data: {" + event.actionData.sampleData + "}\n\n";
        }
      }
    }
    
  13. Press Ctrl+Enter to preview the app in Flash. You might get an error on CS5.5 do to the External library settings but this is normal.
  14. Only on Flash CS 6.0 open File > Air for iOS Settings, press the Publish button, and you’re done!. This will create an IPA file next to the FLA file. For information on how to upload the IPA file to the device see here.
    If you are using Flash CS5.5 instead, follow to the next step.
  15. Next to your FLA file, create a new text document called “sample-app.xml”.
  16. Paste the following XML code inside it and save it:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<application xmlns="http://ns.adobe.com/air/application/3.3">
    <id>com.juank.Sample</id>
    <versionNumber>1.0</versionNumber>
    <filename>sample</filename>
    <description></description>
    <name>sample</name>
    <copyright></copyright>
    <initialWindow>
        <content>sample.swf</content>
        <systemChrome>standard</systemChrome>
        <transparent>false</transparent>
        <visible>true</visible>
        <fullScreen>false</fullScreen>
        <autoOrients>false</autoOrients>
        <aspectRatio>portrait</aspectRatio>
        <renderMode>auto</renderMode>
    </initialWindow>
    <customUpdateUI>false</customUpdateUI>
    <allowBrowserInvocation>false</allowBrowserInvocation>
    <icon></icon>
    <iPhone>
        <requestedDisplayResolution>standard</requestedDisplayResolution>
        <InfoAdditions><![CDATA[<key>UIDeviceFamily</key><array><string>1</string></array>]]></InfoAdditions>
    </iPhone>
    <android>
        <colorDepth>16bit</colorDepth>
        <manifestAdditions><![CDATA[
            <manifest android:installLocation="auto">
                <uses-permission android:name="android.permission.VIBRATE"/>
                <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
                <application>
                    <service android:name="com.juankpro.ane.localnotif.LocalNotificationIntentService"/>
                    <receiver android:name="com.juankpro.ane.localnotif.AlarmIntentService" />
                    <receiver android:name="com.juankpro.ane.localnotif.AlarmRestoreOnBoot" >
                        <intent-filter>
                            <action android:name="android.intent.action.BOOT_COMPLETED" />
                        </intent-filter>
                    </receiver>
                </application>
            </manifest>
        ]]></manifestAdditions>
    </android>
    <extensions>
        <extensionID>com.juankpro.ane.LocalNotification</extensionID>
    </extensions>
</application>

UPDATE:

I added a new permission and registered a new service in the application XML to allow recovering notifications on boot on Android.

  • Replace the id tag content with you own Bundle Identifier. You’ll find information on how to get the app ID from Apple here.
  • Open a command window “cmd.exe” on Windows or the Terminal on Mac and type:
    • Windows:
      adt -package -target ipa-ad-hoc -storetype pkcs12 -keystore  -provisioning-profile  sample.ipa sample-app.xml sample.swf -extdir
      
    • Mac:
      /Path_to_AIR_SDK_bin/adt" -package -target ipa-ad-hoc -storetype pkcs12 -keystore  -provisioning-profile  sample.ipa sample-app.xml sample.swf -extdir
      
    • Replace with your own certificate .p12 file path and with your own .provisioning profile file paths. You’ll find information on how to get all needed asets from Apple here

If everything worked well, hopefully, a sample.ipa/sample.apk file will appear next to your FLA file. For information on how to upload the IPA file to the device see (http://help.adobe.com/en_US/as3/iphone/WS144092a96ffef7cc-4ae52ec4126ab9d6ce6-8000.html)%5Bhere%5D.

Using the ANE on Flash Builder 4.6

This is a simple iOS app with three buttons and a TextArea. The first button will schedule a notification to trigger after 15 seconds. You can press this button an quit the application to see how the notification triggers. The second button simply cancels the previously scheduled notification and the third button clears the debug textfield and resets the application badge number to zero.

  1. Create a new Flex Mobile Project with File > New > Flex Mobile Project
  2. Set LocalNotificationTest as project name and choose a location for your project. Press Next.
  3. For simplicity deselect Blackberry Tablet OS. Press Finish.
  4. Copy the LocalNotificationLib.ane file from /bin folder, and paste it in your projects root folder.
  5. Select Project > Properties
    1. At Flex Build Path section > Native Extension press the “Add ANE” button to select the copied LocalNotificationLib.ane file
    2. At Flex Build Packaging > Apple iOS:
      1. In the Digital Signature tab browse to select your certificate and provisioning profile. You’ll find information on how to get all needed assets from Apple here.
      2. In the Native Extensions tab select the checkbox next to the LocalNotificationLib.ane file in the table. If a warning appears press Yes.
  6. Open the LocalNotificationTest-app.xml file and replace the id tag contents with your own Bundle Identifier. You’ll find information on how to get all needed assets from Apple here.
  7. Open the “LocalNotificationTestHomeView.mxml” file, erase all current code and paste:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView" creationComplete="view1_creationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import com.juankpro.ane.localnotif.Notification;
            import com.juankpro.ane.localnotif.NotificationEvent;
            import com.juankpro.ane.localnotif.NotificationManager;

            import mx.events.FlexEvent;

            private static const NOTIFICATION_CODE:String = "NOTIFICATION_CODE_001";

            private var notificationManager:NotificationManager;

            protected function view1_creationCompleteHandler(event:FlexEvent):void
            {
                if(NotificationManager.isSupported)
                {
                    notificationManager = new NotificationManager();

                    notificationManager.addEventListener( NotificationEvent.NOTIFICATION_ACTION, notificationActionHandler);
                }
            }

            protected function button_clickHandler(event:MouseEvent):void
            {
                if(!notificationManager) return;

                switch(event.target)
                {
                    case button1:
                        var notification:Notification = new Notification();
                        notification.actionLabel = "OK";
                        notification.body = "Body sample";
                        notification.title = "Title";
                        notification.fireDate = new Date((new Date()).time + (15 * 1000));
                        notification.numberAnnotation = 1;
                        notification.actionData = {sampleData:"Hello World!"}

                        notificationManager.notifyUser(NOTIFICATION_CODE, notification);
                        break;
                    case button2:
                        notificationManager.cancel(NOTIFICATION_CODE);
                        break;
                    case button3:
                        notificationManager.applicationBadgeNumber = 0;
                        notificationTF.text = "";
                        break;
                }
            }

            private function notificationActionHandler(event:NotificationEvent):void
            {
                notificationTF.text = "Notification Code: " + event.notificationCode +
                    "nSample Data: {" + event.actionData.sampleData + "}nn";
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:Button id="button1" x="55" y="10" width="211" label="Send" click="button_clickHandler(event)"/>
    <s:Button id="button2" x="55" y="61" width="211" label="Clear" click="button_clickHandler(event)"/>
    <s:Button id="button3" x="55" y="112" width="211" label="Reset" click="button_clickHandler(event)"/>
    <s:TextArea id="notificationTF" x="10" y="163" height="242"/>
</s:View>
  1. You can Debug your project if you want (Optional). The first time you debug you might have to select “On desktop” as Launch method and select a target device on the dialog that shows.
  2. To compile the iOS App select Project > Export Release Build and click Next
  3. In the “Digital Signature” tab, fill the Password field with your certificate password.
  4. Select “Final release” or “Ad hoc” as package type depending on your certificate type.
  5. This will create an IPA in your projects root folder. For information on how to upload the IPA/APK file to the device see here.

How to use sample files

To use the sample files you’ll need to replace the App ID, certificate .p12 file and provisioning profile file paths with your own data and then build the IPA file using the method corresponding to the editor you use (Flash CS5.5, Flash CS6 or Flash Builder).

To compile on Flash CS5.5, I provide shell script files to compile the sample on Mac. You need to change the paths to certificates and provisioning profiles in theses files too.

Final words

Hope this tutorial and the ANE itself is useful. I’m planning to do more components.
If you’re interested in donating, do it here.

PayPal

Thanks in advance!

132 thoughts on “Using the Local Notification ANE

  1. hi,

    i got error when build on air sdk 21.0 for IOS, -:
    META-INF/ANE/iPhone-ARM/libLocalNotificationLib.a are required to have universal iOS libraries.

    Like

  2. Thank you for the useful ANE and the straight forward tutorial. It’s so frustrating all the work you need to do to get this simple functionality to a device. Writing in 2+ languages, tons of SDKs tools etc..

    Anyway I got my project to compile in cs6 with your ANE and demo code. I needed to add your as code library in the com folder and I also had to add CONFIG variables in the actionscript settings. After doing this it compiled. But on my android device it just stays at a blank screen. Not sure why and I haven’t tried to debug yet. Perhaps this isn’t working on new builds of android?

    Like

    1. Fixed the blank screen by modifying the manifest xml to match your sample xml but no notifications firing. I believe I may not of updated the paths of the id in the manifest properly:

      Should those be replaced with my app id so its:

      com.myid.myapp.AlarmIntentService?

      Like

  3. Hey Juan and thank you very much – this ANE is great, easy to use, and works like a charm!

    Myself I’m targeting to both, Android and iOS, tho so far I’ve developed my project only with Android.
    I’m wondering if I can change the notification icon for Android. If yes, should it be done with Eclipse, or is there already some easier way? I have no experience with Eclipse, and for Flash stuff I use Flash Professional CC.
    It would be super cool to have multiple different icons to use, but my project will be fine with one icon too – as long as it’s custom made.

    Cheers, and thanks again!

    Like

  4. Hi Juan Carlos,

    I have to update a app from 2013. Only the Flex-SDK was changed to 16.0.
    Android works fine, but iOS runs into an error building/debuging the app:
    Error: libLocalNotificationLib.a, libUDPSocketiOSLibrary.a are required to have universal iOS libraries. Please contact the ANE developer(s) to get the same.

    I downloaded teh latest repository from bitbucket and used this ane. But what to do with the two missing files? They are included in the zip – but i did not know where to store them.

    Regards

    Like

    1. Hi Juan Carlos,

      I found this:
      Apple announced that new apps have to support 64bit.Air sdk 16 supports 64bit.

      “If you have access to the source it’s fairly simple to update as long as the extension is well coded in ObjC.

      open the Xcode project
      check that it’s using the standard architectures and has arm64 a supported platform
      build the project

      Then if you use the latest air beta to compile the ANE you’ll get a 64 bit supported extension.”

      Like

  5. HELP!!! Error: libSocialIosExtension.a, libLocalNotificationLib.a are required to have universal iOS libraries. Please contact the ANE developer(s) to get the same.

    Please, HELP!
    Thanks!

    Like

  6. Hi,
    and first of all, thanks for this ANE! I remember to have tried it some months ago and it worked like a charm, but unfortunately with AIR 16.0 it doesnt package any more..
    Any chance to get a 64 bit version of this ANE? Would be great, since my adt calls spits out:
    Error: META-INF/ANE/iPhone-ARM/libLocalNotificationLib.a are required to have universal iOS libraries. Please contact the ANE developer(s) to get the same.
    Thanks very much!
    – Stephan

    Like

  7. Hello. I Have to used your .ane without problems. But now, with adobe Air 17 i have a problem.

    Flash Pro throw this message:

    Error: libLocalNotificationLib.a are required to have universal iOS libraries. Please contact the ANE developer(s) to get the same.

    Like

  8. Hello!!!

    Important!
    The Android version doesn’t support custom icons and sounds.

    As i learn that Android have functionality to customize Icon and sound then why this ANE didn’t support Custom sound and Icon?

    its important for me and i must find a solutions for it, please leave reply.

    Many Many Thanks
    JK Patel

    Like

  9. Hi Juan.

    Thank you so much for this ane!

    I’m working on an app that will add several notifications at once for many dates in the future for both ios and android.

    I have some doubts about the “date” and “repeatInterval”…

    How do i specify a date? is it the same “date” as in as3?

    repeatInterval in the docs say it’s only for iOS, is that right? if not, how can i make it repeat yearly?

    Thank you so much!

    Like

  10. 1. How to restore notifications that was removed by the user (clear Android button) or that disappear because the battery was removed ?

    2. There is any way to get all the notifications instances from a within the Flex app (for example to show in a proper view) ?

    Like

  11. Is it possible to have the notification show while in the app? Mine only show up when outside of the app.

    Like

    1. On ios notifications only trigger as a popup or bar when you’re not in the application. If you are inside the application then an event is triggered so you can hear the event and give visual feedback.

      Like

  12. If i want to open a diferent view how is it working on adobe flash builder. I mean a diferent view where the notification was created.

    Like

  13. Your product is perfect only sounname dont work for android
    is it possible for you to update this extension please..

    Thank you

    Like

        1. I have abandoned the project for quite a while now. Not only the x64 stuff is behind but also other technologies like Android notification channels which will make the ANE to still be broken even if just solve the iOS issue only. Let me see if I can get you a non-public version that just fixes your issue even if Android is still broken.

          Like

  14. Hello,
    I would increase the icon count in iphone for change i run many different badge but the count is alway one
    could you explain me is it’s normal elsa could you tell me what I need to change for increase my icon count please

    thank you a lot for your help

    Like

    1. Are you using the LocalNotification.numberAnnotation property to change the count. This property is not relative. Hence if numberAnnotation = 1 doesn’t mean it is going to add 1 to the counter. You are the one responsible for handling the count somewhere (e.g. using SharedObject) and then displaying it.

      Like

Leave a comment