Continuos Vibrate and Music Alert until Confirmation

The main phone application that I support at work gets data pushed to it. Part of the data is a Message Page to notify the technician that they have a service call assigned or needing attention. Due to the nature of the service calls, the technician needs this alert to continually go off until they acknowledge the alert. A while back I changed the pop up message to a global message, which makes the pop up show on all screens, regardless if the user is in the application.

public static void displayGlobalMessage(final String gMessage)
{
	UiApplication.getUiApplication().invokeLater( new Runnable() {
			public void run() {
				UiEngine uie = Ui.getUiEngine();
				alertDialogListener  closeListener = new alertDialogListener();
				
				Dialog screen = new Dialog(Dialog.D_OK, gMessage, Dialog.OK,
											Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),
											Manager.VERTICAL_SCROLL);
				screen.setDialogClosedListener(closeListener);
				uie.pushGlobalScreen(screen, 1, UiEngine.GLOBAL_MODAL);
			}
	});
}

Unfortunately, when I created this option, I some how broke my continuous alert that was previously setup. After many attempts to get it to work again, including using a TimerTask, I finally got the alert to work again.

The first part is creating the AlertListener class that I will use to handled starting the music and vibrate. This was the most important part, because stopping and starting the alert depends on what is to be called. It took a very long time to figure out when to turn off the overall alert (continueAlert) and when to turn on and off the music and vibrate (audioFinished). This is handled in the audioDone function, because the music plays longer than the vibration (which is why nothing is done on vibrateDone and buzzerDone).

public class SDAAlertListener implements AlertListener
{
    private boolean continueAlert;
    private Object continueAlertLock;
    private boolean audioFinished;
    private Object audioFinishedLock;
    
    public SDAAlertListener()
    {
    	//System.out.print("Added Continuos Alert Listener");
        continueAlert = true;
        continueAlertLock = new Object();
        audioFinished = false;
        audioFinishedLock = new Object();
    }
    
    public void startAlert()
    {
    	//System.out.println("Starting Contiuous Alert");
    	SetContinueAlertStatus(true);
    	SetAudioDoneStatus(false); 
    	
    	Alert.startAudio(music.myFogHornTune, 8);
    	Alert.startVibrate(500);
    }
    
    public void continueAlert()
    {
    	//System.out.println("Contiuous Alert to Continue");
    	SetContinueAlertStatus(true);
    	SetAudioDoneStatus(false); 
    	
    	Alert.startAudio(music.myFogHornTune, 8);
    	Alert.startVibrate(500);
    }
    
    public void stopAlert()
    {
    	//System.out.println("Stopping Contiuous Alert");
    	SetAudioDoneStatus(true); 
    	SetContinueAlertStatus(false);
    	
    	Alert.stopAudio();
        Alert.stopBuzzer();
    }
    
    public boolean GetContinueAlertStatus()
    {
        synchronized(continueAlertLock)
        {
            //System.out.println("Getting continueAlertStatus.");
            return continueAlert;
        }
    }
    
    public boolean GetAudioDoneStatus()
    {
        synchronized(audioFinishedLock)
        {
            //System.out.println("Getting buzzerFinished.");
            return audioFinished;
        }
    }
    
    public void SetContinueAlertStatus(boolean value)
    {
    	synchronized(continueAlertLock)
        {
        	//System.out.println("Setting ContinueAlert to " + value);
        	continueAlert = value;
        }
    }
    
    public void SetAudioDoneStatus(boolean value)
    {
        synchronized(audioFinishedLock)
        {
            //System.out.println("Setting audioFinished to " + value);
            audioFinished = value;
        }
    }
    
    public void audioDone(int reason)
    {
    	System.out.println("audioDone function");
    	
    	switch(reason) {
	    	case REASON_KEY_PRESSED:
	    		//System.out.println("Key Pressed.  Stopping Alert");
	    		stopAlert();
	    		break;
	    	case  REASON_COMPLETED:
	    		//System.out.println("Completed Called.  Stopping Alert");
	    		continueAlert();
	    		break;
	    	case REASON_STOP_CALLED:
	    		//System.out.println("Stop Called.  Do Nothing.");
	    		// Do nothing
	    		break;
    	}
    }
    
    public void buzzerDone(int reason)
    {
        // Do nothing.
    }
    
    public void vibrateDone(int reason)
    {
        // Do nothing.
    }
}

The next step is to create an instance of the listener on the main screen, so it is always there. This was one of the issues I was having, because I was adding the listener when the Message Page came in and then removing it after the alert was done. By creating the single listener, I only worry about starting and stopping the music and vibrate.

// Before the main screen is created
public static SDAAlertListener _sdaAlertListener = new SDAAlertListener();
// After the application is created and is only called once
((Application) UiApplication.getUiApplication()).addAlertListener(StartScreen._sdaAlertListener);

Next, I handled the Message Page by sending it to the GlobalMessage display function and creating a loop to check for when the Alert should be played again. The loop checks the Continue Alert Status to see if the button click hasn’t turned it off. Then it checks to see if the audio is done playing. If the Continue Alert is true and the Audio Done is true, then the startAlert function is called again to replay the music and vibration. Otherwise a break stops the loop.

/* Global Dialog display instead of screen pop */
bbhUtil.displayGlobalMessage("New Message Page " + MessagePagingInfo.getCurrentMessage());     
// Start Continuous paging section 
boolean alertStatus = true;
StartScreen._sdaAlertListener.startAlert();
// Start loop 
while (true)
{ 
	alertStatus = StartScreen._sdaAlertListener.GetContinueAlertStatus();
	if(alertStatus)
	{
		if(StartScreen._sdaAlertListener.GetAudioDoneStatus()) {
			//System.out.println("Audio Done Status is True");
			StartScreen._sdaAlertListener.startAlert();
		} else {
			break;
		}
	}
	else
	{ 
		System.out.println("Paging Alert Stop.");
		break;
	}                               
}

Finally, the Global Message display has a close listener attached to it. This listener calls the Alert stop function when the user clicks the “OK” button.

public class alertDialogListener implements DialogClosedListener {
	public void dialogClosed(Dialog dialog, int choice) {
		// Check for OK click and then stop Timer
		//System.out.println("Output Choice: " + choice);
   		 switch (choice) {
   		 	case Dialog.OK : 
   		 		synchronized(UiApplication.getEventLock())
   		 		{
   		 			//System.out.println("Calling Alert Listener Stop");
   		 			StartScreen._sdaAlertListener.stopAlert();
                }
        		break;
            case Dialog.CANCEL : 
            	Status.show("Cancel msg"); 
            	break;
        }
	}
}

This also allows for multiple Message Page alerts, since it turns on and off the same listener. I just wish I hadn’t taken so long in figuring it out.

About DeanLogic
Dean has been playing around with programming ever since his family got an IBM PC back in the early 80's. Things have changed since BASICA and Dean has dabbled in HTML, JavaScript, Action Script, Flex, Flash, PHP, C#, C++, J2ME and SQL. On this site Dean likes to share his adventures in coding. And since programming isn't enough of a time killer, Dean has also picked up the hobby of short film creation.

About DeanLogic

Dean has been playing around with programming ever since his family got an IBM PC back in the early 80's. Things have changed since BASICA and Dean has dabbled in HTML, JavaScript, Action Script, Flex, Flash, PHP, C#, C++, J2ME and SQL. On this site Dean likes to share his adventures in coding. And since programming isn't enough of a time killer, Dean has also picked up the hobby of short film creation.

Leave a Reply

Your email address will not be published. Required fields are marked *

*