This documentation relates to previous versions of Titanium.

To see the latest documentation, visit docs.appcelerator.com.

This space has been migrated to https://techweb.axway.com/confluence/display/dr and will be removed from the Appcelerator wiki on August 9th, 2018

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

Chapters

Table of Contents
maxLevel6
stylecircle
minLevel2

Creating a Notification

Create an intent:

This is what will happen once the notification is clicked. In this example, we will be launching our app from the notification.

Code Block
javascript
javascript
var intent = Ti.Android.createIntent({
		action : Ti.Android.ACTION_MAIN,
		// className : 'com.appcelerator.test.Test7Activity',
		url : 'app.js',
		flags : Ti.Android.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Ti.Android.FLAG_ACTIVITY_SINGLE_TOP
	});
	intent.addCategory(Titanium.Android.CATEGORY_LAUNCHER);
Options

We can launch the activity either by using the className property or url propertys, but not both.

If we use the className property:

In order to launch our app, we need to know the name of the main activity. We can find this out by looking in the "build/android" folder after we have built the app. In this case the app id was "com.appcelerator.test" and the app's name was "Test7".
So, the file structure looked like "build/android/gen/com/appcelerator/test/Test7Activity.java".
From there we get the className: 'com.appcelerator.test.Test7Activity'.

If we use the url property:

We need to add an intent-filter for the activity in tiapp.xml to allow the intent to launch the activity.

Code Block
xml
xml
<android xmlns:android="http://schemas.android.com/apk/res/android">
   <activities>
       <activity url="app.js">
           <intent-filter>
               <action android:name="android.intent.action.VIEW"/>
               <category android:name="android.intent.category.DEFAULT"/>
               <category android:name="android.intent.category.BROWSABLE"/>
           </intent-filter>
       </activity>
   </activities>
</android>

We set the flags and category on this intent so that we can control how the application will be launched. If we did not set them, then a new instance of the activity would be created instead of using the one that is already running. You can find out exactly what each of them mean by looking them up in Android's documentation.

Create Pending Intent:
Code Block
javascript
javascript
var pending = Ti.Android.createPendingIntent({
	activity : activity,
	intent : intent,
	type : Ti.Android.PENDING_INTENT_FOR_ACTIVITY,
	flags : Ti.Android.FLAG_ACTIVITY_NO_HISTORY
});

Creating a pending intent allows us to pass the intent on for another activity to launch at a later time. There is more documentation regarding what a pending intent is used for in Android's documentation.

Create Notification:
Code Block
javascript
javascript
var notification = Ti.Android.createNotification({
	contentIntent : pending,
	contentTitle : 'Test',
	contentText : 'test',
	tickerText : 'This is a test',
	when : new Date().getTime(),
	icon : Ti.App.Android.R.drawable.myicon,
	flags : Titanium.Android.ACTION_DEFAULT | Titanium.Android.FLAG_AUTO_CANCEL | Titanium.Android.FLAG_SHOW_LIGHTS
});
when

"when" has nothing to do with when the actual notification will happen. It is only a timestamp that will show on the notification and can be set to any date you wish.

icon

You can't simply pass a path to an image to the icon property. When an image is added to the project by putting it in the "Resources" directory, its name gets garbled and can't be accessed directly by the notification.

You can see this by opening up the "build/android/gen/com/appcelerator/test/R.java" file.
In this case "button.png" was in the "Resources" directory, and "myicon.png" was in the "platform" directory. Notice how myicon is clean and button's name is garbled.

Code Block
java
java
public final class R {
    public static final class drawable {
        public static final int appicon=0x7f020000;
        public static final int button_1aab581dd3=0x7f020001;
        public static final int myicon=0x7f020002;
    }
}

If you want to use a custom icon named "myicon.png" you need to put it in "<app>/platform/android/res/drawable" and then pass it to the icon property like this "Ti.App.Android.R.drawable.myicon". Do not include the file extension.

Launching the Notification

Now that we have it all set up we simply need to launch the notification.

Code Block
javascript
javascript
Ti.Android.NotificationManager.notify(1, notification);

The first argument is the notification id that we can use to clear the notification later. If we leave this notification id the same for two different notifications, you will only see one notification in the list. If you use two different ids then you will see two separate notifications in the list.

Future notifications

To create a notification sometime in the future we need to do a bit more work. We will need to create a service that will create the notification for use at the right time.
When we create a service, we can't directly tell it to run once in the future. What we can do it tell it to run on an interval, keep in mind that it will run the first time as soon as the service is started. So, we will need to ignore the service the first time it is run so that it does not launch our notification immediately. Once the notification has been launched, we can then kill the service.

Create the service
Code Block
javascript
javascript
var intent = Ti.Android.createServiceIntent({
	url : 'ExampleService.js'
});
var now = new Date().getTime()
var delta = new Date( now + (4 * 1000) );
var deltaMS = delta - now;
intent.putExtra('interval', deltaMS);
intent.putExtra('message' , 'This is that little extra');
Ti.Android.startService(intent);
  • "ExampleService.js" will be our service.
  • We set the interval of the service to 4 second, this will launch our notification 4 seconds in the future.
  • It is useful to note that we can pass out own custom extas to our service using "putExtra". In this case, massage is a custom extra that we can access from inside the service using
    Code Block
    var teststring = serviceIntent.getStringExtra('message');
    
  • We start our service
In the service
Code Block
javascript
javascript
if(!Ti.App.Properties.hasProperty('notificationCount')) {
	Ti.App.Properties.setInt('notificationCount', 0);
} else {
	Ti.App.Properties.removeProperty('notificationCount');

	// this is where we launch our notification

	var service = Ti.Android.currentService;
	var serviceIntent = service.getIntent();
	Ti.Android.stopService(serviceIntent);
}

Here we use the properties api to make sure that we do not launch the notification the first time the service is run, which is immediately when the service is started. We wait until the second time the service runs to launch our notification. Once the notification has been launched, we can kill the service.

Full example

Code Block
titleapp.js
var win = Titanium.UI.createWindow({
	backgroundColor : 'blue'
});
var btn = Ti.UI.createButton({
	title : 'Add Notification'
});

btn.addEventListener('click', function(e) {
	var now = new Date().getTime()
	var delta = new Date( now + (4 * 1000) );
	var deltaMS = delta - now;

	var intent = Ti.Android.createServiceIntent({
		url : 'ExampleService.js'
	});
	intent.putExtra('interval', deltaMS);
	intent.putExtra('message' , 'This is that little extra');
	Ti.Android.startService(intent);
});
win.add(btn);
win.open();
Code Block
titleExampleService.js
if(!Ti.App.Properties.hasProperty('notificationCount')) {
	Ti.App.Properties.setInt('notificationCount', 0);
} else {
	Ti.App.Properties.removeProperty('notificationCount');

	var activity = Ti.Android.currentActivity;
	var intent = Ti.Android.createIntent({
		action : Ti.Android.ACTION_MAIN,
		// you can use className or url to launch the app
		// className and packageName can be found by looking in the build folder
		// for example, mine looked like this
		// build/android/gen/com/appcelerator/test/Test7Activity.java
		// className : 'com.appcelerator.test.Test7Activity',

		// if you use url, you need to make some changes to your tiapp.xml
		url : 'app.js',
		flags : Ti.Android.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Ti.Android.FLAG_ACTIVITY_SINGLE_TOP
	});
	intent.addCategory(Titanium.Android.CATEGORY_LAUNCHER);

	var pending = Ti.Android.createPendingIntent({
		activity : activity,
		intent : intent,
		type : Ti.Android.PENDING_INTENT_FOR_ACTIVITY,
		flags : Ti.Android.FLAG_ACTIVITY_NO_HISTORY
	});

	var notification = Ti.Android.createNotification({
		contentIntent : pending,
		contentTitle : 'Test',
		contentText : 'test',
		tickerText : 'This is a test',
		// "when" will only put the timestamp on the notification and nothing else.
		// Setting it does not show the notification in the future
		when : new Date().getTime(),
		icon : Ti.App.Android.R.drawable.appicon,
		flags : Titanium.Android.ACTION_DEFAULT | Titanium.Android.FLAG_AUTO_CANCEL | Titanium.Android.FLAG_SHOW_LIGHTS
	});

	Ti.Android.NotificationManager.notify(1, notification);

	var service = Ti.Android.currentService;
	var serviceIntent = service.getIntent();

	// this will display that custom extra that we added when we created the intent
	// intent.putExtra('message' , 'This is that little extra');
	var teststring = serviceIntent.getStringExtra('message');
	Ti.API.info('Extra!: ' + teststring);

	Ti.Android.stopService(serviceIntent);
}
Code Block
titletiapp.xml
<android xmlns:android="http://schemas.android.com/apk/res/android">
   <!-- the activities tag must be added if you want to use the url property to launch your app -->
   <activities>
       <activity url="app.js">
           <intent-filter>
               <action android:name="android.intent.action.VIEW"/>
               <category android:name="android.intent.category.DEFAULT"/>
               <category android:name="android.intent.category.BROWSABLE"/>
           </intent-filter>
       </activity>
   </activities>
   <!-- the services tag must be added so that our service will run -->
   <services>
       <service type="interval" url="ExampleService.js"/>
   </services>
</android>