/**
* ConsequenceImpl.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.device.notificationsdemo;
import java.io.EOFException;
import net.rim.device.api.notification.Consequence;
import net.rim.device.api.synchronization.SyncConverter;
import net.rim.device.api.synchronization.SyncObject;
import net.rim.device.api.system.Alert;
import net.rim.device.api.system.LED;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.util.DataBuffer;
import net.rim.device.api.util.Persistable;
/**
* Implementation of the Consequence interface. It must also implement
* SyncConverter. A Consequence can be used to flash the LED, play a sound, and
* vibrate the device when it is triggered.
*/
public class ConsequenceImpl implements Consequence, SyncConverter {
// net.rim.samples.device.notificationsdemo.NotificationsDemo.ConsequenceImpl
static final long ID = 0xbd2350c0dfda2a51L;
private static final int TYPE = 'n' << 24 | 'o' << 16 | 't' << 8 | 'd';
// Notd for NotificationsDemo.
private static final byte[] DATA = new byte[] { 'm', 'y', '-', 'c', 'o',
'n', 'f', 'i', 'g', '-', 'o', 'b', 'j', 'e', 'c', 't' };
private static final Configuration CONFIG = new Configuration(DATA);
// The TUNE (bar 1 and 2 of Islamey by Balakirev).
private static final short BFlat = 466; // 466.16
private static final short AFlat = 415; // 415.30
private static final short A = 440; // 440.00
private static final short GFlat = 370; // 369.99
private static final short DFlat = 554; // 554.37
private static final short C = 523; // 523.25
private static final short F = 349; // 349.32
private static final short TEMPO = 125;
private static final short d16 = 1 * TEMPO; // Duration of a 16th note,
// arbitrary, in ms.
private static final short d8 = d16 << 1; // Duration of an eigth note,
// arbitrary, in ms.
private static final short dpause = 10; // 10 ms pause
private static final short pause = 0; // Zero frequency pause
private static final short[] TUNE = new short[] { BFlat, d16, pause,
dpause, BFlat, d16, pause, dpause, BFlat, d16, pause, dpause,
BFlat, d16, pause, dpause, A, d16, pause, dpause, BFlat, d16,
pause, dpause, GFlat, d16, pause, dpause, GFlat, d16, pause,
dpause, A, d16, pause, dpause, BFlat, d16, pause, dpause, DFlat,
d16, pause, dpause, C,
d16,
pause,
dpause, // Bar 1
AFlat, d16, pause, dpause, AFlat, d16, pause, dpause, AFlat, d16,
pause, dpause, AFlat, d16, pause, dpause, F, d16, pause, dpause,
GFlat, d16, pause, dpause, AFlat, d16, pause, dpause, BFlat, d16,
pause, dpause, AFlat, d16, pause, dpause, F, d8 + d16 // Bar 2
};
private static final int VOLUME = 80; // % volume
/**
* A static inner class, describing the Configuration information for this
* consequence.
* <p>
* This implements the SyncObject interface, although returns a fixed value.
*/
private static final class Configuration implements SyncObject, Persistable {
public byte[] _data;
private Configuration(final byte[] data) {
_data = data;
}
public int getUID() {
// We're not actually doing any synchronization (vs backup/restore)
// so we don't care about this value.
return 0;
}
}
/**
* @see net.rim.device.api.notification.Consequence#startNotification(long,long,long,Object,Object)
*/
public void startNotification(final long consequenceID,
final long sourceID, final long eventID,
final Object configuration, final Object context) {
if (sourceID == NotificationsDemo.NOTIFICATIONS_ID_1) {
// Start the LED blinking.
LED.setConfiguration(500, 250, LED.BRIGHTNESS_50);
LED.setState(LED.STATE_BLINKING);
Alert.startAudio(TUNE, VOLUME);
Alert.startBuzzer(TUNE, VOLUME);
}
}
/**
* @see net.rim.device.api.notification.Consequence#stopNotification(long,long,long,Object,Object)
*/
public void
stopNotification(final long consequenceID, final long sourceID,
final long eventID, final Object configuration,
final Object context) {
// We only want to respond if we initiated the event.
if (sourceID == NotificationsDemo.NOTIFICATIONS_ID_1) {
// Cancel the LED.
LED.setState(LED.STATE_OFF);
Alert.stopAudio();
Alert.stopBuzzer();
}
}
/**
* It is likely that the following call will return a separate config object
* for each SourceID, such as data that describes user set notification
* settings. However, for this example, we return a trivial, arbitrary
* config object.
*
* @see net.rim.device.api.notification.Consequence#newConfiguration(long,long,byte,int,Object)
*/
public Object newConfiguration(final long consequenceID,
final long sourceID, final byte profileIndex, final int level,
final Object context) {
return CONFIG;
}
/**
* Called when there is inbound (from the desktop) data to be converted to
* object form.
*
* @see net.rim.device.api.synchronization.SyncConverter#convert(DataBuffer,int,int)
*/
public SyncObject convert(final DataBuffer data, final int version,
final int UID) {
// It's up to us to write and read the data. We apply a four byte type
// and a 4 byte length, and then the raw data.
try {
final int type = data.readInt();
final int length = data.readCompressedInt();
if (type == TYPE) {
final byte[] rawdata = new byte[length];
data.readFully(rawdata);
return new Configuration(rawdata);
}
}
// We've prematurely reached the end of the DataBuffer.
catch (final EOFException e) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(e.toString());
}
});
}
return null;
}
/**
* @see net.rim.device.api.synchronization.SyncConverter#convert(SyncObject,DataBuffer,int)
*/
public boolean convert(final SyncObject object, final DataBuffer buffer,
final int version) {
boolean retval = false;
if (object instanceof Configuration) {
final Configuration c = (Configuration) object;
buffer.writeInt(TYPE);
buffer.writeCompressedInt(c._data.length);
buffer.write(c._data);
retval = true;
}
return retval;
}
}